<?php
class Personne {
// Attributs de la classe
private string $prenom;
private string $nom;
private int $age;
// Constructeur
public function __construct(string $prenom, string $nom, int $age) {
// Initialisation ou on passe par les setters
$this->setPrenom($prenom);
$this->setNom($nom);
$this->setAge($age);
}
// Destructeur
public function __destruct() {
// Du code à exécuter
print "Destruction de " . __CLASS__ . " {$this->nom}\n";
}
// Méthode toString
public function __toString(): string {
return "[$this->prenom, $this->nom, $this->age]";
}
// Getters
public function getPrenom(): string {
return $this->prenom;
}
public function getNom(): string {
return $this->nom;
}
public function getAge(): int {
return $this->age;
}
// Setters
public function setPrenom(string $prenom): void {
$this->prenom = $prenom;
}
public function setNom(string $nom): void {
$this->nom = $nom;
}
public function setAge(int $age): void {
$this->age = $age;
}
}
// Test
// Création d'objets Personne
$p1 = new Personne("Paul", "Hervé", 48);
$p2 = new Personne("Jules", "Savary", 20);
// Identité de cette personne
print "personne1 = $p1\n";
// On change l'âge
$p1->setAge(24);
// Identité de la personne
print "personne1 = $p1\n";
print "personne2 = $p2\n";
?>
$this
dans une classe pour
faire référence aux propriétés et méthodes
<?php
class Toto {
public int $x = 3;
function afficherX() : void {
echo $x; // (au lieu de $this->x)
}
}
$toto = new Toto();
$toto->afficherX(); // lève une Notice: undefined variable $x
?>
$
,
mais pas ailleurs. Cependant, mettre un $
n'est pas une erreur de syntaxe, ça fait juste
autre chose que ce qu'on voudrait…
<?php
class Toto {
public int $x = 3;
}
$toto = new Toto();
// Affiche 3
echo $toto->x."\n";
// Lève une Notice: undefined variable $x
// Affiche 3
echo $toto->{'x'}."\n";
$variable = "x";
// Affiche 3 : $toto->$variable est interprété comme $toto->x !
echo $toto->{$variable}."\n";
?>
<?php
class Toto {
public int $x = 3;
public string $y = 'coucou';
}
$toto = new Toto();
foreach ($toto as $k => $v) {
echo "cle $k, valeur $v\n";
}
// résultat :
// cle x, valeur 3
// cle y, valeur coucou
?>
__construct()
__destruct()
: appelée lorsque l'instance est détruite
(utilisation de unset
, ou fin de l'exécution du script)__toString()
: appelée lorsque l'objet doit être converti
en chaîne de caractères
<?php
class Point {
public int $x;
public int $y;
public function __construct(int $x, int $y) {
$this->x = $x;
$this->y = $y;
}
public function __toString(): string {
return "({$this->x},{$this->y})";
}
}
$p = new Point(3, 2);
echo $p."\n";
?>
(3,2)
<?php
class Compteur {
public static int $count;
public static function getCount(): int {
return self::$count++;
}
}
Compteur::$count = 1;
for ($i = 0; $i < 10; ++$i) {
echo 'La valeur suivante est : ' . Compteur::getCount() . "<br>";
}
?>
La valeur suivante est : 1
La valeur suivante est : 2
La valeur suivante est : 3
La valeur suivante est : 4
La valeur suivante est : 5
La valeur suivante est : 6
La valeur suivante est : 7
La valeur suivante est : 8
La valeur suivante est : 9
La valeur suivante est : 10
static
$this
, mais avec le mot-clef self
,
qui représente « la classe de l'instance courante »
<?php
class Toto {
private static int $compteur = 0;
private string $contenu;
public function __construct(string $contenu) {
$this->contenu = $contenu;
self::$compteur++;
}
public function printInstanceStats(): string {
// Utilisation de $this->dummy au lieu de $this->compteur
return $this->contenu . " et " . self::$compteur . "\n";
}
public static function printClassStats(): string {
// Commenté pour éviter une fatal error
// $this->dummy = "toto";
return "Il y a actuellement " . self::$compteur . " instances de la classe Toto\n";
}
public function __destruct() {
echo "Destruction d'une instance\n";
self::$compteur--;
}
}
echo Toto::printClassStats();
$A = new Toto("instance A");
echo "\$this->compteur n'est pas défini => donne une chaine vide et une Notice\n";
echo "A : " . $A->printInstanceStats();
echo Toto::printClassStats();
$B = new Toto("instance B");
echo "\$this->compteur n'est pas défini => donne une chaine vide et une Notice\n";
echo "B : " . $B->printInstanceStats();
echo Toto::printClassStats();
echo "unset(\$A)\n";
unset($A);
echo Toto::printClassStats();
unset($B);
echo Toto::printClassStats();
?>
Il y a actuellement 0 instances de la classe Toto $this->compteur n'est pas défini => donne une chaine vide et une Notice A : instance A et 1 Il y a actuellement 1 instances de la classe Toto $this->compteur n'est pas défini => donne une chaine vide et une Notice B : instance B et 2 Il y a actuellement 2 instances de la classe Toto unset($A) Destruction d'une instance Il y a actuellement 1 instances de la classe Toto Destruction d'une instance Il y a actuellement 0 instances de la classe Toto
const
::
<?php
class MyClass {
const ma_constante = 'toto';
public function showConstant(): void {
echo "Voici ma constante: " . self::ma_constante . "\n";
}
public function chgeConstant(): void {
// En PHP 8, une constante ne peut pas être modifiée après sa définition.
// Cela générera une erreur fatale.
// self::ma_constante = "test d'erreur";
}
}
$obj = new MyClass();
$obj->showConstant();
echo "MyClass::ma_constante : " . MyClass::ma_constante . "\n"; // Fonctionne
// Les constantes de classe ne peuvent pas être accédées via une instance
//echo "\$obj->ma_constante : " . $obj->ma_constante . "\n"; // Ne fonctionne pas
// Vous pouvez accéder à une constante de classe via une instance en utilisant ::
echo "\$obj::ma_constante : " . $obj::ma_constante . "\n";
?>
extends
<?php
class Rectangle {
protected float $longueur;
protected float $largeur;
public function __construct(float $longueur, float $largeur) {
$this->longueur = $longueur;
$this->largeur = $largeur;
}
}
class Carre extends Rectangle {
public function __construct(float $cote) {
parent::__construct($cote, $cote);
}
}
?>
parent::__construct()
self
: static
static::toto
n'est pas forcément le toto
de la classe courante,
mais celui de la classe qui a effectivement été instanciée à l'exécution
<?php
class MyClass
{
public string $public = 'Public ';
protected string $protected = 'Protected ';
private string $private = 'Private ';
public function printHello(): void
{
echo "$this->public $this->protected $this->private\n";
}
}
$obj = new MyClass();
echo $obj->public; // Fonctionne
//echo $obj->protected; // Erreur fatale
//echo $obj->private; // Erreur fatale
$obj->printHello(); // Affiche Public, Protected et Private
// Classe dérivée
class MyClass2 extends MyClass
{
// On peut redéclarer la méthode publique et protégée, mais pas la privée
protected string $protected = 'Protected2 ';
public function printHello(): void
{
echo "$this->public $this->protected $this->private\n";
}
}
$obj2 = new MyClass2();
echo $obj2->public; // Fonctionne
//echo $obj2->private; // Indéfini (propriété privée)
//echo $obj2->protected; // Erreur fatale
$obj2->printHello(); // Affiche Public, Protected2
?>
Public Public Protected Private Public Public Protected2
<?php
class Rectangle {
protected float $longueur;
protected float $largeur;
public function __construct(float $longueur, float $largeur) {
$this->longueur = $longueur;
$this->largeur = $largeur;
}
// Accesseurs
// Getters
public function getLongueur(): float {
return $this->longueur;
}
public function getLargeur(): float {
return $this->largeur;
}
// Setters
public function setLongueur(float $longueur): void {
$this->longueur = $longueur;
}
public function setLargeur(float $largeur): void {
$this->largeur = $largeur;
}
}
class Carre extends Rectangle {
public function __construct(float $cote) {
parent::__construct($cote, $cote);
}
public function setLongueur(float $cote): void {
parent::setLongueur($cote);
parent::setLargeur($cote);
}
public function setLargeur(float $cote): void {
parent::setLongueur($cote);
parent::setLargeur($cote);
}
}
echo "Définition d'un rectangle 5x2 :\n";
$R = new Rectangle(5, 2);
// echo $R->longueur; produit Fatal error
// Utiliser les accesseurs :
echo "Longueur : " . $R->getLongueur() . "\n";
echo "Largeur : " . $R->getLargeur() . "\n";
echo "Définition d'un carré de côté 4\n";
$C = new Carre(4);
echo "Côté : " . $C->getLargeur() . "\n";
echo "Changement du côté : \n";
$C->setLargeur(8);
echo "Côté : " . $C->getLargeur() . "\n";
?>
Définition d'un rectangle 5x2 : Longueur : 5 Largeur : 2 Définition d'un carré de côté 4 Côté : 4 Changement du côté : Côté : 8
Au passage, noter le mot-clef parent
pour appeler une méthode (ou le constructeur) de la superclasse
throw new Exception("Houston, we have a problem");
getMessage()
: message d'erreur de l'exceptiongetCode()
: code d'erreur de l'exceptiongetFile()
: fichier dans lequel l'exception a été renvoyéegetLine()
: n° de ligne où l'exception a été renvoyéegetTrace()
: tableau contenant la tracegetTraceAsString()
: chaîne de caractères avec la tracetry
try
doit être suivi d'un bloc catch
try
<?php
try {
// Code à exécuter
division(1, 0);
} catch (Exception $e) {
echo "Message : " . $e->getMessage() . "<br/>\n";
echo "Code : " . $e->getCode() . "<br/>\n";
}
function division(float $a, float $b): float {
if ($b == 0) {
throw new Exception("Erreur division par zéro", -1);
} else {
return $a / $b;
}
}
?>
Message : Erreur division par zéro
Code : -1
Exception
catch
catch
est passée au bloc suivant
<?php
class MonException extends Exception{
// Ici on peut rajouter de nouvelles méthodes
}
?>
throw new MonException();
try {
// Un code qui lève une erreur
} catch (MonException $e) {
// Une exception spécifique à MonException
} catch (PDOException $e) {
// Une exception spécifique à PDOException (liée à la base de données)
} catch (Exception $e) {
// Une exception plus générale
}
<?php
abstract class Forme {
abstract public function aire(): float;
}
class Point extends Forme {
protected float $x;
protected float $y;
public function __construct(float $x, float $y) {
$this->x = $x;
$this->y = $y;
}
public function getX(): float {
return $this->x;
}
public function getY(): float {
return $this->y;
}
public function aire(): float {
return 0; // Un point n'a pas d'aire
}
}
class Ligne extends Forme {
protected Point $point1;
protected Point $point2;
public function __construct(Point $point1, Point $point2) {
$this->point1 = $point1;
$this->point2 = $point2;
}
public function aire(): float {
return 0; // Une ligne n'a pas d'aire
}
}
class Triangle extends Forme {
protected Point $sommet1;
protected Point $sommet2;
protected Point $sommet3;
public function __construct(Point $sommet1, Point $sommet2, Point $sommet3) {
$this->sommet1 = $sommet1;
$this->sommet2 = $sommet2;
$this->sommet3 = $sommet3;
}
public function aire(): float {
// Calcul de l'aire d'un triangle (exemple simple, non réaliste)
$x1 = $this->sommet1->getX();
$y1 = $this->sommet1->getY();
$x2 = $this->sommet2->getX();
$y2 = $this->sommet2->getY();
$x3 = $this->sommet3->getX();
$y3 = $this->sommet3->getY();
// Formule de l'aire d'un triangle
return abs(($x1 * ($y2 - $y3) + $x2 * ($y3 - $y1) + $x3 * ($y1 - $y2)) / 2);
}
}
class Rectangle extends Forme {
protected Point $coinSuperieurGauche;
protected Point $coinInferieurDroit;
public function __construct(Point $coinSuperieurGauche, Point $coinInferieurDroit) {
$this->coinSuperieurGauche = $coinSuperieurGauche;
$this->coinInferieurDroit = $coinInferieurDroit;
}
public function aire(): float {
// Calcul de l'aire d'un rectangle (exemple simple, non réaliste)
$x1 = $this->coinSuperieurGauche->getX();
$y1 = $this->coinSuperieurGauche->getY();
$x2 = $this->coinInferieurDroit->getX();
$y2 = $this->coinInferieurDroit->getY();
return abs(($x2 - $x1) * ($y1 - $y2));
}
}
class Carre extends Rectangle {
public function __construct(Point $coinSuperieurGauche, float $cote) {
$coinInferieurDroit = new Point($coinSuperieurGauche->getX() + $cote, $coinSuperieurGauche->getY() - $cote);
parent::__construct($coinSuperieurGauche, $coinInferieurDroit);
}
}
class Cercle extends Forme {
protected Point $centre;
protected float $rayon;
public function __construct(Point $centre, float $rayon) {
$this->centre = $centre;
$this->rayon = $rayon;
}
public function aire(): float {
// Calcul de l'aire d'un cercle (exemple simple, non réaliste)
return M_PI * $this->rayon * $this->rayon;
}
}
// Fonction générique utilisant le polymorphisme
function afficherAire(Forme $forme): void {
echo "Aire : " . $forme->aire() . "\n";
}
// Utilisation du polymorphisme
$sommet1 = new Point(1, 2);
$sommet2 = new Point(3, 4);
$sommet3 = new Point(5, 6);
$ligne = new Ligne($sommet1, $sommet2);
$triangle = new Triangle($sommet1, $sommet2, $sommet3);
$rectangle = new Rectangle($sommet1, $sommet3);
// Création d'un nouvel objet Point pour représenter le coin supérieur gauche du carré
$coinSuperieurGaucheCarre = new Point(7, 8);
$carre = new Carre($coinSuperieurGaucheCarre, 10);
$cercle = new Cercle($sommet1, 5);
afficherAire($sommet1);
afficherAire($ligne);
afficherAire($triangle);
afficherAire($rectangle);
afficherAire($carre);
afficherAire($cercle);
?>