Tutoriel PHP : pourquoi passer au développement orienté objet ?

Ce que j’aurais toujours voulu savoir sur la programmation orientée objet sans jamais le trouver. Cette introduction est destinée à fournir des idées claires pour aborder la POO dans PHP.

A y est je m’y suis mis. Depuis bientôt un an, je titille la bête. Quoi donc ? La programmation orientée objet (POO). Je commence à entrevoir les véritables avantages de ce mode de développement. Pourtant j’avais le profil-type du développeur PHP OO depuis au moins deux ans, travaillant au quotidien sur des systèmes de gestion de contenu maison de plus en plus compliqués.

Mais j’ai vécu dans l’ignorance, n’osant franchir le pas, inquiet à l’idée de cette méthode si glorifiée. Il faut dire que l’héritage, le polymorphisme, les Design Patterns (« motifs de conception », cf. Fabrique et autre Singleton), c’est effrayant quand on est surtout adepte du HTML de papa et qu’on appris PHP sur le tas. A croire que certains essaient d’éloigner les novices pour rester entre eux…

Mais il faut savoir qu’il y a une vie avant ces gros mots de spécialistes (surtout avec PHP4 qui est très limité), et que la POO peut rendre de grands services sans forcément imposer une courbe d’apprentissage rebutante. J’ai eu beau chercher, je n’ai jamais trouvé de liste simple et claire des bénéfices à en attendre. C’est pourquoi je vous livre ceux qui me paraissent aujourd’hui les plus évidents, saupoudrés de quelques exemples de codes pour démarrer :

Traiter simplement ses données avant la sortie

Avant la POO, mes scripts étaient bourrés de tableaux associatifs et de fonction de traitement inclassables. Mais pour afficher un titre ou une url, je devais passer $article[‘titre’] et $article[‘url’] dans une fonction de formatage formate_titre() ou formate_url() qui convertissait les accents ou créait de toute pièce une URL à partir de valeurs tirées du tableau lui même (id 27 + titre sans accent = /27-titre_sans_accent). Et pareil pour tous les champs et tous les éléments de la page. A l’arrivée, la page de chargement du CMS était un horrible fatras de conditions et d’appels de fonctions répétitifs. Parvenu à ce niveau de casse-tête, j’étais fin prêt pour apprécier le confort des classes.

Avec une classe Article appropriée, le traitement est prévu au sein de la classe, et sera effectué à la demande. Fini le prétraitement. Il suffit d’afficher la méthode $article->titre() qui effectuera le traitement au moment de l’affichage, sans envahir le template. Et si le titre doit faire l’objet d’un formatage différent sur une autre page, une autre méthode $article->titreWiki() sortira tout autre chose à partir du même champ de base de donnée. C’est propre, c’est clair, chaque chose est à sa place : la classe traite, le template affiche.

Retrouver plus rapidement ses petits

Il faut un peu de temps pour s’y habituer et penser « objet ». Avec un peu de discipline, on arrive à organiser ses classes de manière claire et logique. Le gain de temps est énorme lorsqu’il faut retrouver une fonction en particulier. On peut ainsi se faire un dossier inc/classes avec un fichier par classe :

  • classe.inc.php avec la classe Classe qui contient des méthodes de base pour toutes les classes
  • format.inc.php avec la classe Format pour les fonctions qui transforment les chaînes de caractères,
  • magazine.inc.php avec la classe Magazine qui contient des méthodes comme ->listeArticles() qui renvoie un array contenant des objets de la classe Article
  • article.inc.php avec la classe Article qui contient des méthodes comme ->titre() ou ->tags()
  • etc.

Se constituer une bibliothèque de classes

Les sites Web ont souvent de nombreux points communs. Alors que les fonctions de traitement sont propres à un projet, les classes sont généralement assez facilement interchangeables d’un site à l’autre : Rubrique, Article, Membre, Utilisateur… En limitant les méthodes spécifiques (notamment MySQL), vous n’avez qu’une ou deux lignes à changer pour avoir un moteur de site fonctionnel et facile à améliorer. A terme, vous pouvez même vous constituer une bibliothèque de base, strictement identique d’un site à l’autre, et étendre ces classes avec une version spécifique pour chaque projet.

Comment passer sans douleur des tableaux associatifs aux classes

Voici quelques exemples de code qui m’auraient bien servi si j’avais pu les avoir avant de me lancer.

Fichier inc/classes/classe.inc.php

class Classe {     
  // Affecte à l'objet les variables issues du tableau de valeurs (généralement issu de SQL)     
  // Elles seront utilisables sous la forme $objet->titre ou $objet->url     
  function affecteVariables ($tableau)     
  {         
    if (is_array($tableau))         
    {             
      foreach ($tableau as $cle => $valeur)             
      {                 
        $this->$cle = $valeur;             
      }         
    }     
  } 
}

 

Fichier inc/classes/proposition.inc.php

class Proposition extends Classe {     
  // fonction "Constructeur" appelée dès que l'objet est instancié     
  function __construct($id = null)     
  {         
      // Si l'objet est appelé avec un $id, il le charge à partir de la base         
    if ($id)         
    {             
      $this->creerDepuisId($id);         
    }     
  }     

  // Charge les propriétés de l'objet depuis la base de données     
  function creerDepuisId($id)     
  {         
    if ($id)         
    {             
      // Emploie la fonction mysql_ligne présentée sur le billet 10 fonctions MySQL que j'utilise tous les jours             
      $proposition = mysql_ligne ("                 
        SELECT *                 
        FROM propositions                 
        WHERE id = $id AND etat <> 'effacé'                 
        LIMIT 1");             
      $this->affecteVariables($proposition);             
      $this->auteur();         
    }     
  }     

  // Renvoie l'objet Membre qui est l'auteur de la proposition     
  function auteur()     
  {         
    $this->auteur = new Membre($this->auteur_id);         
    return $this->auteur;     
  } 
}

 

Fichier index.php?p_id=4

$proposition = new Proposition($_GET['p_id']); 
print $proposition->id; 
// 4 

$auteur = $proposition->auteur(); 
print $auteur->nomComplet(); 
// Umberto Eco

 

Derniers conseils

Il y a des bonnes pratiques à acquérir en matière de POO. C’est contraignant au début, mais à la longue ça se révèle très utile :

  • Appelez les méthodes, pas les propriétés : à l’exeption de la propriété $objet->id, j’encapsule toutes mes propriétés dans une fonction. Au lieu d’écrire print $article->titre, j’appelle $article->titre(). Dans un premier temps, la méthode titre() ne fera que retourner la propriété $this->titre. Inutile ? Non, car je m’autorise, demain ou dans 6 mois, à passer tous les titres en majuscule ou à convertir les caractères spéciaux avant de les afficher. Ou encore à construire le titre à partir de plusieurs champs de base de donnée. Bref, je ne suis pas limité au titre brut sorti de MySQL. Et cette modification n’aura lieu que dans la classe ; fini la traque aux variables dans cinquante templates différents.
  • Jamais de print dans une classe « métier » : une méthode comme $article->titre() ou $article->texte() n’affiche rien par elle-même. Elle renvoie une valeur via la commande return $valeur. Il y a plein de situations où le titre peut être utilisé sans être envoyé en sortie, c’est au template de gérer l’affichage.
  • Eviter le code HTML dans la classe : là encore, pour séparer les responsabilités. C’est au template de formater le texte, ou à une fonction externe spécialisée (j’ai par exemple une classe Format avec Format::texteWiki($texte)).

J’espère que cette introduction pourra éclairer ceux d’entre vous qui n’ont pas encore osé franchir le pas ou qui n’arrivent pas à comprendre l’intérêt de la POO dans leur travail. Et si vous avez déjà mis les mains dans le cambouis, n’hésitez pas à partager vos expériences ci-dessous. Merci.

Outil de référencement professionnel - essai gratuit Ce contenu a été publié dans Développement PHP, avec comme mot(s)-clé(s) , , , , . Vous pouvez le mettre en favoris avec ce permalien.

25 réponses à Tutoriel PHP : pourquoi passer au développement orienté objet ?

  1. visiteur dit :

    Merci pour l’article. Malheureusement un site l’a copié en intégralité:

    link to pckult.net.

    Il a beau citer la source en petit, ça ne vaut pas l’article complet !!

  2. Unknownn dit :

    Je n’ai jamais pensé à passer au développement orienté objet et je vois à travers cet article que j’ai bien tort.

    Merci pour cet article qui en fait une bonne introduction :)

    Amicalement,
    Unknownn.

  3. fridim dit :

    Je recommende ce livre link to amazon.fr. pour apprendre les bases de la prog POO. C’est en Java, mais honnetement, c’est quasiment la même chose en PHP. Le livre pose bien les bases et les bons réflexes. Après, y a aussi un livre chez O’reilly sur les designs patterns pour aller plus loin.

  4. Anonymous dit :

    Un bon petit article sans prétentions.

    Je trouve aussi dommage que l’OO ne soit pas utilisé par beaucoup de programmeurs PHP.

  5. Flo dit :

    Trés bon article. Il manque juste un download des sources. ;-)

  6. Controverse dit :

    Bonjour,

    L’article est très bien fait, simple et efficace, bravo !

    Par contre quand je vois la différence entre .net et PHP, je suis navré de devoir malgré tout préférer .net car pour une fois, Microsoft a bien été obligé de proposer un outil qualitatif et compétitif. Peut-être ont-ils eu peur du monde linux et de sa gratuité, fournissant des outils également très intéressants.

    Quoiqu’il en soit, l’ont peut depuis quelques temps déjà, avec l’application Visual Web Developer Express Edition (version entièrement gratuite, installée avec un SQL Server et un IIS light), développer de véritables applications rapidement et intuitivement en se servant de la POO.

    Quelqu’un sait si PHP prévoit quelque chose dans ce sens pour bientôt? Mon but n’est vraiment pas de jouer au troll mais de trouver les meilleurs outils.

    D’avance merci pour votre aide et à très bientôt.

  7. v4gab0nd dit :

    Très interessant ton article! Je vais le garder à coté de moi.
    Ton exemple est parfait pour comprendre la base! :)

  8. Selim dit :

    Merci de la contribution. Je suis au même stade que toi 2 ans plutôt ;-)

  9. Thomas dit :

    Simple question … (a tester) Les classes ne relentissent-elles pas les pages ?
    Je me souviens d’une interview du créateur de php qui disait qu’il ne comprenait pas pourquoi compliquer l’interprétation d’une page qui est, de toute façon, interpétée a chaque affichage et de façon linéaire.
    Perso, je préfère limiter les accès disques et les fonctions au maximum. et du coup les classes aussi.
    Idée stupide et rétrograde pensez vous ?

  10. @Thomas : peut-être, mais pas de manière significative. Vue la puissance des processeurs actuels, ce n’est pas à l’interprétation de la page que l’on ressent les plus gros ralentissements.
    Il y a quantité de paramètres qui ralentissent les pages de manière beaucoup plus nette : les requêtes SQL trop complexes ou qui renvoient trop de données en mémoire, les images téléchargées, les scripts Ajax externes, etc.

    D’ailleurs depuis que je suis passé sérieusement à la POO, mes scripts sont devenus plus rapides, car cela m’a permis d’optimiser les requêtes SQL…

  11. Thomas dit :

    oui, bien sure, un mauvais script reste un mauvais script avec ou sens poo. Mais c’est que je suis encore du genre a remplacer mes "." par des "," dans les echo pour gagner quelques ms de rapidité ;-)
    Il faut que je me penche la dessus (test à l’appui) rapport aux dernières versions de php.

  12. onet dit :

    @Thomas
    Autant je suis le premier partisant de l’optimisation, autant la, c’est allé trop loin ;). Autant coder tes sites en C directement, ce sera plus optimiser ;).

    Après, pense surtout à "l’après", au débuggage, à la réutilisation de code, a l’héritage, etc… ;)

  13. hpl76 dit :

    Bonjour, moi je suis un procédurier de base en prog, j’arrive pas à penser POO, ca me saoule (de ne pas y arriver). L’article est bien fait mais si vous avez des pistes, des tuto, des exemples qui rendent les choses moins abstraites je suis preneur :)
    Bien à vous. hpl76.

  14. Jo dit :

    Bonjour,

    L’article est vraiment buen et du coup ça me botte ! Le soucis c’est que je rejoins entièrement hpl76… Auriez vous l’adresse du meilleur tuto pour apprendre ? J’en ai fait 2-3 et c’est pas forcément évident.

    Merci !

  15. Twin Pics dit :

    Salut,
    Article excellent qui finit de me convaincre de passer à la POO!
    Mais comme j’ai appris le codage procédural en PHP en autodidacte (et je vous assure qu’il y a eu des moments de galère!) par tutoriels dénichés sur le web, j’ai déjà des frissons dans le dos de savoir que je vais être de nouveau confronté aux longues heures de débuggage de mes classes.
    Néammoins, étant persévérant (limite têtu disent de moi ceux qui me connaissent) je suis prêt à affronter la « Bête POO PHP »!

    Maintenant, reste à trouver de bons tutos, ceux que l’on comprend aisément sans qu’ils soient truffés d’exemples plus ou moins compréhensibles pour le profane que je suis!

    Je vous passe le bonsoir et m’en vais de ce pas effectuer une recherche en règle par moteurs de recherche interposé ;-)

  16. Kyos dit :

    Bonjour.

    Je suis à la recherche de tutoriels traitant de la POO en PHP, et je suis tombé sur ce blog très explicite sur les raisons de passer à la POO. Ceci étant, je suis déjà convaincu, mais il me manque un ou plutôt des bons tut, et je dois dire que je n’ai pas trouvé grand chose avec mon moteur de recherche. Il est vrai que je suis plutôt fâché avec l’anglais…
    Donc, si vous avez quelques adresses de tut si possible en français, merci de me les communiquer.

  17. ike dit :

    Bon pas encore passé a la POO, mas ca va venir =).
    Merci pour les encouragement.

    Sinon il y as un tuto sympa pour débuter ici : link to supersonique.net

    tchuss!

  18. Steve dit :

    Super article,

    ça m’a convaincu qu’après quelques années à faire du PHP apprit sur le tas, faudrait que je commence à évoluer…sinon je vais vite me retrouver dépasser avec cette programmation objet.

    Les exemples sont trés clairs !
    Merci

  19. Procédurier dit :

    Bonjour,

    Merci pour cet article qui eclaircit un peu les choses.

    Pour ma part, et comme d’autres, je développe de façon procédurale en PHP 4.
    Je n’arrive vraiment pas à me mettre à cette façon de penser « objet ».
    Durant mes études j’avais fait un peu de JAVA en objet, mais cela me semblait utile car il existe de nombreuses classes et fonctions existantes dans les API.

    En revanche en PHP pour vraiment faire de l’objet « intéressant » en réutilisant des bibliothèques, cela reviendrait à choisir un framework (ou CMS, je sais jamais) et alors là… lequel choisir ? quelle évolution ? quelle pérénisation ?
    Pour une petite structure qui crée des sites sur mesure de façon artisanale, quelle utilité de faire de l’objet ? créer son propre framework ? nécessitant une rigueur absolue et une documentation complète…. 1 an de travail pour quoi en définitive ?

    J’aimerais penser que l’objet va révolutionner nos développements web mais j’attend d’autres démonstrations plus édifiantes, car honnêtement je ne pige rien (lol).
    Mon expérience de l’objet se limite à l’utilisation de FPDF pour générer des fichiers PDF…

  20. saint-exupery dit :

    Procédurier, pour comprendre l’objet, il faut comprendre ce qu’est un objet. Dans la vie courante, tout ce qui nous entoure peut être qualifié comme étant un objet. Prenons l’exemple d’une porte.

    Une porte comporte des caractéristiques (largeur, hauteur, épaisseur, couleur, verrouillable, inifugable, etc) ; en POO, on appelle cela des attributs ou propriétés.

    A cette porte, on peut la manipuler (ouvrir, fermer, claquer, démonter, défoncer, vérrouiller, etc) ; en POO, on appelle cela des méthodes.

    La classe Porte pourrait dès lors s’écrire en PHP :
    class Porte
    float largeur
    float hauteur
    string couleur
    boolean estVerrouillable
    boolean estInifugeable
    function ouvrir(){}
    function fermer{}
    ….
    end class

    Si demain, on veut créer une nouvelle porte de type coffre fort. L’intérêt de la POO et l’héritage sont évidents. On hérite du travail déjà effectué sans recréer à zéro une porte.

    La porte de coffre fort dispose des mêmes caractéristiques que notre porte standard excepté qu’elles s’enrichit de ses propres caractéristiques comme : est blindée

    La classe PorteBlindee pourrait dès lors s’écrire en PHP :
    class PorteBlindee extends Porte
    boolean estBlindee
    end class

    En 3 lignes, on définit une porte blindée à partir du porte. On gagne donc du temps. On capitalise sur des développements passés. On enrichit sa collection des objets. Tout ceci contribue à écrire des programmes simples à comprendre, faciles à enrichir, faciles à débugguer.

    Si ma porte se ferme mal, c’est parce que la méthode de traitement destinée à la fermer fait mal son travail.

    Le problème se situe donc dans la méthode « fermer » de la classe « Porte », et ce, même si des dizaines de classes existents, que des dizaines de pages PHP existent sur un site.

    Voilà un exemple en quelques mots pour être convaincu des biens faits de la POO. ;-))

    La difficulté avec la POO, c’est d’avoir les idées claires, de faire preuve de bon sens et d’une bonne réflexion

  21. Coccoweb dit :

    Pas mal du tout, en plus les exemples avec les extensions de class, c’est vraiment sympa et super utile.
    La seul chose qui ma ennuyé, c’est le code afficher sur une seule ligne.

  22. Damien Ravé dit :

    @Coccoweb : merci pour l’info, le passage de Dotclear à WordPress a mis un peu la pagaille dans mes billets, mais (pour celui-ci en tout cas) c’est corrigé.

  23. chrisYo dit :

    J’ai fais quelques projets en utilisant la programmation procédurale chaotique comme décrite ici puis je me suis mis récemment à la POO et c’est véritablement plus simple. Je la conseille à tous également.

  24. Marc dit :

    Je sais que l’article est très ancien, mais comme on me l’a linké très récemment, je me permets de te demander si tu pouvais juste éditer le passage sur le constructeur : cette manière de le faire sera bientôt obsolète.

  25. caphar dit :

    Merci Marc, effectivement tout ça est assez ancien : je ne pensais pas qu’il pouvait encore y avoir des lecteurs sur ces pages ! Du coup j’ai corrigé avec un petit __construct() plus académique ;)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *