-
Notifications
You must be signed in to change notification settings - Fork 152
/
declarations.xml
executable file
·811 lines (739 loc) · 20.4 KB
/
declarations.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 13273912b0f773c35f05297a47daa7f76dd52669 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, à 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 type <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 d’intersection a été ajoutée.
</entry>
</row>
<row>
<entry>8.1.0</entry>
<entry>
Le renvoi par référence à partir d’une 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 d’une 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 lorsqu’elle é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 n’est 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>n’est vérifié qu’à</emphasis> l’entrée de
la fonction, au début de l’appel, mais pas lorsque la fonction est de
nouveau appelée.
Cela signifie qu’une 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 d’utilisation 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>
Antérieur à PHP 8.2.0 et l’introduction 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 d’unions</title>
<warning>
<simpara>
Il n’est pas possible de combiner les deux types de valeur
<literal>false</literal> et <literal>true</literal> ensemble dans une
union de type.
Utilisez plutôt <type>bool</type>.
</simpara>
</warning>
<caution>
<simpara>
Antérieur à 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é uniquement de ces types n’était pas autorisé. 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 d’un point d’interrogation (<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 d’obtenir des arguments nullable en faisant de
<literal>null</literal> la valeur par défaut.
Ceci n’est 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.
</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 qu’une seule fois.
Les types tels que <literal>int|string|INT</literal> ou
<literal>Countable&Traversable&COUNTABLE</literal>
génèrent une erreur.
</simpara>
</listitem>
<listitem>
<simpara>
L’utilisation de <type>mixed</type> entraîne une erreur.
</simpara>
</listitem>
<listitem>
<simpara>Pour les types d’unions :</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 d’intersections :</simpara>
<itemizedlist>
<listitem>
<simpara>
L’utilisation d’un type qui n’est pas un type de classe génère une
erreur.
</simpara>
</listitem>
<listitem>
<simpara>
L’utilisation de <type>self</type>, <type>parent</type> ou
<type>static</type> entraîne une erreur.
</simpara>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<simpara>Pour les type <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 d’intersection 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 {}
// This doesn't extend 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 d’interface de base</title>
<programlisting role="php">
<![CDATA[
<?php
interface I { public function f(); }
class C implements I { public function f() {} }
// This doesn't implement 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;
}
// Note that a float will be returned.
var_dump(sum(1, 2));
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
float(3)
]]>
</screen>
</example>
<example>
<title>Renvoi d’un 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 d’argument 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">
<![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">
<![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 levé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é 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">
<![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));
// These will be coerced to integers: note the output below!
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">
<![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
-->