1
0
mirror of https://github.com/php/doc-fr.git synced 2026-03-24 07:02:06 +01:00
Files
archived-doc-fr/language/types/declarations.xml

813 lines
21 KiB
XML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 0ece873cecfc4dacd14e8bebbec12c6e00de56a0 Maintainer: girgias Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.types.declarations">
<title>Déclarations de type</title>
<para>
Les déclarations de types peuvent être ajoutées aux arguments des fonctions,
valeurs de retour, et à partir de PHP 7.4.0, les propriétés de classe,
et à partir de PHP 8.3.0, les constantes de classe.
Elles assurent que la valeur est du type spécifié au moment de l'appel,
sinon une <classname>TypeError</classname> est lancée.
</para>
<para>
Chaque type pris en charge par PHP, à l'exception du type
<type>resource</type>, peut être utilisé dans une déclaration de type
par l'utilisateur.
Cette page contient un journal des modifications de la disponibilité des
différents types et de la documentation sur leur utilisation dans les
déclarations de type.
</para>
<note>
<para>
Lorsqu'une classe implémente une méthode d'interface ou réimplémente une méthode
qui a déjà été définie par une classe parente, elle doit être compatible avec la
définition susmentionnée.
Une méthode est compatible si elle suit les règles de
<link linkend="language.oop5.variance">variance</link>.
</para>
</note>
<sect2 role="changelog">
&reftitle.changelog;
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.3.0</entry>
<entry>
Ajout du support pour les constantes typées de classe, interface, trait, et enum.
</entry>
</row>
<row>
<entry>8.2.0</entry>
<entry>
Ajout du support de type <acronym>DNF</acronym> (Forme Normale Disjonctive).
</entry>
</row>
<row>
<entry>8.2.0</entry>
<entry>
Ajout du support du type <type>true</type>.
</entry>
</row>
<row>
<entry>8.2.0</entry>
<entry>
Les types <type>null</type> et <type>false</type> peuvent désormais être utilisés de manière autonome.
</entry>
</row>
<row>
<entry>8.1.0</entry>
<entry>
La prise en charge des types dintersection a été ajoutée.
</entry>
</row>
<row>
<entry>8.1.0</entry>
<entry>
Le renvoi par référence à partir dune fonction <type>void</type> est désormais déconseillé.
</entry>
</row>
<row>
<entry>8.1.0</entry>
<entry>
La prise en charge du type de retour uniquement <type>never</type> a été ajoutée.
</entry>
</row>
<row>
<entry>8.0.0</entry>
<entry>
Ajout du support de <type>mixed</type>
</entry>
</row>
<row>
<entry>8.0.0</entry>
<entry>
La prise en charge du type de retour uniquement <type>static</type> a été ajoutée.
</entry>
</row>
<row>
<entry>8.0.0</entry>
<entry>
La prise en charge des types union a été ajoutée.
</entry>
</row>
<row>
<entry>7.4.0</entry>
<entry>
Ajout du support du typage des propriétés de classe.
</entry>
</row>
<row>
<entry>7.2.0</entry>
<entry>
Ajout du support pour <type>object</type>.
</entry>
</row>
<row>
<entry>7.1.0</entry>
<entry>
Ajout du support pour <type>iterable</type>.
</entry>
</row>
<row>
<entry>7.1.0</entry>
<entry>
Ajout du support pour <type>void</type>.
</entry>
</row>
<row>
<entry>7.1.0</entry>
<entry>
La prise en charge des types nullable a été ajoutée.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect2>
<sect2 xml:id="language.types.declarations.base">
<title>Notes d'utilisation des types atomiques</title>
<simpara>
Les types atomiques ont un comportement direct avec quelques mises en garde
mineures qui sont décrites dans cette section.
</simpara>
<sect3 xml:id="language.types.declarations.base.scalar">
<title>Types scalaires</title>
<warning>
<para>
Les alias pour les types scalaires (<type>bool</type>, <type>int</type>,
<type>float</type>, <type>string</type>) ne sont pas supportés.
À la place, ils sont traités comme des noms de classe ou d'interface.
Par exemple, utiliser <literal>boolean</literal> comme une déclaration de
type nécessite que la valeur soit une &instanceof; de la classe ou
interface <literal>boolean</literal>, plutôt que de type
<type>bool</type> :
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function test(boolean $param) {}
test(true);
?>
]]>
</programlisting>
&example.outputs.8;
<screen>
<![CDATA[
Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2
Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
Stack trace:
#0 -(3): test(true)
#1 {main}
thrown in - on line 2
]]>
</screen>
</informalexample>
</warning>
</sect3>
<sect3 xml:id="language.types.declarations.void">
<title>void</title>
<note>
<para>
Le retour par référence à partir dune fonction <type>void</type> est obsolète à partir
de PHP 8.1.0, car une telle fonction est contradictoire.
Auparavant, elle émettait déjà les <constant>E_NOTICE</constant> suivants lorsquelle était appelée :
<computeroutput>Only variable references should be returned by reference</computeroutput>.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function &test(): void {}
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
</sect3>
<sect3 xml:id="language.types.declarations.base.function">
<title>Types Callable</title>
<para>
Ce type ne peut pas être utilisé comme déclaration de type de propriété de
classe.
</para>
<note>
<simpara>
Il nest pas possible de spécifier la signature de la fonction.
</simpara>
</note>
</sect3>
<sect3 xml:id="language.types.declarations.references">
<title>Déclarations de type sur les paramètres de référence</title>
<simpara>
Si un paramètre passé par référence à une déclaration de type, le type
de la variable <emphasis>nest vérifié quà</emphasis> lentrée de
la fonction, au début de lappel, mais pas lorsque la fonction est de
nouveau appelée.
Cela signifie quune fonction peut modifier le type de la variable passée
par référence.
</simpara>
<example>
<title>Paramètre typé passé par référence</title>
<programlisting role="php">
<![CDATA[
<?php
function array_baz(array &$param)
{
$param = 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
int(1)
Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
Stack trace:
#0 -(9): array_baz(1)
#1 {main}
thrown in - on line 2
]]>
</screen>
</example>
</sect3>
</sect2>
<sect2 xml:id="language.types.declarations.composite">
<title>Notes dutilisation des types composites</title>
<para>
Les déclarations de type composite sont soumises à quelques restrictions et
effectueront un contrôle de redondance au moment de la compilation pour
éviter les bogues simples.
</para>
<caution>
<simpara>
Avant PHP 8.2.0 et lintroduction des types <acronym>DNF</acronym>, il
nétait pas possible de combiner les intersections de type avec les
unions de type.
</simpara>
</caution>
<sect3 xml:id="language.types.declarations.composite.union">
<title>Types dunions</title>
<warning>
<simpara>
Il nest pas possible de combiner les deux types de singleton
<literal>false</literal> et <literal>true</literal> ensemble dans une
union de type.
Utiliser plutôt <type>bool</type>.
</simpara>
</warning>
<caution>
<simpara>
Avant PHP 8.2.0, comme <type>false</type> et <type>null</type> ne
pouvaient pas être utilisés comme types autonomes, une union de type
composée uniquement de ces types nétait pas autorisée. Cela comprend les
types suivants : <type>false</type>, <type>false|null</type>
et <type>?false</type>.
</simpara>
</caution>
<sect4 xml:id="language.types.declarations.nullable">
<title>Sucre syntaxique de type nullable</title>
<para>
Une déclaration de type de base unique peut être marquée comme valeur NULL
en faisant précéder le type dun point dinterrogation (<literal>?</literal>).
Ainsi <literal>?T</literal> et <literal>T|null</literal> sont identiques.
</para>
<note>
<simpara>
Cette syntaxe est prise en charge à partir de PHP 7.1.0, et est antérieure
à la prise en charge généralisée des unions de type.
</simpara>
</note>
<note>
<para>
Il est également possible dobtenir des arguments nullable en faisant de
<literal>null</literal> la valeur par défaut.
Ceci nest pas recommandé, car si la valeur par défaut est modifiée dans
une classe enfant, une violation de compatibilité de type sera déclenchée
car le type <type>null</type> devra être ajouté à la déclaration de type.
Ce comportement est également déprécié à partir de PHP 8.4.
</para>
<example>
<title>Ancienne façon de rendre les arguments nullables</title>
<programlisting role="php">
<![CDATA[
<?php
class C {}
function f(C $c = null) {
var_dump($c);
}
f(new C);
f(null);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(C)#1 (0) {
}
NULL
]]>
</screen>
</example>
</note>
</sect4>
</sect3>
<sect3 xml:id="language.types.declarations.composite.redundant">
<title>Types dupliqués et redondants</title>
<para>
Pour détecter des bogues simples dans les déclarations de type composite,
les types redondants qui peuvent être détectés sans effectuer de chargement
de classe entraîneront une erreur de compilation. Cela comprend :
<itemizedlist>
<listitem>
<simpara>
Chaque type résolu par nom ne peut se produire quune seule fois.
Les types tels que <literal>int|string|INT</literal> ou
<literal>Countable&amp;Traversable&amp;COUNTABLE</literal>
génèrent une erreur.
</simpara>
</listitem>
<listitem>
<simpara>
Lutilisation de <type>mixed</type> ou <type>never</type> entraîne une erreur.
</simpara>
</listitem>
<listitem>
<simpara>Pour les types dunions :</simpara>
<itemizedlist>
<listitem>
<simpara>
Si <type>bool</type> est utilisé, <type>false</type> ou
<type>true</type> ne peut pas être utilisé en plus.
</simpara>
</listitem>
<listitem>
<simpara>
Si <type>object</type> est utilisé, les types de classe ne peuvent
pas être utilisés en plus.
</simpara>
</listitem>
<listitem>
<simpara>
Si <type>iterable</type> est utilisé, <type>array</type>
et <classname>Traversable</classname> ne peuvent pas être utilisés
en plus.
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>Pour les types dintersections :</simpara>
<itemizedlist>
<listitem>
<simpara>
Lutilisation dun type qui nest pas un type de classe génère une
erreur.
</simpara>
</listitem>
<listitem>
<simpara>
Lutilisation de <type>self</type>, <type>parent</type> ou
<type>static</type> entraîne une erreur.
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>Pour les types <acronym>DNF</acronym> :</simpara>
<itemizedlist>
<listitem>
<simpara>
Si un type plus générique est utilisé, le plus restrictif est redondant.
</simpara>
</listitem>
<listitem>
<simpara>
Utilisation de deux types dintersection identiques.
</simpara>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</para>
<note>
<simpara>
Cela ne garantit pas que le type est « minimal », car cela nécessiterait
de charger tous les types de classe utilisés.
</simpara>
</note>
<para>
Par exemple, si <literal>A</literal> et <literal>B</literal> sont des
alias de classe, alors <literal>A|B</literal> reste une union de type
légale, même s'il est possible de réduire à <literal>A</literal> ou
<literal>B</literal>.
De même, si la classe <code>B extends A {}</code>, alors
<literal>A|B</literal> est également une union de type légale, même s'il
pourrait être réduit au type <literal>A</literal> uniquement.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function foo(): int|INT {} // Non autorisé
function foo(): bool|false {} // Non autorisé
function foo(): int&Traversable {} // Non autorisé
function foo(): self&Traversable {} // Non autorisé
use A as B;
function foo(): A|B {} // Non autorisé ("use" fait partie de la résolution de noms)
function foo(): A&B {} // Non autorisé ("use" fait partie de la résolution de noms)
class_alias('X', 'Y');
function foo(): X|Y {} // Autorisé (la redondance n'est connue qu'au moment de l'exécution)
function foo(): X&Y {} // Autorisé (la redondance n'est connue qu'au moment de l'exécution)
?>
]]>
</programlisting>
</informalexample>
</para>
</sect3>
</sect2>
<sect2 xml:id="language.types.declarations.examples">
&reftitle.examples;
<example>
<title>Déclaration de type de classe de base</title>
<programlisting role="php">
<![CDATA[
<?php
class C {}
class D extends C {}
// Ceci n'étend pas C.
class E {}
function f(C $c) {
echo get_class($c)."\n";
}
f(new C);
f(new D);
f(new E);
?>
]]>
</programlisting>
&example.outputs.8;
<screen>
<![CDATA[
C
D
Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
thrown in - on line 8
]]>
</screen>
</example>
<example>
<title>Déclaration de type dinterface de base</title>
<programlisting role="php">
<![CDATA[
<?php
interface I { public function f(); }
class C implements I { public function f() {} }
// Ceci n'implémente pas I.
class E {}
function f(I $i) {
echo get_class($i)."\n";
}
f(new C);
f(new E);
?>
]]>
</programlisting>
&example.outputs.8;
<screen>
<![CDATA[
C
Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
thrown in - on line 8
]]>
</screen>
</example>
<example>
<title>Déclaration de type de retour de base</title>
<programlisting role="php">
<![CDATA[
<?php
function sum($a, $b): float {
return $a + $b;
}
// Notez qu'un float sera retourné.
var_dump(sum(1, 2));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
float(3)
]]>
</screen>
</example>
<example>
<title>Renvoi dun objet</title>
<programlisting role="php">
<![CDATA[
<?php
class C {}
function getC(): C {
return new C;
}
var_dump(getC());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(C)#1 (0) {
}
]]>
</screen>
</example>
<example>
<title>Déclaration de type dargument nullable</title>
<programlisting role="php">
<![CDATA[
<?php
class C {}
function f(?C $c) {
var_dump($c);
}
f(new C);
f(null);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(C)#1 (0) {
}
NULL
]]>
</screen>
</example>
<example>
<title>Déclaration de type de retour nullable</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
function get_item(): ?string {
if (isset($_GET['item'])) {
return $_GET['item'];
} else {
return null;
}
}
?>
]]>
</programlisting>
</example>
<example>
<title>Déclaration de type pour les propriétés de classe</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
class User {
public static string $foo = 'foo';
public int $id;
public string $username;
public function __construct(int $id, string $username) {
$this->id = $id;
$this->username = $username;
}
}
?>
]]>
</programlisting>
</example>
</sect2>
<!-- TODO Move this into its own declare page -->
<sect2 xml:id="language.types.declarations.strict">
<title>Typage Strict</title>
<para>
Par défaut, PHP va convertir les valeurs d'un mauvais type vers le type
scalaire attendu tant que possible. Par exemple, une fonction, qui attend
comme paramètre une <type>string</type>, à laquelle est passée un
<type>int</type> recevra une variable de type <type>string</type>.
</para>
<para>
Il est possible d'activer le mode de typage strict fichier par fichier.
Dans le mode strict, seule une variable correspondant exactement au
type attendu dans la déclaration sera acceptée sinon une
<classname>TypeError</classname> sera lancée.
La seule exception à cette règle est qu'une valeur de type <type>int</type>
peut passer une déclaration de type <type>float</type>.
</para>
<warning>
<simpara>
Les appels aux fonctions depuis des fonctions internes ne seront pas
affectés par la déclaration <literal>strict_types</literal>.
</simpara>
</warning>
<para>
Pour activer le mode strict, l'expression &declare; est utilisée avec la
déclaration <literal>strict_types</literal> :
</para>
<note>
<para>
Le typage strict s'applique aux appels de fonction effectués depuis
<emphasis>l'intérieur</emphasis> d'un fichier dont le typage strict est
actif, et non aux fonctions déclarées dans ce fichier. Si un fichier dont
le typage strict n'est pas activé effectue un appel à une fonction qui a
été définie dans un fichier dont le type strict est actif, la préférence de
l'appelant (mode coercitif) sera respectée et la valeur sera forcée.
</para>
</note>
<note>
<para>
Le typage strict n'est défini que pour les déclarations de type scalaire.
</para>
</note>
<example>
<title>Typage strict pour les valeurs d'arguments</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
declare(strict_types=1);
function sum(int $a, int $b) {
return $a + $b;
}
var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
?>
]]>
</programlisting>
&example.outputs.8;
<screen>
<![CDATA[
int(3)
Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
thrown in - on line 4
]]>
</screen>
</example>
<example>
<title>Typage coercitif pour les valeurs d'arguments</title>
<programlisting role="php">
<![CDATA[
<?php
function sum(int $a, int $b) {
return $a + $b;
}
var_dump(sum(1, 2));
// Ceux-ci seront convertis en entiers : notez la sortie ci-dessous !
var_dump(sum(1.5, 2.5));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
int(3)
int(3)
]]>
</screen>
</example>
<example>
<title>Typage strict pour les valeurs de retour</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
declare(strict_types=1);
function sum($a, $b): int {
return $a + $b;
}
var_dump(sum(1, 2));
var_dump(sum(1, 2.5));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
int(3)
Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
Stack trace:
#0 -(9): sum(1, 2.5)
#1 {main}
thrown in - on line 5
]]>
</screen>
</example>
</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
-->