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.
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.
In this context the value will be interpreted as string.
If the value cannot be interpreted a TypeError is thrown.
Prior to PHP 7.4.0, an E_RECOVERABLE_ERROR was raised.
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.
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.
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:
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
?>
(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:
<?php $foo = (int) $bar; $foo = ( int ) $bar; ?>
Casting literal strings and variables to binary
strings:
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:
Example #4 Using Array Offset with a String
<?php $a = 'car'; // $a is a string $a[0] = 'b'; // $a is still a string echo $a; // bar ?>
Uneven division of an integer variable by another integer variable will result in a float by automatic conversion -- you do not have to cast the variables to floats in order to avoid integer truncation (as you would in C, for example):
Cast operators have a very high precedence, for example (int)$a/$b is evaluated as ((int)$a)/$b, not as (int)($a/$b) [which would be like intdiv($a,$b) if both $a and $b are integers]. The only exceptions (as of PHP 8.0) are the exponentiation operator ** [i.e. (int)$a**$b is evaluated as (int)($a**$b) rather than ((int)$a)**$b] and the special access/invocation operators ->, ::, [] and () [i.e. in each of (int)$a->$b, (int)$a::$b, (int)$a[$b] and (int)$a($b), the cast is performed last on the result of the variable expression].
Yes, that looks like an array with two keys with the same name and it looks like the protected field was prepended with an asterisk. But that's not true:
The char codes show that the protected keys are prepended with '\0*\0' and private keys are prepended with '\0'.__CLASS__.'\0' so be careful when playing around with this.
If you want to convert a string automatically to float or integer (e.g. "0.234" to float and "123" to int), simply add 0 to the string - PHP will do the rest.
The object casting methods presented here do not take into account the class hierarchy of the class you're trying to cast your object into.
/** * Convert an object to a specific class. * @param object $object * @param string $class_name The class to cast the object to * @return object */ public static function cast($object, $class_name) { if($object === false) return false; if(class_exists($class_name)) { $ser_object = serialize($object); $obj_name_len = strlen(get_class($object)); $start = $obj_name_len + strlen($obj_name_len) + 6; $new_object = 'O:' . strlen($class_name) . ':"' . $class_name . '":'; $new_object .= substr($ser_object, $start); $new_object = unserialize($new_object); /** * The new object is of the correct type but * is not fully initialized throughout its graph. * To get the full object graph (including parent * class data, we need to create a new instance of * the specified class and then assign the new * properties to it. */ $graph = new $class_name; foreach($new_object as $prop => $val) { $graph->$prop = $val; } return $graph; } else { throw new CoreException(false, "could not find class $class_name for casting in DB::cast"); return false; } }
Printing or echoing a FALSE boolean value or a NULL value results in an empty string: (string)TRUE //returns "1" (string)FALSE //returns "" echo TRUE; //prints "1" echo FALSE; //prints nothing!
There are some shorter and faster (at least on my machine) ways to perform a type cast. <?php $string='12345.678'; $float=+$string; $integer=0|$string; $boolean=!!$string; ?>
This PHP documentation is very thorough. An observation about comments, maybe they lost sense when become old, and the page changes, so, should be signaled this condition, or add a link to the document version when the comment was made.