T: / Articles techniques / PHP
Découverte de ce paradigme de programmation et premiers éléments de syntaxe en PHP.
Tu as fait le tour de nos contenus « Apprendre le PHP », tu les as mis en pratique dans des challenges ou dans un de tes projets et tu souhaites aller + loin ?
Bienvenue dans le monde merveilleux de la Programmation Orientée Objet (POO) !
Au programme de ce premier tutoriel :
La Programmation Orientée Objet est un paradigme de programmation qui organise le code avec des objets. Ces objets vont représenter des entités ou concepts les plus réels possibles. C’est à dire qu’on va faire en sorte que le code représente des éléments palpables du contexte d’un projet.
S’il est question par exemple d’un programme pour une boutique ecommerce, alors on sera amené à créer ces objets :
Chaque objet a ensuite ses propres attributs, appelés « propriétés » et ses propres comportements, appelés « méthodes ». Pour rester dans l’exemple précédent :
Chaque objet est l’instance d’une classe, qui définit la structure et les communes à plusieurs objets similaires. Disons qu’on travaille sur un système ecommerce de vente de produits alimentaires :
La Programmation Orientée Objet donne un cadre et des conventions pour écrire et organiser son code, ce qui en favorise la réutilisation, la modularité et la maintenance.
La grande majorité des programmes évolués, des frameworks ou librairies sont codées en POO. Il est donc primordial de maitriser ce paradigme de programmation.
On va commencer tranquillement par créer une première classe 🙂
Pour commencer, il faut lui trouver un nom. On respectera le format « PascalCase », c’est à dire qu’on commence par une majuscule puis en minuscules, puis de nouveau une majuscule à chaque changement de mot.
Pour notre exemple, on va créer un objet « Student », un élève (on va coder en anglais pour respecter les conventions). Voici comment on va créer notre classe :
// Dans un fichier dédié Student.php
class Student
{
// Contenu de la classe
}
Un peu d’explications :
Une classe, c’est un peu comme une fonction, tant qu’on ne l’utilise pas, elle ne sert pas à grand chose ! On parle d’appel à une fonction. Et ici on va parler d’instanciation d’une classe :
// Dans mon programme principal
$student = new Student;
Un peu d’explications :
Les propriétés peuvent être considérées comme des variables de la classe, qui servent à définir ses données internes, son état, etc.
Pour notre élève, on peut avoir ces informations :
Voici comment coder ces propriétés :
class Student
{
public string $firstName;
public string $lastName;
public int $age;
public bool $hasFollowOnboarding = false;
}
Un peu d’explications :
Il existe 3 + 1 visibilité différentes :
Il y a en complément la notion de « readonly » qui signifie « lecture seule » qui permet de préciser qu’une propriété ne pourra être définie qu’une seule fois. On pourra l’initialiser, mais on ne pourra plus modifier sa valeur par la suite.
Retravaillons le code précédent avec ces éléments :
class Student
{
public readonly string $firstName;
public readonly string $lastName;
public readonly int $age;
private bool $hasFollowOnboarding = false;
}
Avant de manipuler ces propriétés depuis le programme principal, on va définir ce que sont les méthodes.
Les méthodes peuvent être considérées comme des fonctions de la classe, qui peuvent effectuer des opérations sur les propriétés pour renvoyer, ou non, des données vers le programme principal.
Le parallèle avec les fonctions s’applique notamment car les méthodes vont avoir aussi :
Le constructeur est la méthode magique (oui c’est le vrai terme) qui sera appelée de façon automatique lorsqu’on instancie une classe.
Le constructeur peut avoir des paramètres. On va faire en sorte ici de définir le prenom et nom de l’élève :
class Student
{
public readonly string $firstName;
public readonly string $lastName;
public int $age;
private bool $hasFollowOnboarding = false;
// Le constructeur NE DOIT PAS avoir de type de retour
public function __construct(string $firstName, string $lastName)
{
$this->firstName = $firstName;
$this->lastName = $lastName;
}
}
Un peu d’explications :
Pour activer le constructeur, voici comment faire lors de l’instanciation :
// On appelle la classe "à la manière" de l'appel d'une fonction
$student = new Student('John', 'Doe');
Cette façon d’écrire un constructeur est intéressante pour aborder les méthodes et $this mais est obsolète depuis PHP 8. On peut désormais utiliser la promotion de propriétés dans le constructeur, ce qui donnerait :
class Student
{
// Propriétés hors constructeur
public readonly int $age;
private bool $hasFollowOnboarding;
// Constructeur avec promotion de propriétés
public function __construct(
public readonly string $firstName,
public readonly string $lastName,
) {}
}
Voyons voir comment je peux utiliser les propriétés dans le programme principal :
// Dans mon programme principal $student = new Student('John', 'Doe'); // On utilise la flèche pour faire référence à une propriété // Comme ces propriétés sont publiques je peux les appeler echo 'L\'élève s\'appelle ' . $student->firstName . ' ' . $student->lastName; // Cette ligne renvoie une ERREUR car cette propriété n'a pas encore de valeur // Aucune valeur par défaut et aucune initialisation echo 'Son âge est ' . $student->age . ' ans.'; // Il faut donc l'initialiser avant de cette façon : (attention, ceci n'est pas une bonne pratique, on va le voir juste après) $student->age = 30; // Cette ligne renvoie une ERREUR car cette propriété, bien que définie avec une valeur par défaut, est privée (private) if ($student->hasFollowOnboarding) { // ... }Nous allons créer d’autres méthodes pour manipuler les propriétés.
Une première méthode pour initialiser l’âge puisque celui-ci n’est pas géré par le constructeur :
// Dans l'objet
public function setAge(int $age): void
{
$this->age = $age;
}
Un peu d’explications :
Le pendant du setter est le getter, qui sert justement à accéder à une propriété privée en dehors de l’objet :
// Dans l'objet -----------------
private int $age;
// Setter
public function setAge(int $age): void
{
$this->age = $age;
}
// Getter
public function getAge(): int
{
return $this->age;
}
// Dans le programme principal -------------
$student = new Student('John', 'Doe');
$student->setAge(30);
// Cette fois-ci aucune erreur !
echo 'Son âge est ' . $student->getAge() . ' ans.';
Un peu d’explications :
Créons d’autres méthodes :
// L'étudiant.e suit le parcours de formation
public function followOnboarding(): void
{
$this->hasFollowOnboarding = true;
}
// L'étudiant fête son anniversaire
public function birthday(): void
{
$this->age++;
}
// Les informations de l'étudiant au format HTML
public function getCompleteInformationsInHtml(): string
{
$out = '<ul>';
$out .= '<li>Prénom : ' . $this->firstName . '</li>';
$out .= '<li>Nom : ' . $this->lastName . '</li>';
$out .= '<li>Âge : ' . $this->getAge() . '</li>'; // Utilisation d'une méthode interne
if ($this->hasFollowOnboarding) {
$out .= '<li>Onboarding bien suivi !</li>';
}
return $out;
}
Un peu d’explications :
Pour aller + loin sur les notions de typage, tu peux retrouver la liste des types disponibles en PHP.
Et n’hésite pas à te référer à un corrigé en PHP pour voir d’autres exemples + poussés de méthodes.
Définissons une petite classe assez simple qui va nous permettre d’illustrer la notion de référence en POO :
class School
{
public string $name;
}
On oublie les bonnes pratiques énoncées au dessus. On va créer un objet et le modifier :
// Je crée une école et je lui donne un nom
$ecoleA = new School;
$ecoleA->name = 'Harvard';
// Je copie ecoleA dans ecoleB
$ecoleB = $ecoleA;
// Je change ecoleB
$ecoleB->name = 'Oxford';
// Et maintenant...
echo $ecoleA->name; // ??
echo $ecoleB->name; // ??
Instinctivement, on se dit que $ecoleA->name vaut toujours « Harvard » comme on l’a changé sur $ecoleB et non sur $ecoleA… Et bien non, les 2 echo vont afficher la même chose, à savoir « Oxford ».
En fait, $ecoleA ne contient pas l’objet, il contient la référence à celui-ci. Quand on fait le new, on crée un objet (= une instance de classe), et c’est la référence à l’objet qui est stockée dans la variable. Comme si la variable stockait la direction vers l’objet, l’endroit où il est rangé.
Donc lorsque je fais :
$ecoleB = $ecoleA;
Et bien, je ne copie pas l’objet, je copie la référence, donc les 2 variables pointent vers le même objet.
Pour copier un objet il faut utiliser la méthode clone. Mais je ne la présente pas tout de suite car on n’a pas forcément besoin de l’utiliser si souvent que ça.
Quelques informations complémentaires et exemples sur les références sur la modification des valeurs d’un tableau avec foreach en PHP.
Voilà pour un premier tour d’horizon de la POO en PHP !
Pour mettre en pratique et assimiler ces concepts, je t’invite à choisir un challenge de code débutant et à le résoudre avec une logique POO.
Other content to discover