Le nouveau modèle objet de PHP5
Signature : | Mis en ligne le : 02/01/2009
Catégorie(s) :
  • GNU/Linux Magazine HS
  • | Domaine :
    1 commentaire(s)

    Retrouvez cet article dans : Linux Magazine Hors série 20

     A ses débuts, PHP n’était pas un langage orienté objet. Petit à petit, les fonctionnalités et concepts de l’objet ont été ajoutés depuis la version 4. Mais, dans cette version de PHP, il manquait des concepts comme les destructeurs, par exemple. PHP5 va plus loin dans l’objet. Certes, il ne faut pas s’attendre à un langage objet comme Java, mais les concepts fondamentaux de l’objet sont implémentés et permettent de faire du code réutilisable et propre. PHP5 repose désormais sur le moteur Zend2. Zend2 propose un modèle objet complètement revu qui permet à PHP5 de fournir de nouvelles fonctionnalités comme :
    • Constructeurs et destructeurs qui vous permettent de créer des instances de classe (des objets);
    • Méthodes privées et visibilité qui vous permettent de définir des méthodes qui ne peuvent être utilisées que par des méthodes de la même classe;
    • Gestion des exceptions qui vous permette de faire une gestion fine des erreurs et de les propager;
    • Clonage et comparaison d’objets pour manipuler facilement les objets deux à deux.
    On retrouve toujours les concepts essentiels de l’objet qui étaient déjà disponibles dans PHP4 :
    • Héritage qui vous permet de spécialiser un objet (au niveau attribut ou méthode) tout en pouvant accéder aux attributs et méthodes de la super classe;
    • Polymorphisme qui vous permet de surcharger une méthode pour l’utiliser dans des paramètres différents;
    • Encapsulation qui vous permet de masquer l’implémentation d’un objet.

    Concepts objets en PHP

    Mais tout d’abord, commençons par quelques rappels (ou introduction) sur les termes utilisés et comment les utiliser en PHP4.

    Classes, objets, héritage et polymorphisme

    Pour créer des objets, il vous faut utiliser une classe. Les débutants confondent souvent classes et objets. Un objet est une instance d’une classe.Ainsi, pour une classe donnée, vous pouvez créer un nombre important d’objets différents. Pour schématiser, une classe est une template : c’est une usine à objets. Les classes sont hiérarchisées.Au sommet de la hiérarchie, on trouve une classe générique dont toutes les autres classes héritent. C’est la classe stdClass. Cette hiérarchisation s’appelle l’héritage. Une classe héritant de sa classe mère hérite de ce fait de l’ensemble des attributs et méthodes. Par exemple, on peut avoir une classe développeur et deux classes héritantes : PHP et Java. On peut schématiser ça avec UML :

    /img-articles/lmhs/20/art-1/fig-1.jpg

    Les deux sous-classes héritent des attributs nom et prénom qui sont généralisés à l’ensemble des développeurs (qu’ils soient développeurs PHP ou Java) ainsi que des méthodes associées. Ensuite, on spécialise les classes en ajoutant les attributs spécifiques. Par exemple, pour un développeur Java, on ajoute la version de la JVM, alors que pour un développeur PHP, on va plutôt s’attacher à la version de PHP et de Apache. L’héritage est un concept essentiel à tout langage objet car il permet la réutilisation facile de code. Voilà comment définir une classe en PHP :

    Nous pouvons maintenant instancier un objet à l’aide de cette classe :

    Pour accéder aux attributs ou méthodes d’un objet, il faut utiliser l’indirection -> :

    Lorsque vous codez une méthode, il est fréquent de faire appel à d’autres méthodes de la classe ou à des attributs. Mais comment faire puisqu’on ne sait pas encore le nom de l’objet instancié. La variable $this est utilisée à l’intérieur d’une classe pour désigner l’objet courant :

    Vous pouvez définir des attributs statiques dans une classe :

    Il existe un type de méthode particulier : les constructeurs et les destructeurs. Un constructeur est une méthode appelée lors de l’instanciation d’un objet. Il vous permet de définir des attributs ou de faire des actions données. De la même manière, un destructeur est appelé au moment de la destruction d’un objet. Il vous permet de supprimer des variables ou de fermer des ressources externes (des fichiers par exemple) :

    Il est également possible de faire des méthodes statiques. Une méthode statique ne s’applique pas à un objet, mais est générique à la classe.Ainsi, vous pouvez l’appeler sans instancier la classe :

    Pour faire hériter une classe, il faut utiliser le mot réservé extends. Nous arrivons là à une deuxième propriété de l’objet fort intéressante : le polymorphisme. Le polymorphisme est le fait de pouvoir utiliser une même méthode sur des objets complètement différents et sans nécessairement connaître de quel type d’objet il s’agit. Par exemple, considérons cette hiérarchie d’objets :

    Nous avons une classe mère qui décrit les attributs nécessaires à l’ensemble des bases de données (le nom du serveur de base, le port et le nom de la base sur laquelle se connecter). Nous définissons deux classes héritantes : une spécialisant la connexion à MySQL et l’autre à PostgreSQL. On remarque que les deux classes implémentent les mêmes méthodes. On va donc pouvoir appeler, de la même manière la méthode connect, que l’on soit sur MySQL ou PostgreSQL. Il n’est même pas nécessaire de savoir si on fait l’appel sur mysqldb ou pgdb, l’appel est le même (c’est l’implémentation qui est masquée). On appelle également cela la surcharge de méthode.

    Sérialisation et désérialisation

    La sérialisation vous permet d’obtenir une représentation en bytes d’un objet donné. Cette représentation peut être alors stockée dans un fichier, par exemple. Cette fonctionnalité est particulièrement utile pour les données persistantes : par exemple, la sauvegarde et la restauration des sessions. Pour le développeur, la mise en place de ce mécanisme consiste uniquement à implémenter les méthodes serialize() et unserialize() :

    Les sessions en PHP utilisent déjà la sérialisation.Vous n’avez pas besoin de la gérer. C’est pour cela que lorsque vous voulez utiliser une session dans une page, il faut faire appel à la fonction session_start() qui désérialise la session. PHP propose des fonctions qui sont appelées durant le processus de sérialisation/désérialisation : __sleep() et __wakeup(). Ces méthodes sont utilisées pour modifier un objet qui va être sérialisé/désérialisé. Ces méthodes ne sont pas nécessaires pour sérialiser/désérialiser, mais dans ce cas, l’objet n’est absolument pas modifié durant le processus. La méthode __sleep() est appelée sur un objet juste avant sa sérialisation. Elle peut réaliser du nettoyage pour préserver un état cohérent, comme par exemple fermer des connexions à une base de données. Elle retourne un tableau avec le nom des attributs à sauvegarder sous forme de bytes. Si le tableau est vide, rien n’est sauvegardé. De la même manière, __wakeup() est une méthode appelée immédiatement après que l’objet soit créé à partir d’un flux de bytes (désérialisation). Cette méthode a en charge la remise de l’objet dans un état cohérent, comme par exemple la restauration des connexions aux bases de données. Considérons par exemple une classe qui trace les pages d’où viennent les utilisateurs dans un fichier plat :

    Les nouveautés objets de PHP5 Constructeurs et destructeurs

    Nous avons vu en introduction comment définir les constructeurs (avec le style PHP4). En PHP5, les développeurs ont décidé d’unifier la déclaration des constructeurs en utilisant un nom de méthode particulier : __construct.Toutefois, si l’interpréteur PHP ne trouve pas cette méthode, il cherche une déclaration du constructeur avec la définition PHP4 (le nom de la classe). Attention toutefois, les constructeurs des classes parentes ne sont pas automatiquement appelés, pour les utiliser, il vous faut utiliser parent::__construct(). En PHP4, pour détruire un objet, il fallait faire un " classique " :

    Cette solution présente l’inconvénient de ne pas pouvoir faire de traitements automatiques au moment de la destruction. Par exemple, si vous ouvrez un fichier dans le constructeur, il est impératif que vous fermiez le fichier avant de faire le unset. De plus, il n’est pas possible de réellement contrôler le cycle de vie d’un objet. PHP5 introduit la notion de destructeur. Un destructeur est une méthode spéciale qui est appelée juste avant la destruction de l’objet.Ainsi, vous pouvez faire vos traitements spéciaux comme fermer un fichier par exemple. Un destructeur porte le nom spécial __destruct(). Voilà comment utiliser les constructeurs et destructeurs en PHP5 :

    Visibilité

    PHP5 a désormais inclus la notion de visibilité que ce soit pour les attributs ou les méthodes. Il y a trois niveaux de visibilité : public, protected, private.

    • Déclaré en public, l’attribut ou la méthode peut être accédé(e) par n’importe quelle classe et de n’importe où.
    • Déclaré en protected, l’attribut ou la méthode peut être accédé(e) uniquement par les classes descendantes (c’est-à-dire les classes héritant de la classe dans laquelle l’attribut ou la méthode est définie).
    • Déclaré en private, l’attribut ou la méthode peut être accédé(e) uniquement dans la classe de définition.
    Attention : désormais, la déclaration d’un attribut dans une classe ne nécessite plus l’utilisation du mot réservé var. Dorénavant, il suffit d’utiliser la déclaration de la visibilité suivie du nom de la variable. Voilà quelques exemples de déclaration de visibilité

    Statiques et constantes

    L’utilisation du double colon :: vous permet d’accéder à des éléments statiques ou des constantes. Désormais, il est possible de définir des constantes dans une classe : Vous pouvez définir des méthodes statiques (appelées aussi méthodes de classes) avec sa visibilité :

    Attention, lorsque vous définissez une méthode qui ne surcharge (qui a donc le même nom) qu’une méthode de la classe mère, PHP n’appelle QUE la méthode de la classe descendante. Si vous voulez tout de même appeler la méthode de la classe mère, il vous faut utiliser parent::method_name().

    Vous avez sans doute remarqué l’utilisation du mot clef static. Un attribut ou une méthode déclaré(e) statique le rend accessible en dehors d’un contexte objet.

    Il n’est pas nécessaire d’avoir une instance de la classe (un objet) pour appeler l’attribut ou la méthode. On appelle aussi ces attributs ou méthodes des attributs de classe et des méthodes de classe. Comme l’élément est statique, il n’est pas possible d’y accéder dans une sous-classe sans le préfixer de la classe mère et bien sûr, il n’est pas possible d’utiliser $this dans une méthode statique (puisque cette dernière n’a pas d’objet associé). Pour bien comprendre la différence entre attribut de classe et attribut d’objet, voilà comment il est possible de compter le nombre d’instances d’une classe :

    Classe abstraite et méthode abstraite

    PHP5 introduit la notion de classes et méthodes abstraites.

    Une méthode abstraite ne peut pas être instanciée, cela signifie donc qu’il n’est pas possible d’avoir un objet d’une classe abstraite. Il est donc nécessaire de créer une classe héritant de la classe abstraite. De même, lorsque vous déclarez une méthode abstraite, vous ne faites que définir la signature de la méthode et non l’implémentation. L’implémentation de la méthode sera faite dans une sousclasse.

    Mais à quoi cela sert ? Avec l’abstraction, vous définissez des comportements par défaut que vous retrouverez dans toutes les sous-classes de la classe abstraite. Ainsi, sans connaître l’implémentation sous-jacente, vous pourrez utiliser les méthodes abstraites. Dès qu’une classe possède une méthode abstraite, la classe elle-même est abstraite. Une méthode abstraite ne peut être définie qu’en public ou protected. En effet, si on pouvait la définir en private, on ne pourrait pas la définir dans une sous-classe, et donc cela ne servirait à rien.

    Voilà comment utiliser l’abstraction :

    Interfaces

    Une interface ne fait que définir des attributs et des signatures de méthodes. Une classe implémente ensuite les méthodes définies dans l’interface. Une interface permet de définir les comportements communs à un ensemble d’objets qui n’ont rien à voir entre eux :

    Itération

    Il existe une interface Iterator qui vous oblige à surcharger certaines méthodes. Grâce à ces méthodes, il est très facile d’itérer dans les attributs de l’objet (NDLR : l’itération permet d’utiliser foreach avec des objets) :

    Final

    Le mot clef final vous permet de définir des attributs ou des méthodes qui ne peuvent pas être surchargé(e)s dans les sous-classes:

    Clonage et comparaison d’objets

    Cloner un objet ne signifie pas uniquement recopier les valeurs des attributs. Prenons par exemple un objet dont un des attributs est lui-même un objet. Si vous faites une simple affectation, le nouvel objet va avoir une référence sur le même objet attribut. Le clonage consiste à créer un objet indépendant, y compris pour les objets attributs.

    Un objet cloné s’obtient en utilisant le mot réservé clone qui va appeler la méthode __clone(). Il n’est pas possible d’appeler directement la méthode __clone().

    Assez similairement, vous devez préciser comment vous comparez deux objets, surtout si l’objet est composé d’objets attributs. La comparaison d’objets est plus compliquée en PHP5 qu’en PHP4.

     Lorsque vous utilisez l’opérateur de comparaison (==), les objets sont comparés de la façon suivante : deux objets sont égaux s’ils ont les mêmes attributs, si ces attributs ont la même valeur et si les deux objets sont de la même classe. D’un autre côté, lorsque vous utilisez l’opérateur d’identité (===), les objets sont identiques si et seulement si ils référencent la même instance de classe. Prenons un exemple :

    Exception

    PHP5 propose une gestion des exceptions plus fine.Vous avez la possibilité de créer vos propres exceptions en héritant de la classe Exception :

    Ensuite, vous pouvez récupérer les exceptions et les traiter. Prenons l’exemple de la gestion d’exception dans l’utilisation des méthodes SOAP :

    Quand PHP rencontre Java

    Il y a deux manières d’intégrer PHP et Java.Vous pouvez intégrer PHP dans un contexte de Servlet. Pour cela, il vous faut compiler PHP avec le support de Java (avec l’option —with-servlet[=DIR]).

     Vous pouvez utiliser les extensions Java. Dans ce cas, la JVM est créée en utilisant JNI et vous pouvez appeler des méthodes sur les objets Java directement en PHP.

    Le seul pré-requis est d’avoir une JVM installée sur le serveur. Vous pouvez configurer diverses options Java dans le fichier php.ini, comme par exemple le classpath (avec l’option java.class.path) ou le Java Home (avec l’option java.home). Ainsi, vous pouvez créer des objets Java directement en PHP et les utiliser directement :

    Conclusion

    PHP5 a introduit de nouvelles fonctionnalités objets qui le rendent plus proche d’un véritable langage orienté objet comme Java ou Eiffel. Certes, ce n’est pas encore Java, surtout au niveau design que l’on peut mettre en oeuvre, mais on peut déjà réaliser du code plus propre et plus réutilisable.

    De plus, l’intégration facile de Java directement dans PHP donne un niveau d’interopérabilité plus accru et ouvre le chemin vers des applications Web très évoluées. Avec le moteur Zend 2, il serait dommage de ne pas utiliser la programmation orientée objet de PHP5.

    Retrouvez cet article dans : Linux Magazine Hors série 20

    Donnez votre avis - 1 commentaire(s)
  • B72B98G dit :
    PHP5 place l'objet au même niveau que JAVA. La différence fondamentale entre les deux reste maintenant le typage fort pour l'un, faible pour l'autre. PHP5 introduit des méthodes internes fonctionnant comme des hooks, ce qui laisse plus de liberté au programmeur, en plus du classique constructeur et destructeur. En ce sens, PHP5 va plus loin que JAVA.
  • Vous souhaitez commenter cet article ?
    Brèves Flux RSS
    Édito : GNU/Linux Magazine 149
    Édito : GNU/Linux Magazine HS N°60
    Édito : Misc 61
    Édito : Linux Pratique 71
    Édito : Linux Essentiel N°25
    Communication RSS Com. RSS Presse
    Lancement de la plateforme de vente en ligne de PDF des Éditions Diamond ! Un...
    Misc N°61 – Communiqué de presse
    GNU/Linux Magazine N°149 – Communiqué de presse
    GNU/Linux Magazine HS N°60 – Communiqué de presse
    Linux Pratique N°71 – Communiqué de presse
    prochainement moteur de recherches des articles
     
    :
    :
    Jours heures minutes secondes
    En kiosque Flux RSS

    Le tout nouveau GNU/Linux Magazine est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Pratique est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau GNU/Linux Magazine HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Essentiel est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...