mirror of
https://github.com/php/doc-fr.git
synced 2026-03-23 22:52:18 +01:00
855 lines
22 KiB
XML
855 lines
22 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: fc068b4857342eb409efeafe6723058f39ab1045 Maintainer: yannick Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<sect1 xml:id="language.oop5.basic" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Syntaxe de base</title>
|
|
<sect2 xml:id="language.oop5.basic.class">
|
|
<title>class</title>
|
|
<para>
|
|
Une définition de classe basique commence par le mot-clé
|
|
<literal>class</literal>, 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.
|
|
</para>
|
|
<para>
|
|
Le nom de la classe peut être quelconque à condition que ce ne soit pas un
|
|
<link linkend="reserved">mot réservé</link> en PHP.
|
|
À partir de PHP 8.4.0, l'utilisation d'un seul underscore <literal>_</literal> comme nom de classe est obsolète.
|
|
Un nom de classe valide commence par une lettre ou un underscore,
|
|
suivi de n'importe quel nombre de lettres, chiffres ou underscores.
|
|
En tant qu'expression régulière, cela serait exprimé ainsi :
|
|
<code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>.
|
|
</para>
|
|
<para>
|
|
Une classe peut contenir ses propres <link linkend="language.oop5.constants">constantes</link>,
|
|
<link linkend="language.oop5.properties">variables</link>
|
|
(appelées "propriétés" ou "attributs"), et fonctions (appelées "méthodes").
|
|
</para>
|
|
<example>
|
|
<title>Définition typique d'une classe</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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;
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
La pseudo-variable <varname>$this</varname> est disponible
|
|
lorsqu'une méthode est appelée depuis un contexte objet.
|
|
<varname>$this</varname> est la valeur de l'objet appelant.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
Appeler une méthode non-statique statiquement lance une
|
|
<classname>Error</classname>.
|
|
Avant PHP 8.0.0, ceci générait une notice d'obsolescence,
|
|
et <varname>$this</varname> était indéfini.
|
|
</para>
|
|
<example xml:id="language.oop5.basic.class.this">
|
|
<title>Quelques exemples de la pseudo-variable <varname>$this</varname></title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class A
|
|
{
|
|
function foo()
|
|
{
|
|
if (isset($this)) {
|
|
echo '$this is defined (';
|
|
echo get_class($this);
|
|
echo ")\n";
|
|
} else {
|
|
echo "\$this is not defined.\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
class B
|
|
{
|
|
function bar()
|
|
{
|
|
A::foo();
|
|
}
|
|
}
|
|
|
|
$a = new A();
|
|
$a->foo();
|
|
|
|
A::foo();
|
|
|
|
$b = new B();
|
|
$b->bar();
|
|
|
|
B::bar();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.7;
|
|
<screen>
|
|
<![CDATA[
|
|
$this is defined (A)
|
|
|
|
Deprecated: Non-static method A::foo() should not be called statically in %s on line 27
|
|
$this is not defined.
|
|
|
|
Deprecated: Non-static method A::foo() should not be called statically in %s on line 20
|
|
$this is not defined.
|
|
|
|
Deprecated: Non-static method B::bar() should not be called statically in %s on line 32
|
|
|
|
Deprecated: Non-static method A::foo() should not be called statically in %s on line 20
|
|
$this is not defined.
|
|
]]>
|
|
</screen>
|
|
&example.outputs.8;
|
|
<screen>
|
|
<![CDATA[
|
|
$this is defined (A)
|
|
|
|
Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27
|
|
Stack trace:
|
|
#0 {main}
|
|
thrown in %s on line 27
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</warning>
|
|
|
|
<sect3 xml:id="language.oop5.basic.class.readonly">
|
|
<title>Classes en lecture seule (readonly)</title>
|
|
<para>
|
|
À partir de PHP 8.2.0, une classe peut être marquée
|
|
avec le modificateur <modifier>readonly</modifier>.
|
|
Marquer une classe comme <modifier>readonly</modifier> ajoutera
|
|
le <link linkend="language.oop5.properties.readonly-properties">modificateur <modifier>readonly</modifier></link>
|
|
à chaque propriété déclarée, et empêchera la création
|
|
de <link linkend="language.oop5.properties.dynamic-properties">propriétés dynamiques</link>.
|
|
En outre, il est impossible d'ajouter leur prise en charge en utilisant
|
|
l'attribut <classname>AllowDynamicProperties</classname>.
|
|
Toute tentative de le faire déclenchera une erreur de compilation.
|
|
</para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
#[\AllowDynamicProperties]
|
|
readonly class Foo {
|
|
}
|
|
|
|
// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
|
|
<para>
|
|
Comme ni les propriétés non typées ni les propriétés statiques
|
|
ne peuvent être marquées avec le modificateur <literal>readonly</literal>,
|
|
les classes readonly ne peuvent pas non plus les déclarer :
|
|
</para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
readonly class Foo
|
|
{
|
|
public $bar;
|
|
}
|
|
|
|
// Fatal error: Readonly property Foo::$bar must have type
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
readonly class Foo
|
|
{
|
|
public static int $bar;
|
|
}
|
|
|
|
// Fatal error: Readonly class Foo cannot declare static properties
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
<para>
|
|
Une classe <modifier>readonly</modifier> peut être
|
|
<link linkend="language.oop5.basic.extends">étendue</link> si,
|
|
et seulement si, la classe enfant est également
|
|
une classe <modifier>readonly</modifier>.
|
|
</para>
|
|
</sect3>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.oop5.basic.new">
|
|
<title>Le mot-clé <literal>new</literal></title>
|
|
<para>
|
|
Pour créer une instance d'une classe, le mot-clé <literal>new</literal> doit être
|
|
utilisé. Un objet sera alors systématiquement créé, à moins qu'il ait un
|
|
<link linkend="language.oop5.decon">constructeur</link>
|
|
défini qui lance une <link linkend="language.exceptions">exception</link>
|
|
en cas d'erreur. Les classes devraient être définies avant l'instanciation (dans
|
|
certains cas, c'est impératif).
|
|
</para>
|
|
<para>
|
|
Si une variable <type>string</type> contenant un nom de classe est utilisée avec
|
|
<literal>new</literal>, 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é.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</note>
|
|
|
|
<example>
|
|
<title>Création d'une instance</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class SimpleClass {
|
|
}
|
|
|
|
$instance = new SimpleClass();
|
|
var_dump($instance);
|
|
|
|
// Ceci peut également être réalisé avec une variable :
|
|
$className = 'SimpleClass';
|
|
$instance = new $className(); // new SimpleClass()
|
|
var_dump($instance);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<para>
|
|
À partir de PHP 8.0.0, l'utilisation de <literal>new</literal> avec des
|
|
expressions arbitraires est supportée.
|
|
Ceci permet des instantiations plus complexes si l'expression produit une
|
|
<type>string</type>. L'expression doit être entourée de parenthèses.
|
|
</para>
|
|
<example>
|
|
<title>Créer une instance en utilisant une expression arbitraire</title>
|
|
<para>
|
|
Dans l'exemple donné, nous montrons plusieurs exemples d'expressions
|
|
arbitraires valides qui produisent un nom de classe.
|
|
Ceci montre un appel de fonction, une concaténation de chaînes
|
|
et la constante <constant>::class</constant>.
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class ClassA extends \stdClass {}
|
|
class ClassB extends \stdClass {}
|
|
class ClassC extends ClassB {}
|
|
class ClassD extends ClassA {}
|
|
|
|
function getSomeClass(): string
|
|
{
|
|
return 'ClassA';
|
|
}
|
|
|
|
var_dump(new (getSomeClass()));
|
|
var_dump(new ('Class' . 'B'));
|
|
var_dump(new ('Class' . 'C'));
|
|
var_dump(new (ClassD::class));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.8;
|
|
<screen>
|
|
<![CDATA[
|
|
object(ClassA)#1 (0) {
|
|
}
|
|
object(ClassB)#1 (0) {
|
|
}
|
|
object(ClassC)#1 (0) {
|
|
}
|
|
object(ClassD)#1 (0) {
|
|
}
|
|
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<para>
|
|
Dans le contexte de la classe, il est possible de créer un nouvel objet
|
|
avec <literal>new self</literal> et <literal>new parent</literal>.
|
|
</para>
|
|
<para>
|
|
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
|
|
<link linkend="language.oop5.cloning">clonage</link>.
|
|
</para>
|
|
<example>
|
|
<title>Assignation d'un objet</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class SimpleClass {
|
|
public string $var;
|
|
}
|
|
|
|
$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);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
NULL
|
|
NULL
|
|
object(SimpleClass)#1 (1) {
|
|
["var"]=>
|
|
string(30) "$assigned aura cette valeur"
|
|
}
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<para>
|
|
Il est possible de créer une instance d'un objet de quelques manières différentes :
|
|
</para>
|
|
<example>
|
|
<title>Créer de nouveaux objets</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class Test
|
|
{
|
|
public static function getNew()
|
|
{
|
|
return new static();
|
|
}
|
|
}
|
|
|
|
class Child extends Test {}
|
|
|
|
$obj1 = new Test(); // Par le nom de la classe
|
|
$obj2 = new $obj1; // À travers la variable contenant un objet
|
|
var_dump($obj1 !== $obj2);
|
|
|
|
$obj3 = Test::getNew(); // Par la méthode de classe
|
|
var_dump($obj3 instanceof Test);
|
|
|
|
$obj4 = Child::getNew(); // À travers une méthode de classe enfant
|
|
var_dump($obj4 instanceof Child);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<para>
|
|
Il est possible d'accéder à un membre d'un objet nouvellement
|
|
créé en une seule expression :
|
|
</para>
|
|
<example>
|
|
<title>Accéder un membre d'un objet nouvellement créé</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo (new DateTime())->format('Y'), PHP_EOL;
|
|
|
|
// les parenthèses autour sont optionnelles à partir de PHP 8.4.0
|
|
echo new DateTime()->format('Y'), PHP_EOL;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.similar;
|
|
<screen>
|
|
<![CDATA[
|
|
2025
|
|
2025
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<note>
|
|
<simpara>
|
|
Avant PHP 7.1, les arguments ne sont pas évalués s'il n'y a pas de
|
|
fonction constructeur définie.
|
|
</simpara>
|
|
</note>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.oop5.basic.properties-methods">
|
|
<title>Propriétés et méthodes</title>
|
|
<para>
|
|
Les propriétés et méthodes de classe vivent dans des "espaces de noms" séparés,
|
|
donc il est possible d'avoir une propriété et une méthode avec le même nom.
|
|
Faire référence à la fois à 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.
|
|
</para>
|
|
<example>
|
|
<title>Accès de propriété contre appel de méthode</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Foo
|
|
{
|
|
public $bar = 'property';
|
|
|
|
public function bar() {
|
|
return 'method';
|
|
}
|
|
}
|
|
|
|
$obj = new Foo();
|
|
echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
property
|
|
method
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<para>
|
|
Ceci signifie qu'appeler une <link linkend="functions.anonymous">fonction
|
|
anonyme</link> qui a été assignée à une propriété n'est pas possible directement.
|
|
Au lieu de cela, la propriété doit d'abord être affectée à une variable.
|
|
Il est possible d'appeler ce genre de propriété directement
|
|
en la mettant entre parenthèses.
|
|
</para>
|
|
<example>
|
|
<title>Appeler une fonction anonyme enregistrée dans une propriété</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Foo
|
|
{
|
|
public $bar;
|
|
|
|
public function __construct() {
|
|
$this->bar = function() {
|
|
return 42;
|
|
};
|
|
}
|
|
}
|
|
|
|
$obj = new Foo();
|
|
|
|
echo ($obj->bar)(), PHP_EOL;
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
42
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.oop5.basic.extends">
|
|
<title>Le mot-clé <literal>extends</literal></title>
|
|
<para>
|
|
Une classe peut hériter des constantes, méthodes et des propriétés d'une autre classe en
|
|
utilisant le mot-clé <literal>extends</literal> 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.
|
|
</para>
|
|
<para>
|
|
Les constantes, méthodes et propriétés héritées peuvent être redéfinies 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 ou constante comme <link linkend="language.oop5.final">final</link>,
|
|
alors celles-ci ne peuvent pas être redéfinies. Il est possible d'accéder aux
|
|
méthodes ou propriétés statiques redéfinies en y faisant référence avec l'opérateur
|
|
<link linkend="language.oop5.paamayim-nekudotayim">parent::</link>.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
À partir de PHP 8.1.0, les constantes peuvent être déclarées comme finales.
|
|
</simpara>
|
|
</note>
|
|
<example>
|
|
<title>Héritage simple d'une classe</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class SimpleClass
|
|
{
|
|
function displayVar()
|
|
{
|
|
echo "Classe parente\n";
|
|
}
|
|
}
|
|
|
|
class ExtendClass extends SimpleClass
|
|
{
|
|
// Redéfinition de la méthode parente
|
|
function displayVar()
|
|
{
|
|
echo "Classe étendue\n";
|
|
parent::displayVar();
|
|
}
|
|
}
|
|
|
|
$extended = new ExtendClass();
|
|
$extended->displayVar();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Classe étendue
|
|
Classe parente
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<sect3 xml:id="language.oop.lsp">
|
|
<title>Règles de compatibilité de signature</title>
|
|
<para>
|
|
Lors de la surcharge d'une méthode, sa signature doit être compatible avec
|
|
la méthode parente. Sinon, une erreur fatale est émise, ou, antérieur à
|
|
PHP 8.0.0, une erreur de niveau <constant>E_WARNING</constant> est générée.
|
|
Une signature est compatible si elle respecte les règles de
|
|
<link linkend="language.oop5.variance">variance</link>, rend un paramètre
|
|
obligatoire optionnel, et seulement si tous les nouveaux paramètres sont
|
|
optionnels et assouplissent les règles de visibilité.
|
|
Ceci est connu sous le Principe de Substitution de Liskov
|
|
(Liskov Substitution Principle), ou simplement LSP.
|
|
Le <link linkend="language.oop5.decon.constructor">constructeur</link>,
|
|
et les méthodes <literal>private</literal> sont exclus de ces règles de
|
|
compatibilité des signatures, et par conséquent n'émettront pas d'erreur
|
|
fatale en cas de signature incompatible.
|
|
</para>
|
|
<example>
|
|
<title>Méthodes enfant compatibles</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Base
|
|
{
|
|
public function foo(int $a) {
|
|
echo "Valid\n";
|
|
}
|
|
}
|
|
class Extend1 extends Base
|
|
{
|
|
function foo(int $a = 5)
|
|
{
|
|
parent::foo($a);
|
|
}
|
|
}
|
|
class Extend2 extends Base
|
|
{
|
|
function foo(int $a, $b = 5)
|
|
{
|
|
parent::foo($a);
|
|
}
|
|
}
|
|
$extended1 = new Extend1();
|
|
$extended1->foo();
|
|
$extended2 = new Extend2();
|
|
$extended2->foo(1);
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Valid
|
|
Valid
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<para>
|
|
Les exemples suivants démontrent qu'une méthode enfant qui supprime un paramètre,
|
|
ou rend un paramètre optionnel obligatoire, n'est pas compatible avec la méthode parente.
|
|
</para>
|
|
<example>
|
|
<title>Erreur fatale quand une méthode enfant supprime un paramètre</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Base
|
|
{
|
|
public function foo(int $a = 5) {
|
|
echo "Valid\n";
|
|
}
|
|
}
|
|
class Extend extends Base
|
|
{
|
|
function foo()
|
|
{
|
|
parent::foo(1);
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.8.similar;
|
|
<screen>
|
|
<![CDATA[
|
|
Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Erreur fatale quand une méthode enfant rend un paramètre optionnel obligatoire</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Base
|
|
{
|
|
public function foo(int $a = 5) {
|
|
echo "Valid\n";
|
|
}
|
|
}
|
|
class Extend extends Base
|
|
{
|
|
function foo(int $a)
|
|
{
|
|
parent::foo($a);
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.8.similar;
|
|
<screen>
|
|
<![CDATA[
|
|
Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<warning>
|
|
<para>
|
|
Renommer un paramètre d'une méthode dans une classe enfant n'est pas
|
|
une incompatibilité de signature. Cependant, ceci est découragé car ceci
|
|
va résulter en une <classname>Error</classname> lors du runtime si les
|
|
<link linkend="functions.named-arguments">arguments nommés</link>
|
|
sont utilisés.
|
|
</para>
|
|
<example>
|
|
<title>Erreur lors de l'utilisation des arguments nommés et que les paramètres ont été renommés dans une classe enfant</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class A {
|
|
public function test($foo, $bar) {}
|
|
}
|
|
class B extends A {
|
|
public function test($a, $b) {}
|
|
}
|
|
$obj = new B;
|
|
// Pass parameters according to A::test() contract
|
|
$obj->test(foo: "foo", bar: "bar"); // ERROR!
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.similar;
|
|
<screen>
|
|
<![CDATA[
|
|
Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14
|
|
Stack trace:
|
|
#0 {main}
|
|
thrown in /in/XaaeN on line 14
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</warning>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.oop5.basic.class.class">
|
|
<title>::class</title>
|
|
|
|
<para>
|
|
Le mot clé <literal>class</literal> est également utilisé
|
|
pour la résolution des noms de classes.
|
|
Il est possible d'obtenir le nom complètement qualifié d'une classe
|
|
<literal>ClassName</literal> en utilisant <literal>ClassName::class</literal>.
|
|
C'est particulièrement utile avec les classes utilisant des
|
|
<link linkend="language.namespaces">espaces de noms</link>.
|
|
</para>
|
|
<para>
|
|
<example xml:id="language.oop5.basic.class.class.name">
|
|
<title>Résolution de nom de classe</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace NS {
|
|
class ClassName {
|
|
}
|
|
|
|
echo ClassName::class;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
NS\ClassName
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
La résolution du nom de classe en utilisant <literal>::class</literal> est une
|
|
transformation lors de la compilation. C'est-à-dire à l'instant où la chaîne du
|
|
nom de classe est créée aucun autochargement n'a encore eu lieu. Par conséquent,
|
|
les noms de classes sont étendus même si la classe n'existe pas. Aucune erreur
|
|
n'est émise dans ce cas-là.
|
|
</para>
|
|
<example xml:id="language.oop5.basic.class.class.fail">
|
|
<title>Résolution de nom de classe manquante</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
print Does\Not\Exist::class;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Does\Not\Exist
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</note>
|
|
<para>
|
|
À partir de PHP 8.0.0, <literal>::class</literal> peut être utilisé
|
|
sur les objets. Cette résolution se produit lors de l'exécution, et non lors de
|
|
la compilation. Ses effets sont les mêmes que d'appeler
|
|
<function>get_class</function> sur l'objet.
|
|
</para>
|
|
<example xml:id="language.oop5.basic.class.class.object">
|
|
<title>Résolution du nom d'un objet</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
namespace NS {
|
|
class ClassName {
|
|
}
|
|
|
|
$c = new ClassName();
|
|
print $c::class;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
NS\ClassName
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</sect2>
|
|
<sect2 xml:id="language.oop5.basic.nullsafe">
|
|
<title>Méthodes et propriétés nullsafe</title>
|
|
<para>
|
|
À partir de PHP 8.0.0, les méthodes et propriétés peuvent aussi être accédées
|
|
avec l'opérateur "nullsafe" : <literal>?-></literal>. L'opérateur nullsafe
|
|
fonctionne à l'identique que l'accès de propriétés ou méthodes comme ci-dessus,
|
|
à l'exception que si l'objet qui est déréférencé est &null; alors &null; sera
|
|
retourné au lieu de lancer une exception. Si le déréférencement fait partie d'une
|
|
chaîne, le reste de la chaîne est ignoré.
|
|
</para>
|
|
<para>
|
|
L'effet est similaire à entourer chaque accès par une vérification avec
|
|
<function>is_null</function> d'abord, mais plus compact.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Opérateur nullsafe</title>
|
|
<programlisting role="php" annotations="non-interactive">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// À partir de PHP 8.0.0, cette ligne:
|
|
$result = $repository?->getUser(5)?->name;
|
|
|
|
// Est équivalente au bloc de code suivant :
|
|
if (is_null($repository)) {
|
|
$result = null;
|
|
} else {
|
|
$user = $repository->getUser(5);
|
|
if (is_null($user)) {
|
|
$result = null;
|
|
} else {
|
|
$result = $user->name;
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
L'opérateur nullsafe est mieux utilisé quand null est considéré une valeur valide
|
|
et potentiellement attendu pour une propriété ou valeur de retour d'une méthode.
|
|
Pour indiquer une erreur, lancer une exception est préférable.
|
|
</para>
|
|
</note>
|
|
</sect2>
|
|
</sect1>
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|