language/types/type-juggling.xml
183439d468314fc3b1a62cf58feb20330922ed11
...
...
@@ -81,6 +81,8 @@
81
81

82
82
<simpara>
83
83
In this context the value will be interpreted as <type>string</type>.
84
+
If the value cannot be interpreted a <classname>TypeError</classname> is thrown.
85
+
Prior to PHP 7.4.0, an <constant>E_RECOVERABLE_ERROR</constant> was raised.
84
86
</simpara>
85
87
</sect2>
86
88

...
...
@@ -102,7 +104,7 @@
102
104
<title>Integral and string contexts</title>
103
105

104
106
<simpara>
105
-
This is the context when using a
107
+
This is the context when using
106
108
<link linkend="language.operators.bitwise">bitwise operators</link>.
107
109
</simpara>
108
110

...
...
@@ -131,7 +133,7 @@
131
133
</simpara>
132
134
</sect2>
133
135

134
-
<sect2>
136
+
<sect2 xml:id="language.types.type-juggling.function">
135
137
<title>Function contexts</title>
136
138

137
139
<simpara>
...
...
@@ -140,9 +142,28 @@
140
142
</simpara>
141
143

142
144
<para>
143
-
In this context, when coercive typing mode is active (the default),
144
-
only scalar values may be converted to another scalar value.
145
-
For simple types declarations the behaviour is as follows:
145
+
In this context the value must be a value of the type.
146
+
Two exceptions exist, the first one is: if the value is of type
147
+
<type>int</type> and the declared type is <type>float</type>, then the
148
+
integer is converted to a floating point number.
149
+
The second one is: if the declared type is a <emphasis>scalar</emphasis>
150
+
<!-- e.g. An object that implements __toString will pass a string type -->
151
+
type, the value is convertable to a scalar type,
152
+
and the coercive typing mode is active
153
+
(the default), the value may be converted to an accepted scalar value.
154
+
See below for a description of this behaviour.
155
+
</para>
156
+

157
+
<warning>
158
+
<simpara>
159
+
<link linkend="functions.internal">Internal functions</link>
160
+
automatically coerce &null; to scalar types,
161
+
this behaviour is <emphasis>DEPRECATED</emphasis> as of PHP 8.1.0.
162
+
</simpara>
163
+
</warning>
164
+

165
+
<sect3 xml:id="language.types.type-juggling.function.simple">
166
+
<title>Coercive typing with simple type declarations</title>
146
167
<itemizedlist>
147
168
<listitem>
148
169
<simpara>
...
...
@@ -152,14 +173,14 @@
152
173
<listitem>
153
174
<simpara>
154
175
<type>int</type> type declaration: value is interpreted as <type>int</type>
155
-
if conversion is well-defined. I.e. the string is
176
+
if the conversion is well-defined. For example the string is
156
177
<link linkend="language.types.numeric-strings">numeric</link>.
157
178
</simpara>
158
179
</listitem>
159
180
<listitem>
160
181
<simpara>
161
182
<type>float</type> type declaration: value is interpreted as <type>float</type>
162
-
if conversion is well-defined. I.e. the string is
183
+
if the conversion is well-defined. For example the string is
163
184
<link linkend="language.types.numeric-strings">numeric</link>.
164
185
</simpara>
165
186
</listitem>
...
...
@@ -169,18 +190,95 @@
169
190
</simpara>
170
191
</listitem>
171
192
</itemizedlist>
193
+
</sect3>
172
194

173
-
If the type declaration is a union, see the section about
174
-
<link linkend="language.types.declarations.union.coercive">Coercive typing with union types</link>.
175
-
</para>
195
+
<sect3 xml:id="language.types.type-juggling.function.union">
196
+
<title>Coercive typing with union types</title>
197
+
<para>
198
+
When <literal>strict_types</literal> is not enabled, scalar type declarations
199
+
are subject to limited implicit type coercions.
200
+
If the exact type of the value is not part of the union, then the target type
201
+
is chosen in the following order of preference:
202
+

203
+
<orderedlist>
204
+
<listitem>
205
+
<simpara>
206
+
<type>int</type>
207
+
</simpara>
208
+
</listitem>
209
+
<listitem>
210
+
<simpara>
211
+
<type>float</type>
212
+
</simpara>
213
+
</listitem>
214
+
<listitem>
215
+
<simpara>
216
+
<type>string</type>
217
+
</simpara>
218
+
</listitem>
219
+
<listitem>
220
+
<simpara>
221
+
<type>bool</type>
222
+
</simpara>
223
+
</listitem>
224
+
</orderedlist>
225
+

226
+
If the type exists in the union and the value can be coerced to the
227
+
type under PHP's existing type-checking semantics, then the type is chosen.
228
+
Otherwise, the next type is tried.
229
+
</para>
230
+

231
+
<caution>
232
+
<para>
233
+
As an exception, if the value is a string and both int and float are part
234
+
of the union, the preferred type is determined by the existing
235
+
<link linkend="language.types.numeric-strings">numeric string</link>
236
+
semantics.
237
+
For example, for <literal>"42"</literal> <type>int</type> is chosen,
238
+
while for <literal>"42.0"</literal> <type>float</type> is chosen.
239
+
</para>
240
+
</caution>
241
+

242
+
<note>
243
+
<para>
244
+
Types that are not part of the above preference list are not eligible
245
+
targets for implicit coercion. In particular no implicit coercions to
246
+
the <type>null</type>, <type>false</type>, and <type>true</type>
247
+
types occur.
248
+
</para>
249
+
</note>
250
+

251
+
<example>
252
+
<title>Example of types being coerced into a type part of the union</title>
253
+
<programlisting role="php">
254
+
<![CDATA[
255
+
<?php
256
+
// int|string
257
+
42 --> 42 // exact type
258
+
"42" --> "42" // exact type
259
+
new ObjectWithToString --> "Result of __toString()"
260
+
// object never compatible with int, fall back to string
261
+
42.0 --> 42 // float compatible with int
262
+
42.1 --> 42 // float compatible with int
263
+
1e100 --> "1.0E+100" // float too large for int type, fall back to string
264
+
INF --> "INF" // float too large for int type, fall back to string
265
+
true --> 1 // bool compatible with int
266
+
[] --> TypeError // array not compatible with int or string
267
+

268
+
// int|float|bool
269
+
"45" --> 45 // int numeric string
270
+
"45.0" --> 45.0 // float numeric string
271
+

272
+
"45X" --> true // not numeric string, fall back to bool
273
+
"" --> false // not numeric string, fall back to bool
274
+
"X" --> true // not numeric string, fall back to bool
275
+
[] --> TypeError // array not compatible with int, float or bool
276
+
?>
277
+
]]>
278
+
</programlisting>
279
+
</example>
280
+
</sect3>
176
281

177
-
<warning>
178
-
<simpara>
179
-
<link linkend="functions.internal">Internal functions</link>
180
-
automatically coerce &null; to scalar types,
181
-
this behaviour is <emphasis>DEPRECATED</emphasis> as of PHP 8.1.0.
182
-
</simpara>
183
-
</warning>
184
282
</sect2>
185
283

186
284
<sect2 xml:id="language.types.typecasting">
...
...
@@ -254,7 +352,7 @@ $bar = (bool) $foo; // $bar is a boolean
254
352
<note>
255
353
<para>
256
354
Whitespaces are ignored within the parentheses of a cast.
257
-
Therefore, the following are two casts are equivalent:
355
+
Therefore, the following two casts are equivalent:
258
356
<informalexample>
259
357
<programlisting role="php">
260
358
<![CDATA[
261
359