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 ?

Laisser un commentaire

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