Type Juggling
PHP does not require explicit type definition in variable declaration.
In this case, the type of a variable is determined by the value it stores.
That is to say, if a string is assigned to variable
$var, then $var is of type
string. If afterwards an int value is assigned
to $var, it will be of type int.
PHP may attempt to convert the type of a value to another automatically
in certain contexts. The different contexts which exist are:
-
Numeric
-
String
-
Logical
-
Integral and string
-
Comparative
-
Function
Note:
When a value needs to be interpreted as a different type, the value itself
does not change types.
To force a variable to be evaluated as a certain type, see the section on
Type casting. To change the
type of a variable, see the settype() function.
Numeric contexts
This is the context when using an
arithmetical operator.
In this context if either operand is a float (or not
interpretable as an int), both operands are interpreted as
floats, and the result will be a float.
Otherwise, the operands will be interpreted as ints,
and the result will also be an int.
As of PHP 8.0.0, if one of the operands cannot be interpreted a
TypeError is thrown.
Integral and string contexts
This is the context when using
bitwise operators.
In this context if all operands are of type string the result
will also be a string.
Otherwise, the operands will be interpreted as ints,
and the result will also be an int.
As of PHP 8.0.0, if one of the operands cannot be interpreted a
TypeError is thrown.
Comparative contexts
This is the context when using a
comparison operator.
The type conversions which occur in this context are explained in the
Comparison with Various Types
table.
Function contexts
This is the context when a value is passed to a typed parameter, property,
or returned from a function which declares a return type.
In this context the value must be a value of the type.
Two exceptions exist, the first one is: if the value is of type
int and the declared type is float, then the
integer is converted to a floating point number.
The second one is: if the declared type is a scalar
type, the value is convertable to a scalar type,
and the coercive typing mode is active
(the default), the value may be converted to an accepted scalar value.
See below for a description of this behaviour.
Warning
Internal functions
automatically coerce null
to scalar types,
this behaviour is DEPRECATED as of PHP 8.1.0.
Coercive typing with simple type declarations
-
bool type declaration: value is interpreted as bool.
-
int type declaration: value is interpreted as int
if the conversion is well-defined. For example the string is
numeric.
-
float type declaration: value is interpreted as float
if the conversion is well-defined. For example the string is
numeric.
-
string type declaration: value is interpreted as string.
Coercive typing with union types
When strict_types
is not enabled, scalar type declarations
are subject to limited implicit type coercions.
If the exact type of the value is not part of the union, then the target type
is chosen in the following order of preference:
-
int
-
float
-
string
-
bool
If the type exists in the union and the value can be coerced to the
type under PHP's existing type-checking semantics, then the type is chosen.
Otherwise, the next type is tried.
Caution
As an exception, if the value is a string and both int and float are part
of the union, the preferred type is determined by the existing
numeric string
semantics.
For example, for "42"
int is chosen,
while for "42.0"
float is chosen.
Note:
Types that are not part of the above preference list are not eligible
targets for implicit coercion. In particular no implicit coercions to
the null, false, and true
types occur.
Example #1 Example of types being coerced into a type part of the union
<?php
// int|string
42 --> 42 // exact type
"42" --> "42" // exact type
new ObjectWithToString --> "Result of __toString()"
// object never compatible with int, fall back to string
42.0 --> 42 // float compatible with int
42.1 --> 42 // float compatible with int
1e100 --> "1.0E+100" // float too large for int type, fall back to string
INF --> "INF" // float too large for int type, fall back to string
true --> 1 // bool compatible with int
[] --> TypeError // array not compatible with int or string
// int|float|bool
"45" --> 45 // int numeric string
"45.0" --> 45.0 // float numeric string
"45X" --> true // not numeric string, fall back to bool
"" --> false // not numeric string, fall back to bool
"X" --> true // not numeric string, fall back to bool
[] --> TypeError // array not compatible with int, float or bool
?>
Type Casting
Type casting converts the value to a chosen type by writing the type within
parentheses before the value to convert.
The casts allowed are:
Note:
(integer)
is an alias of the (int)
cast.
(boolean)
is an alias of the (bool)
cast.
(binary)
is an alias of the (string)
cast.
(double)
and (real)
are aliases of
the (float)
cast.
These casts do not use the canonical type name and are not recommended.
Warning
The (real)
cast alias has been deprecated as of PHP 8.0.0.
Warning
The (unset)
cast has been deprecated as of PHP 7.2.0.
Note that the (unset)
cast is the same as assigning the
value NULL to the variable or call.
The (unset)
cast is removed as of PHP 8.0.0.
Caution
The (binary)
cast and b
prefix exists
for forward support. Currently (binary)
and
(string)
are identical, however this may change and
should not be relied upon.
Note:
Whitespaces are ignored within the parentheses of a cast.
Therefore, the following two casts are equivalent:
Note:
Instead of casting a variable to a string, it is also possible
to enclose the variable in double quotes.
It may not be obvious exactly what will happen when casting between certain
types. For more information, see these sections:
Note:
Because PHP supports indexing into strings via offsets
using the same syntax as array indexing, the following example
holds true for all PHP versions:
See the section titled String
access by character for more information.