Programmation orientée objet (avancé)

Programmation orientée objet (avancé)

Lien vers le cours

L. Delafontaine, avec l'aide de GitHub Copilot.

Ce travail est sous licence CC BY-SA 4.0.

Programmation orientée objet (avancé)

Retrouvez plus de détails dans le support de cours

Cette présentation est un résumé du support de cours. Pour plus de détails, consultez le support de cours.

Programmation orientée objet (avancé)

Objectifs

  • Rappeler les concepts de base de la programmation orientée objet.
  • Appliquer les notions d'interface, d'héritage et d'abstraction avec la programmation orientée objet.
Programmation orientée objet (avancé)

PHP, un rappel

Programmation orientée objet (avancé)

Architecture client-serveur (1/2)

  • La plupart des applications web modernes reposent sur une architecture dite "client-serveur" :
    1. Un client (navigateur web) envoie une requête à un serveur.
    2. Le serveur répond aux requêtes des différents clients.
    3. Le client affiche le résultat de la requête.
  • PHP repose sur cette même architecture.
Programmation orientée objet (avancé)

Architecture client-serveur (2/2)

  • PHP fonctionne grâce aux outils suivants :
    • Un serveur web.
    • PHP installé sur le serveur web.
    • Un navigateur web.
    • Un éditeur de code (pour le développement).
Programmation orientée objet (avancé)

Variables (1/2)

  • PHP est un language de programmation à typage dynamique.
  • Il n'y a pas besoin de déclarer le type de données d'une variable.
  • Le type de données d'une variable est déterminé par la valeur qui lui est assignée.
Programmation orientée objet (avancé)

Variables (2/2)

  • Une variable commence toujours par le symbole $ en PHP.
  • Une valeur lui est affectée (= donnée) avec l'opérateur =.
  • Une variable peut changer de type en cours d'exécution.
<?php
$variable = "Hello";                        // string
$variable = 42;                             // int
$variable = 3.14;                           // float
$variable = true;                           // bool
$variable = [true, 2, "3", 4 => [5, 6, 7]]; // array
$variable = null;                           // null
Programmation orientée objet (avancé)

Constantes (1/2)

  • Les constantes sont des valeurs qui ne peuvent pas être modifiées.
  • Les constantes sont déclarées avec le mot-clé const ou avec la fonction define().
  • La convention veut que les constantes soient écrites en majuscules.
Programmation orientée objet (avancé)

Constantes (2/2)

<?php
define("PI", 3.14159); // Définition d'une constante
const EULER = 2.71828; // Définition d'une constante

echo PI;    // Affiche 3.14159
echo EULER; // Affiche 2.71828

PI = 3.14; // Erreur : les constantes ne peuvent pas être modifiées
Programmation orientée objet (avancé)

Opérateurs (1/2)

  • Permet d'effectuer des opérations sur des variables et des valeurs.
  • Opérateurs arithmétiques : +, -, *, /, % (modulo)
  • Opérateurs de comparaison : == (égal), != (différent), > (supérieur), < (inférieur)
  • Opérateurs logiques : && (et), || (ou), ! (non/inversion)
Programmation orientée objet (avancé)

Opérateurs (2/2)

<?php

$a = 10;
$b = 5;
$c = 15;
$d = 15;

// L'opérateur `===` permet de vérifier la valeur et le type (à préférer).
if ($a > $b && $c === $d) {
  echo "Condition met!";
} else {
  echo "Condition not met!";
}
Programmation orientée objet (avancé)

Structures conditionnelles (1/4)

  • Permettent de contrôler le flux d'exécution d'un programme.
  • Utilisent les opérateurs de comparaison et logiques.
  • Elles se composent de if, else, elseif et switch.
Programmation orientée objet (avancé)

Structures conditionnelles (2/4)

<?php
$age = 20;

if ($age < 18) {
    echo "You are a minor.";
} elseif ($age >= 18 && $age < 65) {
    echo "You are an adult.";
} else {
    echo "You are a senior.";
}
Programmation orientée objet (avancé)

Structures conditionnelles (3/4)

<?php
$day = "Monday";

switch ($day) {
    case "Monday":
        echo "It's Monday!";
        break;
    case "Tuesday":
        echo "It's Tuesday!";
        break;
    case "Wednesday":
        echo "It's Wednesday!";
        break;
// ...
// ...
    case "Thursday":
        echo "It's Thursday!";
        break;
    case "Friday":
        echo "It's Friday!";
        break;
    case "Saturday":
        echo "It's Saturday!";
        break;
    case "Sunday":
        echo "It's Sunday!";
        break;
}
Programmation orientée objet (avancé)

Structures conditionnelles (4/4)

<?php
$day = "Monday";

switch ($day) {
    case "Monday":
    case "Tuesday":
    case "Wednesday":
    case "Thursday":
    case "Friday":
        echo "It's a weekday!";
        break;
// ...
// ...
    case "Saturday":
    case "Sunday":
        echo "It's the weekend!";
        break;
    default:
        echo "Invalid day!";
        break;
}
Programmation orientée objet (avancé)

Fonctions

  • Ensemble d'instructions pour effectuer une tâche spécifique
  • Inspirée des fonctions mathématiques :
    • est un paramètre
    • , , etc.
  • Permettent de structurer le code en blocs réutilisables.
Programmation orientée objet (avancé)

Fonctions sans paramètres

<?php
function greet() {
    return "Hello, World!";
}

// 1. Exécute la fonction `greet()`
// 2. Récupère la valeur de retour
// 3. Affecte (= donne) cette valeur à la variable `$greetings`
$greetings = greet();

// Affiche le résultat ("Hello, World!")
echo $greetings;
Programmation orientée objet (avancé)

Fonctions avec paramètres

<?php
function greet($name) {
    return "Hello, " . $name . "!";
}

$greetings = greet("Alice");
echo $greetings . "<br>";       // "Hello, Alice!"
echo greet("Bob") . "<br>";     // "Hello, Bob!"
Programmation orientée objet (avancé)

Fonctions avec des paramètres par défaut

<?php
function greet($name = "World") {
    return "Hello, " . $name . "!";
}

echo greet() . "<br>";          // "Hello, World!" (utilise la valeur par défaut)
echo greet("Alice") . "<br>";   // "Hello, Alice!" (utilise l'argument fourni)
Programmation orientée objet (avancé)

Fonctions avec typage des paramètres et du retour (1/2)

  • Depuis la version 7.1 de PHP, il est possible de typer les paramètres et le retour des fonctions.
<?php
function greet(string $name = "World"): string {
    return "Hello, " . $name . "!";
}

function add(int $a, int $b): int {
    return $a + $b;
}
Programmation orientée objet (avancé)

Fonctions avec typage des paramètres et du retour (2/2)

  • Le typage permet de s'assurer que les arguments passés à une fonction sont du bon type.
echo greet() . "<br>";          // "Hello, World!"
echo greet("Alice") . "<br>";   // "Hello, Alice!"
echo greet(42) . "<br>";        // "Hello, 42!" (conversion implicite)
echo add(2, 3) . "<br>";        // 5

// Erreur 1 : Implicit conversion from float 2.5 to int loses precision
// Erreur 2 : Argument #2 ($b) must be of type int, string given
echo add(2.5, "Hello") . "<br>";
Programmation orientée objet (avancé)

Importation de fichiers (1/2)

  • L'importation permet de réutiliser du code défini dans d'autres fichiers.
  • Il est recommandé d'utiliser require (erreur et arrête l'exécution) plutôt que include (avertissement mais continue l'exécution).
Programmation orientée objet (avancé)

Importation de fichiers (2/2)

<?php
// Fichier functions.php
function greet(string $name = "World"): string {
    return "Hello, " . $name . "!";
}
<?php
// Fichier index.php
require "functions.php";

echo greet("Alice"); // "Hello, Alice!"
Programmation orientée objet (avancé)

Tableaux et boucles

Programmation orientée objet (avancé)

Tableaux (1/2)

  • Les tableaux sont des collections de valeurs.
  • Les tableaux sont déclarés entre des crochets ([]) ou avec la fonction array().
  • Les valeurs peuvent être de n'importe quel type.
  • Il existe trois types de tableaux en PHP : indexés, associatifs et multidimensionnels.
Programmation orientée objet (avancé)

Tableaux (2/2)

<?php
// Tableau indexé numériquement
$fruits = ['apple', 'banana', 'orange'];

echo $fruits[0] . "<br>"; // "apple"

// Tableau associatif
$person = [
    'name' => 'Alice',
    'age' => 30,
    'city' => 'New York'
];

echo $person['name'] . "<br>"; // "Alice"
Programmation orientée objet (avancé)

Boucles (1/5)

  • Les boucles sont des structures de contrôle qui permettent d'exécuter un bloc de code plusieurs fois.
  • Elles sont utilisées pour parcourir des tableaux ou des collections de données.
  • Il existe plusieurs types de boucles en PHP : for, while, do...while et foreach.
Programmation orientée objet (avancé)

Boucles (2/5)

<?php
// Affiche les nombres de 0 à 9
for ($i = 0; $i < 10; $i++) {
    echo "$i<br>";
}
Programmation orientée objet (avancé)

Boucles (3/5)

<?php
$i = 0;

// Affiche les nombres de 0 à 9
while ($i < 10) {
    echo "$i<br>";
    $i++;
}
Programmation orientée objet (avancé)

Boucles (4/5)

<?php
$randomNumber = null;

do {
    // La fonction `rand()` génère un nombre aléatoire entre 1 et 10
    $randomNumber = rand(1, 10);
    echo "The random number is $randomNumber<br>";
} while ($randomNumber < 8);
Programmation orientée objet (avancé)

Boucles (5/5)

<?php
$users = [
    'john' => [
        'name' => 'John Doe',
        'age' => 30,
        'city' => 'New York',
    ],
    'jane' => [
        'name' => 'Jane Doe',
        'age' => 25,
        'city' => 'Los Angeles',
    ],
];
Programmation orientée objet (avancé)
// `$user` contient la valeur de l'élément du tableau
foreach ($users as $user) {
    echo "Name: {$user['name']}<br>";
    echo "Age: {$user['age']}<br>";
    echo "City: {$user['city']}<br>";
    echo "<br>";
}
Programmation orientée objet (avancé)

Formulaires HTML, validation et sécurité

  • Les formulaires HTML permettent de collecter des données.
  • Les données des formulaires sont stockées dans les superglobales $_POST et $_GET.
  • Il est nécessaire de traiter et valider les données pour éviter des vulnérabilités.
Programmation orientée objet (avancé)

Programmation orientée objet (base) (1/2)

  • Paradigme de programmation qui utilise des "objets" pour modéliser des concepts du monde réel.
  • Une classe est un modèle pour créer des objets. Un objet est une instance (= un exemplaire) d'une classe.
Programmation orientée objet (avancé)

Programmation orientée objet (base) (2/2)

<?php
class User {
    // Propriétés (attributs)
    private string $firstName;
    private string $lastName;

    // Constructeur
    public function __construct(string $firstName, string $lastName) {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
    }
Programmation orientée objet (avancé)
    // Méthodes
    public function getFirstName(): string {
        return $this->firstName;
    }

    public function setFirstName(string $firstName): void {
        $this->firstName = $firstName;
    }

    public function getLastName(): string {
        return $this->lastName;
    }

    public function setLastName(string $lastName): void {
        $this->lastName = $lastName;
    }

    public function getFullName(): string {
        return "{$this->firstName} {$this->lastName}";
    }
}
Programmation orientée objet (avancé)
// Création d'objets (instanciation)
$user1 = new User("Alice", "Smith");
$user2 = new User("Bob", "Johnson");

// Utilisation des méthodes
echo $user1->getFirstName() . "<br>";   // "Alice"
echo $user2->getFullName() . "<br>";    // "Bob Johnson"
$user2->setLastName("Doe");             // Modifie le nom de famille de Bob
echo $user2->getFullName() . "<br>";    // "Bob Doe"
Programmation orientée objet (avancé)

Programmation orientée objet (avancé)

Programmation orientée objet (avancé)

Interfaces (1/2)

  • Les interfaces définissent un contrat que les classes doivent respecter.
  • Chaque classe qui implémente une interface doit définir toutes les méthodes déclarées dans l'interface.
  • Cela permet de garantir que certaines méthodes sont toujours présentes dans les classes qui implémentent l'interface.
Programmation orientée objet (avancé)

Interfaces (2/2)

<?php
interface AnimalInterface {
    public function makeSound(): string;
    public function getHabitat(): string;
}
Programmation orientée objet (avancé)
class Lion implements AnimalInterface {
    public function makeSound(): string {
        return "Roar!";
    }

    public function getHabitat(): string {
        return "Savannah";
    }
}

class Penguin implements AnimalInterface {
    public function makeSound(): string {
        return "Honk!";
    }

    public function getHabitat(): string {
        return "Antarctica";
    }
}
Programmation orientée objet (avancé)
$lion = new Lion();
$penguin = new Penguin();

echo $lion->makeSound();        // "Roar!"
echo $lion->getHabitat();       // "Savannah"
echo $penguin->makeSound();     // "Honk!"
echo $penguin->getHabitat();    // "Antarctica"
Programmation orientée objet (avancé)

Héritage (1/2)

  • L'héritage permet à une classe fille d'hériter des propriétés et méthodes d'une classe parent.
  • Cela favorise la réutilisation du code et la création de hiérarchies de classes.
Programmation orientée objet (avancé)

Héritage (2/2)

<?php
class Plant {
    protected string $englishName;
    protected string $latinName;

    public function __construct(string $englishName, string $latinName) {
        $this->englishName = $englishName;
        $this->latinName = $latinName;
    }

    public function getEnglishName(): string {
        return $this->englishName;
    }

    public function getLatinName(): int {
        return $this->latinName;
    }
}
Programmation orientée objet (avancé)
class Basil extends Plant {
    private string $variety;

    public function __construct(string $englishName, string $latinName, string $variety) {
        parent::__construct($englishName, $latinName);
        $this->variety = $variety;
    }

    public function getVariety(): string {
        return $this->variety;
    }
}
Programmation orientée objet (avancé)
class Tomato extends Plant {
    private string $color;

    public function __construct(string $englishName, string $latinName, string $color) {
        parent::__construct($englishName, $latinName);
        $this->color = $color;
    }

    public function getColor(): string {
        return $this->color;
    }
}
Programmation orientée objet (avancé)
$plant = new Plant("Generic Plant", "Plantae");
$basil = new Basil("Basil", "Ocimum basilicum", "Sweet Basil");
$tomato = new Tomato("Tomato", "Solanum lycopersicum", "Red");

echo $plant->getEnglishName(); // "Generic Plant"
echo $plant->getLatinName();   // "Plantae"
echo $basil->getVariety();     // "Sweet Basil"
echo $tomato->getColor();      // "Red"
Programmation orientée objet (avancé)

Abstraction (1/2)

  • Les classes abstraites définissent une base commune avec des méthodes partiellement implémentées.
  • Une classe abstraite ne peut pas être instanciée directement.
  • Les classes filles doivent implémenter les méthodes abstraites définies dans la classe abstraite.
Programmation orientée objet (avancé)

Abstraction (2/2)

<?php
abstract class Shape {
    protected string $color;

    public function __construct(string $color) {
        $this->color = $color;
    }

    // Méthode concrète (implémentée)
    public function getColor(): string {
        return $this->color;
    }

    // Méthodes abstraites (doivent être implémentées par les classes filles)
    abstract public function calculateArea(): float;
    abstract public function calculatePerimeter(): float;


Programmation orientée objet (avancé)
    // Méthode concrète utilisant les méthodes abstraites
    public function getShapeInfo(): string {
        return sprintf(
            "Shape: %s, Color: %s, Area: %.2f, Perimeter: %.2f",
            static::class,
            $this->color,
            $this->calculateArea(),
            $this->calculatePerimeter()
        );
    }
}
Programmation orientée objet (avancé)
class Rectangle extends Shape {
    private float $width;
    private float $height;

    public function __construct(string $color, float $width, float $height) {
        parent::__construct($color);
        $this->width = $width;
        $this->height = $height;
    }

    public function calculateArea(): float {
        return $this->width * $this->height;
    }

    public function calculatePerimeter(): float {
        return 2 * ($this->width + $this->height);
    }
}
Programmation orientée objet (avancé)
class Circle extends Shape {
    private float $radius;

    public function __construct(string $color, float $radius) {
        parent::__construct($color);
        $this->radius = $radius;
    }

    public function calculateArea(): float {
        return pi() * pow($this->radius, 2);
    }

    public function calculatePerimeter(): float {
        return 2 * pi() * $this->radius;
    }
}
Programmation orientée objet (avancé)
$rectangle = new Rectangle("blue", 10, 5);
$circle = new Circle("red", 7);

echo $rectangle->getShapeInfo();
// Shape: Rectangle, Color: blue, Area: 50.00, Perimeter: 30.00

echo $circle->getShapeInfo();
// Shape: Circle, Color: red, Area: 153.94, Perimeter: 43.98
$shape = new Shape("green"); // Erreur fatale : Cannot instantiate abstract class Shape
Programmation orientée objet (avancé)

Inclusion des fichiers et classes

  • Pour organiser le code, chaque classe peut être définie dans son propre fichier.
  • Il est important de gérer correctement l'inclusion des fichiers pour éviter les erreurs.
Programmation orientée objet (avancé)

Inclusion manuelle

  • L'inclusion manuelle consiste à inclure chaque fichier de classe individuellement avec require ou include.
  • Cela peut devenir fastidieux dans les projets avec de nombreuses classes.
  • Il est préférable d'utiliser require_once ou include_once pour éviter les inclusions multiples.
  • Illustrons les problèmes potentiels avec un exemple simple.
Programmation orientée objet (avancé)
Programmation orientée objet (avancé)
<?php
// Animal.php
abstract class Animal {
    protected string $name;
    protected float $size;

    public function __construct(string $name, float $size) {
        $this->name = $name;
        $this->size = $size;
    }

    abstract public function makeSound(): string;

    public function getName(): string {
        return $this->name;
    }

    public function setName(string $name): void {
        $this->name = $name;
    }

    public function getSize(): float {
        return $this->size;
    }

    public function setSize(float $size): void {
        $this->size = $size;
    }
}
Programmation orientée objet (avancé)
<?php
// Pet.php
require 'Animal.php';

abstract class Pet extends Animal {
    protected string $nickname;

    public function __construct(string $name, float $size, string $nickname) {
        parent::__construct($name, $size);
        $this->nickname = $nickname;
    }

    public function getNickname(): string {
        return $this->nickname;
    }

    public function setNickname(string $nickname): void {
        $this->nickname = $nickname;
    }
}
Programmation orientée objet (avancé)
<?php
// Dog.php
require 'Pet.php';

class Dog extends Pet {
    public function __construct(string $name, float $size, string $nickname) {
        parent::__construct($name, $size, $nickname);
    }

    public function makeSound(): string {
        return "Woof!";
    }
}
Programmation orientée objet (avancé)
<?php
// Cat.php
require 'Pet.php';

class Cat extends Pet {
    public function __construct(string $name, float $size, string $nickname) {
        parent::__construct($name, $size, $nickname);
    }

    public function makeSound(): string {
        return "Meow!";
    }
}
Programmation orientée objet (avancé)
<?php
// index.php
require 'Dog.php';
require 'Cat.php';

$dog = new Dog("Nalia", 30.5, "Naliouille");
$cat = new Cat("Tofu", 10.0, "Sushi");

echo $dog->getName() . " says: " . $dog->makeSound() . "<br>";
echo $cat->getName() . " says: " . $cat->makeSound() . "<br>";
Programmation orientée objet (avancé)
<?php
// Dog.php
require_once 'Pet.php';
...
<?php
// Cat.php
require_once 'Pet.php';
...
<?php
// Pet.php
require_once 'Animal.php';
...
Programmation orientée objet (avancé)

Espaces de noms (namespaces) (1/2)

  • Les namespaces permettent d'organiser le code et d'éviter les conflits de noms dans des projets qui utilisent de nombreuses classes.
  • Ils sont définis avec le mot-clé namespace au début d'un fichier.
  • Ils permettent de grouper des classes, interfaces, fonctions et constantes sous un même espace de noms.
Programmation orientée objet (avancé)
<?php
// src/Animals/Animal.php
namespace Animals;

abstract class Animal {
    protected string $name;
    // ...
}
Programmation orientée objet (avancé)
<?php
// src/Animals/Pets/Pet.php
namespace Animals\Pets;

require_once 'Animal.php';

use Animals\Animal;

abstract class Pet extends Animal {
    protected string $nickname;
    // ...
}
Programmation orientée objet (avancé)
<?php
// src/Animals/Pets/Dog.php
namespace Animals\Pets;

require_once 'Pet.php';

use Animals\Pets\Pet;

class Dog extends Pet {
    // ...
}
Programmation orientée objet (avancé)
<?php
// src/Animals/Pets/Cat.php
namespace Animals\Pets;

require_once 'Pet.php';

use Animals\Pets\Pet;

class Cat extends Pet {
    // ...
}
Programmation orientée objet (avancé)

Inclusion automatique (autoloader) (1/2)

  • L'autoloader permet de charger automatiquement les classes sans inclusions manuelles.
  • Permet de simplifier la gestion des dépendances.
  • L'autoloader sera chargé d'importer les classes au moment où elles sont utilisées en utilisant le namespace pour localiser le fichier.
Programmation orientée objet (avancé)

Inclusion automatique (autoloader) (2/2)

<?php
// autoloader.php
// Charge les classes automatiquement
spl_autoload_register(function ($class) {
    // Convertit les séparateurs de namespace en séparateurs de répertoires
    $relativePath = str_replace('\\', '/', $class);

    // Construit le chemin complet du fichier
    $file = __DIR__ . '/../classes/' . $relativePath . '.php';

    // Vérifie si le fichier existe avant de l'inclure
    if (file_exists($file)) {
        // Inclut le fichier de classe
        require_once $file;
    }
});
Programmation orientée objet (avancé)
<?php
// index.php
require 'autoloader.php'; // Plus besoin d'inclure chaque fichier de classe manuellement

use Animals\Pets\Dog;
use Animals\Pets\Cat;

$dog = new Dog("Nalia", 30.5, "Naliouille");
$cat = new Cat("Tofu", 10.0, "Sushi");

echo $dog->getName() . " says: " . $dog->makeSound() . "<br>";
echo $cat->getName() . " says: " . $cat->makeSound() . "<br>";
Programmation orientée objet (avancé)

Limites de l'héritage et de l'abstraction

  • PHP ne supporte pas l'héritage multiple (une classe ne peut hériter que d'une seule classe parent).
  • Mais une classe peut implémenter plusieurs interfaces.
  • Ces concepts sont à utiliser avec parcimonie pour éviter une complexité excessive :
    • Restez simple.
    • Évitez les hiérarchies trop profondes ou complexes.
Programmation orientée objet (avancé)
Programmation orientée objet (avancé)

Conclusion

  • PHP est un langage de programmation à typage dynamique, largement utilisé pour le développement web.
  • La programmation orientée objet (POO) est un paradigme puissant pour structurer le code.
  • Les concepts avancés de la POO, tels que les interfaces, l'héritage et l'abstraction, permettent de créer des applications modulaires et maintenables.
  • Utilisez les namespaces et l'autoloading pour organiser et gérer vos classes efficacement.
Programmation orientée objet (avancé)

Questions

Est-ce que vous avez des questions ?

Programmation orientée objet (avancé)

À vous de jouer !

  • (Re)lire le support de cours.
  • Explorer les exemples de code.
  • Faire les exercices.
  • Poser des questions si nécessaire.

➡️ Lien vers le cours

N'hésitez pas à vous entraidez si vous avez des difficultés !

Programmation orientée objet (avancé)

Sources (1/2)

Programmation orientée objet (avancé)

Sources (2/2)

URLs

Illustrations