-
Notifications
You must be signed in to change notification settings - Fork 165
Expand file tree
/
Copy pathtype-juggling.xml
More file actions
477 lines (423 loc) · 15.9 KB
/
type-juggling.xml
File metadata and controls
477 lines (423 loc) · 15.9 KB
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
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 78a11d3ca004ee937549d932e77a79c51b9777cd Maintainer: girgias Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.types.type-juggling">
<title>Jonglage de type</title>
<simpara>
PHP ne requiert pas une définition de type explicite dans les déclarations de variables.
Dans ce cas, le type d'une variable est déterminé en fonction de la valeur qu'elle stocke.
C'est-à-dire, si une <type>string</type> est assignée à la variable
<varname>$var</varname>, alors <varname>$var</varname> est de type
<type>string</type>. Si après une valeur <type>int</type> est assignée à
<varname>$var</varname>, elle sera de type <type>int</type>.
</simpara>
<para>
PHP peut tenter de convertir le type d'une valeur en une autre automatiquement
dans certains contextes. Les différents contextes qui existent sont :
<itemizedlist>
<listitem>
<simpara>Numérique</simpara>
</listitem>
<listitem>
<simpara>String</simpara>
</listitem>
<listitem>
<simpara>Logique</simpara>
</listitem>
<listitem>
<simpara>Intégral et string</simpara>
</listitem>
<listitem>
<simpara>Comparatif</simpara>
</listitem>
<listitem>
<simpara>Fonction</simpara>
</listitem>
</itemizedlist>
</para>
<note>
<simpara>
Quand une valeur a besoin d'être interprétée comme un type différent,
la valeur elle-même <emphasis>ne change pas</emphasis> de type.
</simpara>
</note>
<simpara>
Pour forcer une variable à être évaluée comme un type particulier, voir la
section sur le <link linkend="language.types.typecasting">casting de type</link>.
Pour changer le type d'une variable, voir la fonction <function>settype</function>.
</simpara>
<sect2>
<title>Contextes numériques</title>
<simpara>
Ceci est le contexte lors de l'utilisation d'un
<link linkend="language.operators.arithmetic">opérateur arithmétique</link>.
</simpara>
<simpara>
Dans ce contexte si un des opérandes est un <type>float</type> (ou pas
interprétable comme <type>int</type>), les deux opérandes sont interprétés
comme des <type>float</type>s, et le résultat sera un <type>float</type>.
Sinon, les opérandes sont interprétés comme des <type>int</type>s,
et le résultat sera aussi un <type>int</type>.
À partir de PHP 8.0.0, si un des opérandes ne peut être interprété, une
<classname>TypeError</classname> est lancée.
</simpara>
</sect2>
<sect2>
<title>Contextes string</title>
<simpara>
Ceci est le contexte lors de l'utilisation de <function>echo</function>,
<function>print</function>, <link linkend="language.types.string.parsing">l'interpolation de chaînes de caractères</link>, ou l'
<link linkend="language.operators.string">opérateur de concaténation</link>
pour les chaînes de caractères.
</simpara>
<simpara>
Dans ce contexte la valeur sera interprétée comme une <type>string</type>.
Si la valeur ne peut pas être interprétée, une
<classname>TypeError</classname> est levée.
Avant PHP 7.4.0, une <constant>E_RECOVERABLE_ERROR</constant> était soulevée.
</simpara>
</sect2>
<sect2>
<title>Contextes logiques</title>
<simpara>
Ceci est le contexte lors de l'utilisation de déclarations conditionnelles,
l'<link linkend="language.operators.comparison.ternary">opérateur ternaire</link>,
ou un <link linkend="language.operators.logical">opérateur logique</link>.
</simpara>
<simpara>
Dans ce contexte la valeur sera interprétée comme un <type>bool</type>.
</simpara>
</sect2>
<sect2>
<title>Contextes intégraux et string</title>
<simpara>
Ceci est le contexte lors de l'utilisation d'un
<link linkend="language.operators.bitwise">opérateur bit à bit</link>.
</simpara>
<simpara>
Dans ce contexte si tous les opérandes sont de type <type>string</type>
alors le résultat sera aussi une <type>string</type>.
Sinon, les opérandes seront interprétés comme des <type>int</type>s,
et le résultat sera aussi un <type>int</type>.
À partir de PHP 8.0.0, si un des opérandes ne peut être interprété, une
<classname>TypeError</classname> est lancée.
</simpara>
</sect2>
<sect2>
<title>Contextes comparatifs</title>
<simpara>
Ceci est le contexte lors de l'utilisation d'un
<link linkend="language.operators.comparison">opérateur de comparaison</link>.
</simpara>
<simpara>
Les conversions de types qui se produisent dans ce contexte sont expliquées
dans le <link linkend="language.operators.comparison.types">tableau</link>
Comparaison avec plusieurs types.
</simpara>
</sect2>
<sect2 xml:id="language.types.type-juggling.function">
<title>Contextes de fonctions</title>
<simpara>
Ceci est le contexte quand une valeur est passée à un paramètre ou propriété
typée ou retournée depuis une fonction qui déclare un type de retour.
</simpara>
<para>
Dans ce contexte, la valeur doit être une valeur du type.
Il existe deux exceptions, la première est la suivante : si la valeur est de
type <type>int</type> et que le type déclaré est <type>float</type>, alors
l'entier est converti en nombre à virgule flottante.
La seconde est : si le type déclaré est un type <emphasis>scalaire</emphasis>
<!-- par exemple, un objet qui implémente __toString passera pour un type de chaîne de caractères -->
, la valeur est convertible en un type scalaire, et le mode de typage coercitif
est actif (par défaut), la valeur peut être convertie en une valeur scalaire acceptée.
Voir ci-dessous pour une description de ce comportement.
</para>
<warning>
<simpara>
<link linkend="functions.internal">Les fonctions internes</link>
contraignent automatiquement &null; aux types scalaires,
ce comportement est <emphasis>OBSOLÈTE</emphasis> à partir de PHP 8.1.0.
</simpara>
</warning>
<sect3 xml:id="language.types.type-juggling.function.simple">
<title>Typage coercitif avec déclarations de type simples</title>
<itemizedlist>
<listitem>
<simpara>
Type de déclaration <type>bool</type> : valeur est interprétée comme <type>bool</type>.
</simpara>
</listitem>
<listitem>
<simpara>
Type de déclaration <type>int</type> : valeur est interprétée comme <type>int</type>
si la conversion est bien-définie. Par exemple la chaîne est
<link linkend="language.types.numeric-strings">numérique</link>.
</simpara>
</listitem>
<listitem>
<simpara>
Type de déclaration <type>float</type> : valeur est interprétée comme <type>float</type>
si la conversion est bien-définie. Par exemple la chaîne est
<link linkend="language.types.numeric-strings">numérique</link>.
</simpara>
</listitem>
<listitem>
<simpara>
Type de déclaration <type>string</type> : valeur est interprétée comme <type>string</type>.
</simpara>
</listitem>
</itemizedlist>
</sect3>
<sect3 xml:id="language.types.type-juggling.function.union">
<title>Typage coercitif avec unions de type</title>
<para>
Lorsque <literal>strict_types</literal> n’est pas activé, les
déclarations de type scalaire sont soumises à des contraintes de type
implicites limitées.
Si le type exact de la valeur ne fait pas partie de l’union, le type cible
est choisi dans l’ordre de préférence suivant :
<orderedlist>
<listitem>
<simpara>
<type>int</type>
</simpara>
</listitem>
<listitem>
<simpara>
<type>float</type>
</simpara>
</listitem>
<listitem>
<simpara>
<type>string</type>
</simpara>
</listitem>
<listitem>
<simpara>
<type>bool</type>
</simpara>
</listitem>
</orderedlist>
Si le type existe dans l'union et que la valeur peut être forcée en ce
type en utilisant la sémantique de vérification de type existante de PHP, alors le type est choisi.
Sinon, le type suivant est essayé.
</para>
<caution>
<para>
À titre d’exception, si la valeur est une chaîne et que <type>int</type> et <type>float</type> font
tous deux partie de l’union, le type préféré est déterminé par la
sémantique de <link linkend="language.types.numeric-strings">chaîne numérique</link>.
Par exemple, pour <literal>"42"</literal> <type>int</type> est choisi,
tandis que pour <literal>"42.0"</literal> <type>float</type> est choisi.
</para>
</caution>
<note>
<para>
Les types qui ne font pas partie de la liste de préférences ci-dessus ne
sont pas des cibles admissibles à la coercition implicite. En particulier,
aucune contrainte implicite aux types <type>null</type>,
<type>false</type>, et <type>true</type> ne se produit.
</para>
</note>
<example>
<title>Exemple de types contraints à un type faisant partie de l'union</title>
<programlisting role="php">
<![CDATA[
<?php
// int|string
42 --> 42 // type exact
"42" --> "42" // type exact
new ObjectWithToString --> "Résultat de __toString()"
// Objet jamais compatible avec int, utilisation d'une string par défaut
42.0 --> 42 // float compatible avec int
42.1 --> 42 // float compatible avec int
1e100 --> "1.0E+100" // float trop grand pour le type int, utilisation d'une string par défaut
INF --> "INF" // float trop grand pour le type int, utilisation d'une string par défaut
true --> 1 // bool compatible avec int
[] --> TypeError // tableau non compatible avec int ou string
// int|float|bool
"45" --> 45 // int numérique string
"45.0" --> 45.0 // float numérique string
"45X" --> true // string non numérique, bool par défaut
"" --> false // string non numérique, bool par défaut
"X" --> true // string non numérique, bool par défaut
[] --> TypeError // tableau non compatible avec int, float ou bool
?>
]]>
</programlisting>
</example>
</sect3>
</sect2>
<sect2 xml:id="language.types.typecasting">
<title>Cast de type</title>
<simpara>
Le casting de type convertit la valeur en un type donné en écrivant le type
entre parenthèses avant la valeur à convertir.
</simpara>
<example>
<title>Conversion de type</title>
<programlisting role="php">
<![CDATA[
<?php
$foo = 10; // $foo est un entier
$bar = (bool) $foo; // $bar est un booléen
var_dump($bar);
?>
]]>
</programlisting>
</example>
<simpara>
Les casts permis sont :
</simpara>
<simplelist>
<member><literal>(int)</literal> - cast en <type>int</type></member>
<member><literal>(bool)</literal> - cast en <type>bool</type></member>
<member><literal>(float)</literal> - cast en <type>float</type></member>
<member><literal>(string)</literal> - cast en <type>string</type></member>
<member><literal>(array)</literal> - cast en <type>array</type></member>
<member><literal>(object)</literal> - cast en <type>object</type></member>
<member><literal>(unset)</literal> - cast en <type>NULL</type></member>
</simplelist>
<warning>
<para>
<literal>(integer)</literal> est un alias du cast <literal>(int)</literal>.
<literal>(boolean)</literal> est un alias du cast <literal>(bool)</literal>.
<literal>(binary)</literal> est un alias du cast <literal>(string)</literal>.
<literal>(double)</literal> et <literal>(real)</literal> sont des alias du
cast <literal>(float)</literal>.
Ces casts n'utilisent pas le nom de type canonique et sont obsolètes à partir de PHP 8.5.0.
</para>
</warning>
<warning>
<simpara>
L'alias de cast <literal>(real)</literal> est obsolète à partir de PHP 7.4.0
et supprimé à partir de PHP 8.0.0.
</simpara>
</warning>
<warning>
<simpara>
Le cast <literal>(unset)</literal> a été rendu obsolète à partir de PHP 7.2.0.
À noter que le cast <literal>(unset)</literal> est identique à assigner la
valeur <type>NULL</type> à une variable ou un appel.
Le cast <literal>(unset)</literal> est supprimé à partir de PHP 8.0.0.
</simpara>
</warning>
<caution>
<simpara>
Le cast <literal>(binary)</literal> et le préfixe <literal>b</literal>
existent uniquement pour la compatibilité ascendante. Actuellement
<literal>(binary)</literal> et <literal>(string)</literal> sont identiques,
mais ceci peut changer et il ne faut pas compter dessus.
</simpara>
</caution>
<note>
<para>
Les espaces blancs sont ignorés à l'intérieur des parenthèses d'un cast.
Ainsi, les deux casts suivants sont équivalents :
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
<informalexample>
<simpara>
Cast de <type>string</type>s littérales et variables en
<type>string</type>s binaires :
</simpara>
<programlisting role="php">
<![CDATA[
<?php
$binary = (binary) $string;
$binary = b"binary string";
?>
]]>
</programlisting>
</informalexample>
<!-- TODO Remove or move into string context section? -->
<simpara>
Au lieu de transtyper une variable en une <type>string</type>, il est également possible
d'entourer la variable de guillemets doubles.
</simpara>
<example>
<title>Différents mécanismes de conversion</title>
<programlisting role="php">
<![CDATA[
<?php
$foo = 10; // $foo est un entier
$str = "$foo"; // $str est une chaîne
$fst = (string) $foo; // $fst est également une chaîne
// Ceci affiche "Ils sont les mêmes"
if ($fst === $str) {
echo "Ils sont les mêmes", PHP_EOL;
}
?>
]]>
</programlisting>
</example>
<para>
Ce qui se produira exactement lors d'un transtypage entre certains types
n'est pas forcément évident. Pour plus d'informations, voir ces sections :
<simplelist>
<member><link linkend="language.types.boolean.casting">Convertir en boolean</link></member>
<member><link linkend="language.types.integer.casting">Convertir en integer</link></member>
<member><link linkend="language.types.float.casting">Convertir en float</link></member>
<member><link linkend="language.types.string.casting">Convertir en string</link></member>
<member><link linkend="language.types.array.casting">Convertir en array</link></member>
<member><link linkend="language.types.object.casting">Convertir en object</link></member>
<member><link linkend="language.types.resource.casting">Convertir en resource</link></member>
<member><link linkend="language.types.null.casting">Convertir en NULL</link></member>
<member><link linkend="types.comparisons">Les tables de comparaison de type</link></member>
</simplelist>
</para>
<note>
<simpara>
Comme PHP prend en charge l'indexation dans les <type>string</type>s
via des positions en utilisant la même syntaxe que l'indexation des <type>array</type>,
l'exemple suivant est valable pour toutes les versions de PHP :
</simpara>
<example>
<title>Utilisation d'un index de tableau avec une chaîne</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 'car'; // $a est une chaîne de caractères
$a[0] = 'b'; // $a est toujours une chaîne de caractères
echo $a; // bar
?>
]]>
</programlisting>
</example>
<simpara>
Voir la section sur l'<link linkend="language.types.string.substr">accès
aux chaînes par caractère</link> pour plus d'informations.
</simpara>
</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
-->