mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-25 17:32:07 +01:00
388 lines
14 KiB
XML
388 lines
14 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: 18b39f03ef77080a349f6cd2d82112dd43f904c2 Maintainer: yannick Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<sect1 xml:id="language.oop5.decon" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Constructeurs et destructeurs</title>
|
|
|
|
<sect2 xml:id="language.oop5.decon.constructor">
|
|
<title>Constructeur</title>
|
|
<methodsynopsis xml:id="object.construct">
|
|
<type>void</type><methodname>__construct</methodname>
|
|
<methodparam rep="repeat"><type>mixed</type><parameter>values</parameter><initializer>""</initializer></methodparam>
|
|
</methodsynopsis>
|
|
<para>
|
|
PHP permet aux développeurs de déclarer des constructeurs pour
|
|
les classes. Les classes qui possèdent une méthode constructeur
|
|
appellent cette méthode à chaque création d'une nouvelle instance
|
|
de l'objet, ce qui est intéressant pour toutes les initialisations
|
|
dont l'objet a besoin avant d'être utilisé.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Les constructeurs parents ne sont pas appelés implicitement
|
|
si la classe enfant définit un constructeur. Si vous
|
|
voulez utiliser un constructeur parent, il sera nécessaire de faire
|
|
appel à <literal>parent::__construct()</literal> depuis le constructeur enfant.
|
|
Si l'enfant ne définit pas un constructeur alors il peut être hérité
|
|
de la classe parent, exactement de la même façon qu'une méthode le serait
|
|
(si elle n'a pas été déclarée comme privée).
|
|
</simpara>
|
|
</note>
|
|
<example>
|
|
<title>Constructeur lors de l'héritage</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class BaseClass {
|
|
function __construct() {
|
|
print "Dans le constructeur de BaseClass\n";
|
|
}
|
|
}
|
|
|
|
class SubClass extends BaseClass {
|
|
function __construct() {
|
|
parent::__construct();
|
|
print "Dans le constructeur de SubClass\n";
|
|
}
|
|
}
|
|
|
|
class OtherSubClass extends BaseClass {
|
|
// Constructeur hérité de BaseClass
|
|
}
|
|
|
|
// Dans le constructeur de BaseClass
|
|
$obj = new BaseClass();
|
|
|
|
// Dans le constructeur de BaseClass
|
|
// Dans le constructeur de SubClass
|
|
$obj = new SubClass();
|
|
|
|
// Dans le constructeur de BaseClass
|
|
$obj = new OtherSubClass();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
À la différence des autres méthodes, <link linkend="object.construct">__construct()</link>
|
|
est exclus des <link linkend="language.oop.lsp">règles de compatibilités des signatures</link>
|
|
usuel quand elle est étendue.
|
|
</para>
|
|
<para>
|
|
Les constructeurs sont des méthodes ordinaires qui sont appelées lors de
|
|
l'instanciation de leur objet correspondant. Par conséquent, ils peuvent
|
|
définir un nombre arbitraire d'arguments, qui peuvent être requis, avoir un type,
|
|
et peuvent avoir une valeur par défaut. Les arguments d'un constructeur sont appelés
|
|
en plaçant les arguments dans des parenthèses après le nom de la classe.
|
|
</para>
|
|
<example>
|
|
<title>Utiliser les arguments d'un constructeur</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Point {
|
|
protected int $x;
|
|
protected int $y;
|
|
|
|
public function __construct(int $x, int $y = 0) {
|
|
$this->x = $x;
|
|
$this->y = $y;
|
|
}
|
|
}
|
|
|
|
// Pass both parameters.
|
|
$p1 = new Point(4, 5);
|
|
// Pass only the required parameter. $y will take its default value of 0.
|
|
$p2 = new Point(4);
|
|
// With named parameters (as of PHP 8.0):
|
|
$p3 = new Point(y: 5, x: 4);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Si une classe n'a pas de constructeur, ou que le constructeur n'a pas d'arguments requis,
|
|
les parenthèses peuvent être omises.
|
|
</para>
|
|
<sect3>
|
|
<title>Style ancien des constructeurs</title>
|
|
<para>
|
|
Antérieur à PHP 8.0.0, les classes dans le nom d'espace global interpréteront une
|
|
méthode qui à la même nom que la classe comme un constructeur de style ancien.
|
|
Cette syntaxe est obsolète, et résultera en une erreur <constant>E_DEPRECATED</constant>
|
|
mais appellera quand même cette fonction comme un constructeur.
|
|
Si <link linkend="object.construct">__construct()</link> et une méthode du même nom
|
|
sont définie, <link linkend="object.construct">__construct()</link> sera appelé.
|
|
</para>
|
|
<para>
|
|
Les classes dans les espaces de nom, ou toute classe à partir de PHP 8.0.0,
|
|
une méthode du même nom que la classe n'a jamais de signification particulière.
|
|
</para>
|
|
<para>
|
|
Toujours utiliser <link linkend="object.construct">__construct()</link> dans du nouveau code.
|
|
</para>
|
|
</sect3>
|
|
<sect3 xml:id="language.oop5.decon.constructor.promotion">
|
|
<title>Promotion du Constructeur</title>
|
|
<para>
|
|
À partir de PHP 8.0.0, les paramètres du constructeur peuvent être promus pour
|
|
correspondre à une propriété de l'objet. Il est très commun pour les paramètres
|
|
d'un constructeur d'être assigné à une propriété sans effectuer d'opérations dessus.
|
|
La promotion du constructeur fournie un raccourci pour ce cas d'utilisation.
|
|
L'exemple ci-dessus peut être réécrit de la façon suivante.
|
|
</para>
|
|
<example>
|
|
<title>Utilisant la promotion de propriété de constructeur</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Point {
|
|
public function __construct(protected int $x, protected int $y = 0) {
|
|
}
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Quand un argument de constructeur inclus un modificateur de visibilité, PHP l'interprétera
|
|
comme une propriété d'objet et un argument du constructeur, et assigne la valeur de l'argument
|
|
à la propriété. Le corps du constructeur peut être alors vide ou peut contenir d'autres
|
|
déclarations. Toutes déclarations additionnelles seront exécutées après que la valeur de
|
|
l'argument a été assignée à sa propriété correspondante.
|
|
</para>
|
|
<para>
|
|
Tous les arguments ne doivent pas être promus. Il est possible de mélanger et assortir les
|
|
arguments promus et non-promus, dans n'importe quel ordre. Les arguments promus n'ont aucun impact
|
|
sur du code appellant le constructeur.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Les propriétés d'objet ne peuvent être typés <type>callable</type> à cause des ambiguïtés du moteur
|
|
que ceci introduirait. Ainsi, les arguments promus, ne peuvent pas non plus être typés
|
|
<type>callable</type>. Cependant, toute autre
|
|
<link linkend="language.types.declarations">déclaration de type</link> est permise.
|
|
</para>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Les <link linkend="language.attributes">attributs</link> placés sur un
|
|
argument de constructeur promu seront reproduits à la fois sur la
|
|
propriété et sur l'argument.
|
|
</para>
|
|
</note>
|
|
</sect3>
|
|
|
|
<sect3 xml:id="language.oop5.decon.constructor.new">
|
|
<title>New in initializers</title>
|
|
<para>
|
|
À partir de PHP 8.1.0, les objets peuvent être utilisé comme valeur par défaut pour les paramètres,
|
|
variables statiques, constantes globales et les arguments d'attributs.
|
|
Les objets peuvent être désormais passé à <function>define</function>.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
L'utilisation d'un nom de classe dynamique ou non-string ou une class anonyme n'est pas permit.
|
|
L'utilisation de déballage d'argument n'est pas permit.
|
|
L'utilisation d'expressions pas supportées en tant qu'argument n'est pas permit.
|
|
</para>
|
|
</note>
|
|
<example>
|
|
<title>Utilisation de new dans des initialiseurs</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// All allowed:
|
|
static $x = new Foo;
|
|
|
|
const C = new Foo;
|
|
|
|
function test($param = new Foo) {}
|
|
|
|
#[AnAttribute(new Foo)]
|
|
class Test {
|
|
public function __construct(
|
|
public $prop = new Foo,
|
|
) {}
|
|
}
|
|
|
|
// All not allowed (compile-time error):
|
|
function test(
|
|
$a = new (CLASS_NAME_CONSTANT)(), // dynamic class name
|
|
$b = new class {}, // anonymous class
|
|
$c = new A(...[]), // argument unpacking
|
|
$d = new B($abc), // unsupported constant expression
|
|
) {}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</sect3>
|
|
|
|
<sect3 xml:id="language.oop5.decon.constructor.static">
|
|
<title>Méthode de création statique</title>
|
|
<para>
|
|
PHP supporte uniquement un constructeur unique par classe. Cependant, dans
|
|
certains cas il peut être désirable de permettre à un objet d'être construit
|
|
de manière différente avec des entrées différentes.
|
|
La façon recommandée de faire ceci est en utilisant des méthodes statiques
|
|
comme une enveloppe du constructeur.
|
|
</para>
|
|
<example>
|
|
<title>Utilisant la création via une méthode statique</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Product {
|
|
|
|
private ?int $id;
|
|
private ?string $name;
|
|
|
|
private function __construct(?int $id = null, ?string $name = null) {
|
|
$this->id = $id;
|
|
$this->name = $name;
|
|
}
|
|
|
|
public static function fromBasicData(int $id, string $name): static {
|
|
$new = new static($id, $name);
|
|
return $new;
|
|
}
|
|
|
|
public static function fromJson(string $json): static {
|
|
$data = json_decode($json);
|
|
return new static($data['id'], $data['name']);
|
|
}
|
|
|
|
public static function fromXml(string $xml): static {
|
|
// Logique personnalisé.
|
|
$data = convert_xml_to_array($xml);
|
|
$new = new static();
|
|
$new->id = $data['id'];
|
|
$new->name = $data['name'];
|
|
return $new;
|
|
}
|
|
}
|
|
|
|
$p1 = Product::fromBasicData(5, 'Widget');
|
|
$p2 = Product::fromJson($some_json_string);
|
|
$p3 = Product::fromXml($some_xml_string);
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Le constructeur peut être rendu privé ou protégé pour empêcher son appel
|
|
depuis l'extérieur. Dans ce cas, seul une méthode statique sera capable
|
|
d'instancier la classe. Car elles sont dans la même définition de classe
|
|
elles ont accès aux méthodes privées, même dans une instance différente de
|
|
l'objet. Un constructeur privé est optionnel et peut ou pas faire de sens
|
|
en fonction du cas d'utilisation.
|
|
</para>
|
|
<para>
|
|
Les trois méthodes statiques publiques démontrent alors des manières différentes
|
|
d'instancier l'objet.
|
|
</para>
|
|
<simplelist>
|
|
<member><code>fromBasicData()</code> prend les paramètres exacts qui sont nécessaires,
|
|
puis créé l'objet en appellant le constructeur puis retournant le résultat.</member>
|
|
<member><code>fromJson()</code> accepte une chaîne de caractère JSON et fait
|
|
du pré-traitement sur lui même pour ce convertir dans le format désiré par
|
|
le constructeur. Elle retourne alors le nouvel objet.</member>
|
|
<member>
|
|
<code>fromXml()</code> accepte une chaîne de caractère XML, fait du pré-traitement,
|
|
puis créé un objet brut. Le constructeur est appelé, mais comme tout les
|
|
paramètres sont optionnels la méthode les ignore. Elle assigne alors les
|
|
valeurs aux propriétés de l'objet directement avant de retourner le résultat.
|
|
</member>
|
|
</simplelist>
|
|
<para>
|
|
Dans les trois cas, le mot clé <code>static</code> est traduit en le nom de
|
|
la classe dont le code y est. Dans ce cas, <code>Product</code>.
|
|
</para>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.oop5.decon.destructor">
|
|
<title>Destructeur</title>
|
|
<methodsynopsis xml:id="object.destruct">
|
|
<type>void</type><methodname>__destruct</methodname>
|
|
<void />
|
|
</methodsynopsis>
|
|
<para>
|
|
PHP possède un concept de destructeur similaire à celui d'autres langages
|
|
orientés objet, comme le <literal>C++</literal>. La méthode destructeur est appelée
|
|
dès qu'il n'y a plus de référence sur un objet donné, ou dans n'importe quel
|
|
ordre pendant la séquence d'arrêt.
|
|
</para>
|
|
<example>
|
|
<title>Exemple avec un Destructeur</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class MyDestructableClass
|
|
{
|
|
function __construct() {
|
|
print "In constructor\n";
|
|
}
|
|
|
|
function __destruct() {
|
|
print "Destroying " . __CLASS__ . "\n";
|
|
}
|
|
}
|
|
|
|
$obj = new MyDestructableClass();
|
|
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Tout comme le constructeur, le destructeur parent ne sera pas appelé
|
|
implicitement par le moteur. Pour exécuter le destructeur parent, vous
|
|
devez appeler explicitement la fonction
|
|
<literal>parent::__destruct</literal> dans le corps du destructeur.
|
|
Tout comme les constructeurs, une classe enfant peut hériter du
|
|
destructeur du parent s'il n'en implémente pas un lui même.
|
|
</para>
|
|
<para>
|
|
Le destructeur sera appelé même si l'exécution du script est stoppée
|
|
en utilisant la fonction <function>exit</function>.
|
|
Appeler la fonction <function>exit</function>
|
|
dans un destructeur empêchera l'exécution des routines d'arrêt restantes.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Les destructeurs appelés durant l'arrêt du script sont dans une situation
|
|
où les en-têtes HTTP ont déjà été envoyés.
|
|
Le dossier de travail dans la phase d'arrêt du script
|
|
peut être différent avec certaines APIs (e.g. Apache).
|
|
</para>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Tenter de lancer une exception depuis un destructeur (appelé à la fin du script)
|
|
entraine une erreur fatale.
|
|
</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
|
|
-->
|