Syntaxe de base

class

Une définition de classe basique commence par le mot-clé class, suivi du nom de la classe. Suit une paire d'accolades contenant la définition des propriétés et des méthodes appartenant à la classe.

Le nom de la classe peut être quelconque à condition que ce ne soit pas un mot réservé en PHP. Un nom de classe valide commence par une lettre ou un underscore, suivi de n'importe quel nombre de chiffres, ou de lettres, ou d'underscores. Si on devait l'exprimer sous forme d'une expression rationnelle, il s'agirait de ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$.

Une classe peut contenir ses propres constantes, variables (appelées "propriétés" ou "attributs"), et fonctions (appelées "méthodes").

Exemple #1 Définition typique d'une classe

<?php
class SimpleClass
{
    
// déclaration d'une propriété
    
public $var 'une valeur par défaut';

    
// déclaration des méthodes
    
public function displayVar() {
        echo 
$this->var;
    }
}
?>

La pseudo-variable $this est disponible lorsqu'une méthode est appelée depuis un contexte objet. $this est une référence à l'objet appelant (habituellement, l'objet auquel la méthode appartient, mais ce peut être un autre objet si la méthode est appelée de manière statique depuis le contexte d'un autre objet). À partir de PHP 7.0.0 appeller une méthode non statique statiquement depuis un context incompatible résulte en $this étant indéfini à l'intérieur de la méthode. Appeller une méthode non statique statiquement depuis un context incompatible a été rendu obsolète à partir de PHP 5.6.0. À partir de PHP 7.0.0 appelller une méthode non statique statiquement a été rendu obsolète généralement (même si appellé depuis un contexte compatible). Antérieur à PHP 5.6.0 ce genre d'appel déclanchaient déjà une notice stricte.

Exemple #2 Quelques exemples de la pseudo-variable $this

Nous assumerons que error_reporting est désactivé dans cet exemple ; sinon le code suivant déclancherait des notices obsolète et stricte, respectivement en fonction de la version de PHP.

<?php
class A
{
  function 
toto()
  {
    if (isset(
$this)) {
      echo 
'$this est définie (';
      echo 
get_class($this);
      echo 
")\n";
    } else {
      echo 
"\$this n'est pas définie.\n";
    }
  }
}

class 
B
{
  function 
titi()
  {
    
A::toto();
  }
}

$a = new A();
$a->toto();

A::toto();
$b = new B();
$b->titi();

B::titi();
?>

Résultat de l'exemple ci-dessus en PHP 5 :

$this est définie (A)
$this n'est pas définie.
$this est définie (B)
$this n'est pas définie.

Résultat de l'exemple ci-dessus en PHP 7 :

$this est définie (A)
$this n'est pas définie.
$this n'est pas définie.
$this n'est pas définie.

Le mot-clé new

Pour créer une instance d'une classe, le mot-clé new doit être utilisé. Un objet sera alors systématiquement créé, à moins qu'il ait un constructeur défini qui lance une exception en cas d'erreur. Les classes devraient être définies avant l'instanciation (dans certains cas, c'est impératif).

Si une chaîne de caractères contenant un nom de classe est utilisée avec new, une nouvelle instance de cette classe sera créée. Si la classe est dans un espace de noms, son nom pleinement qualifié doit être utilisé.

Note:

S'il n'y a pas d'arguments à passer au constructeur de la classe, les parenthèses après le nom de la classe peuvent être omises.

Exemple #3 Création d'une instance

<?php
$instance 
= new SimpleClass();

// Ceci peut également être réalisé avec une variable :
$className 'SimpleClass';
$instance = new $className(); // new SimpleClass()
?>

Dans le contexte de la classe, il est possible de créer un nouvel objet avec new self et new parent.

Lors de l'assignation d'une instance déjà créée d'une classe à une variable, la nouvelle variable accédera à la même instance que l'objet qui a été assigné. Ce comportement est le même lors du passage d'une instance à une fonction. Une copie d'un objet déjà créé peut être effectuée par clonage.

Exemple #4 Assignation d'un objet

<?php

$instance 
= new SimpleClass();

$assigned   =  $instance;
$reference  =& $instance;

$instance->var '$assigned aura cette valeur';

$instance null// $instance et $reference deviennent null

var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>

L'exemple ci-dessus va afficher :

NULL
NULL
object(SimpleClass)#1 (1) {
   ["var"]=>
     string(30) "$assigned aura cette valeur"
}

PHP 5.3.0 a introduit de nouvelles manières de créer des objets :

Exemple #5 Créer de nouveaux objets

<?php
class Test
{
    static public function 
getNew()
    {
        return new static;
    }
}

class 
Child extends Test
{}

$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);

$obj3 Test::getNew();
var_dump($obj3 instanceof Test);

$obj4 Child::getNew();
var_dump($obj4 instanceof Child);
?>

L'exemple ci-dessus va afficher :

bool(true)
bool(true)
bool(true)

PHP 5.4.0 introduit la possibilité d'accéder un membre d'un objet nouvellement créé en une seule expression :

Exemple #6 Accéder un membre d'un objet nouvellement créé

<?php
echo (new DateTime())->format('Y');
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

2016

Propriétés et méthodes

Les propriétes et méthodes de classe vivent dans des "espaces de noms" séparé, donc il est possible d'avoir une propriété et une méthode avec le même nom. Faire référence à la fois a une propriété ainsi qu'une méthode ont la même notation, et le fait qu'une propriété sera accédée ou qu'une méthode sera appelée, dépend seulement du contexte, c'est à dire si l'utilisation est un accès variable ou un appel de fonction.

Exemple #7 Accès de propriété contre appel de méthode

<?php
class Foo
{
    public 
$bar 'property';
    
    public function 
bar() {
        return 
'method';
    }
}

$obj = new Foo();
echo 
$obj->barPHP_EOL$obj->bar(), PHP_EOL;

L'exemple ci-dessus va afficher :

property
method

Ceci signifie qu'appeller une fonction anonyme qui a été assigné à une propriété n'est pas possible directement. Au lieu de cela, la propriété doit d'abord être affectée à une variable. À partir de PHP 7.0.0 il est possible d'appeler ce genre de propriété directement en la mettant entre parenthèses.

Exemple #8 Appeller une fonction anonyme enregistré dans une propriété

<?php
class Foo
{
    public 
$bar;
    
    public function 
__construct() {
        
$this->bar = function() {
            return 
42;
        };
    }
}

$obj = new Foo();

// à partir de PHP 5.3.0:
$func $obj->bar;
echo 
$func(), PHP_EOL;

// alternativement, à partir de PHP 7.0.0:
echo ($obj->bar)(), PHP_EOL;

L'exemple ci-dessus va afficher :

42

Le mot-clé extends

Une classe peut hériter des méthodes et des membres d'une autre classe en utilisant le mot-clé extends dans la déclaration. Il n'est pas possible d'étendre plusieurs classes : une classe peut uniquement hériter d'une seule classe de base.

Les méthodes et membres hérités peuvent être surchargés en les redéclarant avec le même nom que dans la classe parente. Cependant, si la classe parente a défini une méthode comme final, alors celle-ci ne sera pas surchargeable. Il est possible d'accéder aux méthodes ou une propriétés statiques surchargées en y faisant référence avec l'opérateur parent::.

Lors de la surcharge de méthodes, la signature devrait rester la même ; sinon, PHP génèrera une erreur de niveau E_STRICT. Ceci ne s'applique pas au constructeur, qui accepte la surcharge avec des paramètres différents.

Exemple #9 Héritage simple d'une classe

<?php
class ExtendClass extends SimpleClass
{
  
// Redéfinition de la méthode parente
  
function displayVar()
  {
    echo 
"Classe étendue\n";
    
parent::displayVar();
  }
}

$extended = new ExtendClass();
$extended->displayVar();
?>

L'exemple ci-dessus va afficher :

Classe étendue
une valeur par défaut

::class

Depuis PHP 5.5, le mot clé class est également utilisé pour la résolution des noms de classes. Vous pouvez récupérer une chaîne contenant le nom qualifié complet de la classe ClassName en utilisant ClassName::class. C'est particulièrement pratique avec les classes utilisant des espaces de noms.

Exemple #10 Résolution de nom de classe

<?php
namespace NS {
    class 
ClassName {
    }
    
    echo 
ClassName::class;
}
?>

L'exemple ci-dessus va afficher :

NS\ClassName

Note:

La résolution du nom de classe en utilisant ::class est une transformation lors de la compilation. C'est à dire à l'instant où la chaine du nom de classe est crée aucun auto-chargement n'a encore eu lieu. Par conséquent, les noms de classes sont étendues même si la classe n'existe pas. Aucune erreur n'est émise dans ce cas là.