Archives par mot-clé : class

Problèmes de mémoire ?

Petit point sur C++ et la gestion mémoire

Publié dans C / C++ | Un commentaire

Différents types de données

En terme de mémoire, il existe différents types de donnée en C++.

  • Donnée statique : emplacement alloué une fois pour toute la durée du programme
  • Donnée automatique (pile) : emplacement alloué à l’entrée d’un bloc (exemple : une fonction, une boucle, …) et libéré à sa sortie
  • Donnée dynamique (tas) : emplacement alloué et libéré à la demande du programme, donc du développeur à l’aide des opérateurs new et delete Bref à l’aide de pointeurs.

On parle ainsi de trois classes d’allocation : statique, automatique, dynamique.
Dans cet article, nous allons étudier un peu plus en détails l’allocation / destruction de données dynamiques.
Continuer la lecture

Calculer la durée d’un script ou d’un programme Java

Publié dans Java | Laisser un commentaire

Combien de fois vous est-il arriver de chercher à connaître la durée d’un script, d’une action ou d’un morceau de code ? Franchement, ça m’est arrivé relativement souvent, à tel point d’ailleurs que le code de base que j’ai créé pour démarrer un nouveau projet de site Internet en PHP, affiche par défaut en bas de page le temps de chargement.

En Java, il existe une class nommée Timerdans le package com.ge.tools qui permet de calculer facilement la durée d’un script. Deux méthodes sont à utiliser :

  • getTempsTotal : renvoie la durée en milliseconde depuis la déclaration du Timer
  • getTempsIntermediaire : renvoie la durée en milliseconde depuis le dernier appel à getTempsIntermediaire ou à la déclaration du Timer si aucun appel à getTempsIntermediaire effectué précédement

Dans l’exemple ci-dessous, j’utilise en fait getTempsTotalFormate et getTempsIntermediaireFormate qui renvoie la durée au format plus lisible : h:min:s,ms.

Timer timer = new Timer();
System.out.println("Sleep 1000ms...");
Thread.currentThread().sleep(1000);
System.out.println("Temps intermédiaire 1 : "+timer.getTempsIntermediaireFormate());
System.out.println("Temps total 1 : "+timer.getTempsTotalFormate()); System.out.println("Sleep 1000ms...");
Thread.currentThread().sleep(1000);
System.out.println("Temps intermédiaire 2 : "+timer.getTempsIntermediaireFormate());
System.out.println("Temps total 2 : "+timer.getTempsTotalFormate());

Ce qui affiche au bout de 2s :

Sleep 1000ms…
Temps intermédiaire 1 : 0:0:1,0
Temps total 1 : 0:0:1,0
Sleep 1000ms…
Temps intermédiaire 2 : 0:0:1,0
Temps total 2 : 0:0:2,0

Récapitulatif PHP Objet

Publié dans PHP objet | Laisser un commentaire

Logo PHP

Ce billet vient récapituler la série sur PHP Objet que j’ai effectuée entre mai à juillet 2009. Le but est de faire le point sur PHP Objet, sur mes connaissances et sur les publications réalisés à ce sujet sur 30minparjour. Désormais, j’essayerai de faire un tel résumé pour toutes les séries que j’aborderai. C’est long et fastidieux, mais je pense que cela m’est utile pour faire le point. J’espère que cela vous servira aussi.

Résumons quelques points importants

Petit résumé sur les classes

[abstract ]class MaClasse [extends AutreClasse implements Interface]
{
	public|protected|private [static] $maVariable [= valeur];
	public static $etat = 1;
	
	/**
	 * Constructeur
	*/
	public|protected|private function MaClass|__construct()
	{
		// Déclaration des variables et autres
	}
	
	/**
	 * Fonction classique
	*/
	public|protected|private [static final abstract] function maMethode()
	{
		// Action de la fonction maMethode
		$this--->maVariable = 'test';
		self::$etat = 0;
		$this->autreMethode();
		[parent::autreMethode();]
	}
	public function $autreMethode()
	{
		echo 'Hello world!';
	}
}

Au passage, je rappelle qu’une classe peut implémenter plusieurs interfaces, mais ne peut hériter que d’une seule classe.

Petit résumé sur les interfaces

interface Interface [extends AutreInterface]
{
	/**
	 * Fonction classique
	*/
	public function $maMethode();
	/**
	 * Autre fonction classique
	*/
	public function $autreMethode();
}

Petit résumé sur les singletons

class Singleton
{
	/**
	 * Variable static valant null si la classe n'est pas encore instanciée
	 * ou contenant l'instance si la classe est instanciée.
	 * On y accède avec self::$_instance
	*/
	private static $_instance = null;
	
	/**
	 * Constructeur private inaccessible en dehors de la classe
	*/
	private function __construct()
	{
		// On instancie ce qu'il faut
	}
	
	/**
	 * Accessor static, donc accessible sans être instancié, renvoyant 
	 * l'instance, en la créant si besoin
	*/
	public static function getInstance()
	{
		if (self::$_instance == null) {
			self::$_instance = new Singleton();
		}
		return self::$_instance;
	}
}

Quelques méthodes magiques utiles

  • __construct() : Appelée lorsqu’on tente de construire la class
  • __destruct() : Appelée lorsqu’on tente de détruire la class
  • __set() : Déclenchée lors de l’accès en écriture à une propriété de l’objet. Exemple d’utilisation
  • __get() : Déclenchée lors de l’accès en lecture à une propriété de l’objet. Exemple d’utilisation
  • __call() : Déclenchée lors de l’appel d’une méthode inexistante de la classe (appel non static). Exemple d’utilisation
  • __callstatic() : Déclenchée lors de l’appel d’une méthode inexistante de la classe (appel static) : disponible depuis PHP 5.3 et 6.0
  • __isset() : Déclenchée si on applique isset() à une propriété de l’objet
  • __unset() : Déclenchée si on applique unset() à une propriété de l’objet -> différence avec __destruct() ?
  • __sleep() : Exécutée si la fonction serialize() est appliquée à l’objet. Exemple d’utilisation
  • __wakeup() : Exécutée si la fonction unserialize() est appliquée à l’objet. Exemple d’utilisation
  • __toString() : Appelée lorsque l’on essaie d’afficher directement l’objet : echo $object;
  • __clone() : Appelé lorsque l’on essaie de cloner l’objet. Exemple d’utilisation

Conclusion

Je crois qu’on vient de faire un tour vraiment rapide mais plus ou moins complet du PHP Objet. A mon sens, il manque 3 notions à ce résumé (mais on ne peut pas tout résumer) :

  • Les exceptions. Il faudrait que je m’y mette un jour. Heureusement il existe un très bon tutoriel sur « Apprendre PHP » : Les exceptions.
  • Un autre chose plutôt cool qu’aborde « Apprendre PHP » est l’interface Iterator, quoi que je ne vois pas trop l’interêt en PHP, mais je sais combien c’est cool en Java !
  • La copie d’une classe. Je l’ai quand même vraiment pas mal résumé ici : Le clônage n’est pas une référence.

Billets traitant de PHP Objet

J’ai trié et classé toutes les publications que j’ai fait sur ce blog à propos du PHP Objet.

Apprentissage

Application

Trucs et astuces

Documentation et tutoriels

Je vous présente les quelques sites que j’ai fréquemment utilisé pour comprendre le fonctionnement et les finesses de PHP et du PHP orienté objet.

Singleton(s) !

Publié dans PHP objet | Commentaires fermés sur Singleton(s) !

Voilà bien longtemps que je n’avais pas fait de billets sur le PHP Objet. A vrai dire, je suis en train d’apprendre la programmation orientée objet en cours (au travers du Java et du C++), donc ça fixe vraiment les idées et permet de comprendre pas mal de petites choses, notamment l’utilité de certaines notions, comme les singletons, qui me paraissait bien douteuse auparavant. Un singleton, c’est une classe que l’on ne peut instancier qu’une seule fois. Par exemple, en cours on a créé une classe liste dont hérite la classe liste vide, et la classe listeNonVide. Clairement, il n’existe qu’une et une seule liste vide (sinon, on ne s’en sort pas), donc cette classe ne peut être instanciée qu’une seule fois, donc c’est un singleton. Je n’ai pas encore trouvé d’exemples plus parlant, par contre sur Apprendre-PHP, l’exemple est celui d’une classe PresidentDeLaRepublique qui, en effet, ne peut être instanciée qu’une seule fois)

Comment faire ?

L’idée est la suivante : le constructeur de la classe est private, on ne peut donc instancier la classe en passant directement par lui. Par contre, une variable static possède un accessor (getMachin()) qui est public et qui appelle le constructeur si la classe n’est pas encore instanciée (variable static == null), ou retourne l’instance sinon. En somme, voilà ce que ça donne :
Continuer la lecture

Classes abstraites et finales

Publié dans PHP objet | 2 commentaires

Les notions de classes abstraites et classes finales permettent de sécuriser notre programmation PHP, dans le sens qu’elles permettent d’éviter qu’un programmeur, reprenant notre code, n’en contourne la logique et s’égare ainsi sur une fausse piste.
En effet :

  • Class abstraite : class qui ne peut être instanciée, il est donc OBLIGATOIRE de créer une class héritante de cette class pour s’en servir. Utile lorsque l’on créé une class générique qui ne servira qu’à créer des sous class et non à être instanciée. Une telle class ne contient donc pas de __construct() puisqu’elle n’est pas instanciée. Mot clef : abstract.
  • Class finale : class qui NE PEUT PLUS avoir de sous-class, c’est-à-dire de class héritante. Les méthodes de cette class ne pourront être surchargées (réécrites, redéfinies). Mot clef : final. De la même manière, on peut aussi déclarer des méthodes abstraites et finales.
  • Méthode abstraite : méthode qui doit OBLIGATOIREMENT être surchargée (réécrite, ou redéfinie). Une class contenant une méthode abstraite doit aussi être abstraite. Mot clef : abstract.
  • Méthode finale : méthode qui NE PEUT ÊTRE surchargée (réécrite, redéfinie). Une class finale s’applique sur toutes les méthodes ou attributs de la classe, alors qu’ici on ne touche qu’à une seule méthode. Mot clef : final. Pour bien comprendre ces 2 notions et en saisir mieux l’intérêt voici plusieurs exemples, un pour chaque cas.

Class et méthodes abstraites

 abstract class Site {
	protected $type;
	protected $name;
	public function getType()
	{
		return $this->type;
	}
	public function getName()
	{
		return $this->name;
	}
}
$monSite = new Site();
echo $monSite->getType(); // Erreur : on tente d'instancier une classe abstraite

Continuer la lecture

Quelques méthodes et constantes magiques ou prédéfinies

Publié dans PHP objet | Laisser un commentaire

Attributs ou méthodes qui n’existent pas ?

Avant de faire un petit récapitulatif magique ou déjà défini (mouahaha), voyons une petite notion importante du PHP objet : il est possible de modifier et de lire la valeur d’un attribut qui n’existe pas (ah horreur), par contre, on ne peut utiliser une méthode qui n’existe pas (ah bah ça tombe bien alors !). Je m’explique en codant :

class Chat { }
$unChat = new Chat();
$unChat->couleur = 'noir';
$unChat->etat = 'sorti ses griffes';
echo 'Mon chat '.$unChat->couleur.' a '.$unChat->etat.'.';

Eh oui, ce petit exemple affichera bien : « Mon chat noir a sorti ses griffes . ». C’est horrible, n’est-ce-pas ? Heureusement avec __set() et __get(), on va pouvoir empêcher ce types d’actions et en profiter pour vérifier le type des valeurs que l’on assigne à nos attributs.
Par contre :

class Chat { } 
$unChat = new Chat();
$unChat->etreGentils();

Nous renverra une jolie petite erreur ! (heu, oui, je n’aime pas tellement les chats. Enfin, cela dit, je n’ai rien contre eux non plus) Heureusement la méthode magique __call() va nous permettre de rattraper ce petit bémol. Mais tout cela est très bien expliqué sur Apprendre PHP, alors sans plus tarder voilà une liste des méthodes et des constantes magiques, ainsi que des fonctions prédéfinies avec à chaque fois une explique, ou des exemples tiré du manuel PHP, de tutoriels sur le Web ou de mes propres mot.
Continuer la lecture

Utiliser les méthodes et les attributs d’une autre class

Publié dans PHP objet | Laisser un commentaire

Ah, je viens enfin de mieux comprendre à quoi servait l’opérateur cons ::. Dans le précédent billet où j’en parlais je disais qu’il permet de résoudre un attribut ou une méthode, éh bien c’est tout à fait vrai !

  • Pour appeler un attribut ou une méthode d’une class dans cette même class, on utilise $this->methodeOuAttribut.
  • Pour appeler un attribut ou une méthode d’une class lorsqu’on a instancié cette class, on utilise $nomInstance->methodeOuAttribut.
  • Pour appeler un attribut ou une méthode d’une class dans une autre class, on utilise NomDeLaClass::methodeOuAttribut. Les deux class doivent bien sûr se trouver dans le même fichier, ou on peut inclure l’une dans le fichier de l’autre avec include() ou require().

Dans le cas d’un attribut, si l’on tente d’y accéder avec le nom d’une class, cela signifie que notre attribut doit être static, il reste identique pour toutes les instances de cette class.
Prêt pour un petit exemple (débile) ?

<?php
class DitBonjour {
	protected static $fr = 'Coucou le monde !';
	public static $en = 'Hello world!';
	public static $de = 'Guten tag!';
	function saluer()
	{
		return 'Guten tag!'.'<br />';
	}
	function saluer_en_langue($langue)
	{
		return $langue;
	}
	function fr()
	{
		return self::$fr;
	}
	function de()
	{
		return $this->de;
	}
}

class Appeler {
	function dire_bonjour()
	{
		echo DitBonjour::saluer();
	}
	function dire_bonjour_en_langue()
	{
		echo DitBonjour::saluer_en_langue(DitBonjour::fr()).'<br />';
		echo DitBonjour::saluer_en_langue(DitBonjour::$en).'<br />';
		echo DitBonjour::saluer_en_langue(DitBonjour::de()).'<br />';
	}
}

$appel = new Appeler();
$appel->dire_bonjour();
$appel->dire_bonjour_en_langue();

Ceci renverra :

Guten tag!
Coucou le monde !
Hello world!
Notice: Undefined property: Appeler::$de in F:\bn\Web\Test\PHPObjet\test2.php on line 26

Continuer la lecture

Rendre __construct() comptatible PHP 4

Publié dans PHP objet | Laisser un commentaire

La méthode magique __construct() est apparue dans PHP5, par conséquent PHP4 (ou inférieur) ne la reconnait pas. Auparavant, au lieu d’utiliser __construct(), on utilisait une méthode qui portait le même nom que la classe elle-même. Donc pour avoir une compatibilité PHP4 et PHP5, on peut utiliser le code suivant :

<?php
class MaClass
{
  var $app;

  function MaClass($app)
  {
    $this->__construct($app);
  }

  function __construct($app)
  {
    $this->app = $app;
  }
}

Ainsi, si on est en PHP5, le __construct() est bien compris et utilisé. Si on est en PHP4 (ou inférieur), on utilise MaClass() qui utilise une nouvelle méthode que l’on définie : __construct().
Alors pourquoi ne pas laisser tomber __construct() et n’utiliser que MaClass()__construct() c’est l’avenir le présent. Un développeur de la boîte où j’ai effectué un stage m’a appris que si on est en PHP5, ce dernier va sauter sur le __construct() et lira ensuite plus tard le MaClass() (et donc le zappera), on gagne un peu de temps pour une exécution en PHP5. Par conséquent ce bout de code utilise les avantages du PHP5 et est compatible PHP4 (et inférieur) 😀

Le clonage n’est pas une référence

Publié dans PHP objet | Laisser un commentaire

Aujourd’hui j’ai fini le cours de PHP 5 sur Developpez.com consacré au PHP objet. Il y a encore quelques trucs que je détaillerai dans les billets des prochains jours, mais en somme, mis à part mon problème avec self et parent, je pense avoir compris l’essentiel. Il se trouve que je suis actuellement en stage et que je vais avoir l’occasion de me confronter au framework maison de la boîte où je travaille, et, ô miracle, c’est un framework objet ! Il a l’air bigrement complet et bien fichu, mais aussi peut-être un petit peu compliqué pour moi… ça va être l’occasion de voir ce que j’ai compris ! Mais bref… parlons un peu de l’instanciation d’une classe et clonage d’objets.

Instanciation d’une classe et destruction d’objets

Lorsqu’on instancie une classe avec le mot clé new, on créé une référence de cette instanciation. Et si on fait une copie de cet objet avec le symbole =, on créé une nouvelle référence vers cette instanciation. Or pour supprimer une instanciation d’une classe, avec la fonction unset(), il faut que toutes les références de cette classe soient supprimées. Pour bien comprendre, reprenons l’exemple de Développez.com. Pour cela, il faut savoir que la méthode magique __destruct() est déclenchée lorsqu’on supprime une instance d’une classe.

<?php
class Blog {
  function __destruct()
  {
    echo 'Je me meurs !';
  }
}
$monBlog = new Blog();
$monAutreBlog = $monBlog;
echo 'Allons soldats, tuons monBlog !';
unset($monBlog);
echo 'Puisqu\'il résiste, éliminons donc son frère !';
unset($monAutreBlog);

Cet exemple affichera :

Allons soldats, tuons monBlog !
Puisqu'il résiste, éliminons donc son frère !
Je me meurs !

Continuer la lecture

Interfaces : plus utiles qu’il n’y parait

Publié dans PHP objet | Laisser un commentaire

C’est en regardant le détails des interfaces prédéfinies sur le Manuel PHP que j’ai mieux compris l’intérêt des Interfaces. Prenons comme exemple l’interface Traversable : elle signifie que les classes l’implémentant doivent pouvoir parcourir des objets avec foreach. Pour cela, il faut que les classes en question implémentent, par exemple, l’interface prédéfinie Iterator qui définit les itérateurs. Ces itérateurs doivent pouvoir utiliser les fonctions rewind (retour arrière), next (au suivant), current (position actuelle), etc… Et le manuel nous montre des exemples d’implémentations de ces interfaces.
En somme, j’ai envie de dire que les interfaces sont aux classes ce que sont les types aux variables en programmation « classique ». Un peu quoi… En structurant sa manière de programmer (en utilisant des types et/ou des interfaces) on diminue le risque d’erreurs ou de bugs, on améliore la lisibilité, la relecture et la réutilisation du code et ça : c’est quand même tout l’enjeu d’un code durable !!!
Ah, il est à noter qu’une interface peut hériter d’une autre. L’interface Iterator hérite de Traversable par exemple. Si on devait créer cette interface, on écrirait :

<?php
interface Iterator extends Traversable
{ }

Même syntaxe qu’avec les classes en fait !
Et une classe peut aussi implémenter plusieurs interfaces, alors pour faciliter l’écriture, il est possible de séparer les interfaces par des virgules :

<?php
class RecursiveCachingIterator extends CachingIterator implements Countable , ArrayAccess , Iterator , Traversable , OuterIterator , RecursiveIterator
{ }

Comme toujours, le Manuel PHP m’aura été d’une grande aide ! Je l’utilise beaucoup pour le procédural (i.e. la programmation non-objet), j’aurai dû y penser plus tôt pour l’objet !

Je me demande s’il est possible de définir une classe qui hérite de plusieurs autres classes en les séparant par des virgules. En théorie oui. Une classe ne peut hériter de plusieurs classes. Bref l’héritage multiple est impossible en PHP, mais l’interfaçage multiple existe. Nuançons cette seconde partie de ma sentence : une classe ne peut pas implémenter deux interfaces partageant des noms de méthodes.