PHP 在变量声明时不需要定义类型。在这种情况下,变量的类型由存储的值决定。也就是说,如果 string 赋值给 $var,然后 $var 的类型就是 string。之后将 int 值赋值给 $var,它将是 int 类型。
PHP 可能会尝试在某些上下文中自动将值转换为另一种类型。不同的上下文有:
注意: 当值需要解释为不同类型时,值本身不会改变类型。
强制将变量当做某种变量来求值,参见类型转换一节。要更改变量的类型,请参阅 settype() 函数。
使用算术运算符时的上下文。
在这种情况下,如果任一运算对象是 float(或者不能解释为 int),则两个运算对象都将解释为 float,结果也将是 float。否则,运算对象将解释为 int,结果也将是 int。自 PHP 8.0.0 起,如果无法解释其中一个运算对象,则会抛出 TypeError。
使用 echo、print、字符串插值或者字符串连接运算符时的上下文。
这种情况下,值将会解释为 string。如果值无法解释,那么会抛出
TypeError。在 PHP 7.4.0 之前,会引发 E_RECOVERABLE_ERROR
。
使用位运算符时的上下文。
在这种情况下,如果所有的运算对象都是 string,则结果也将是 string。否则运算对象将解释为 int,结果也将是 int。如果其中一个运算对象无法解释,则会抛出 TypeError。
将值传递给已声明类型的参数、属性,或从声明了返回类型的函数返回值时的上下文。
在此上下文中,值必须是类型值。但存在两个例外,第一个是如果值为 int,但声明的类型是 float,然后整数会转换为浮点数。第二个是如果声明的类型是 scalar 类型,值可转换为标量类型,并且强制类型模式处于活动状态(默认),值会转换为可接受的标量值。参见下文查看有关此行为的描述。
当未启用 strict_types
时,声明的标量类型会受到有限的隐式类型转换的影响。如果值的精确类型不是联合的一部分,然后会按照以下优先顺序选择目标类型:
注意:
示例 #1 类型转换为 union 类型中的一个的示例
<?php
// int|string
42 --> 42 // 具体类型
"42" --> "42" // 具体类型
new ObjectWithToString --> "Result of __toString()"
// 对象绝不会兼容 int,回退到 string
42.0 --> 42 // int 兼容 float
42.1 --> 42 // int 兼容 float
1e100 --> "1.0E+100" // float 对于 int 类型来说太大了,回退为 string
INF --> "INF" // float 对于 int 类型来说太大了,回退为 string
true --> 1 // int 兼容 bool
[] --> TypeError // int 或 string 不兼容 array
// int|float|bool
"45" --> 45 // int 数字 string
"45.0" --> 45.0 // float 数字 string
"45X" --> true // 不是 numeric string,回退为 bool
"" --> false // 不是 numeric string,回退为 bool
"X" --> true // 不是 numeric string,回退为 bool
[] --> TypeError // int、float 或 bool 不兼容 array
?>
类型转换通过在值前面的括号中写入类型来将值转换指定的类型。
<?php
$foo = 10; // $foo 是 int
$bar = (bool) $foo; // $bar 是 bool
?>
允许的转换是:
(int)
——转换为 int(bool)
——转换为 bool(float)
——转换为 float(string)
——转换为 string(array)
——转换为 array(object)
——转换为 object(unset)
——转换为 NULL注意:
(integer)
是(int)
转换的别名。(boolean)
是(bool)
转换的别名。(binary)
是(string)
转换的别名。(double)
和(real)
是(float)
转换的别名。这些转换不使用标准的类型名称,不推荐使用。
自 PHP 8.0.0 起弃用 (real)
转换别名。
自 PHP 7.2.0 起弃用 (unset)
转换。注意
(unset)
转换等同于将值 NULL
通过赋值或者调用给变量。自 PHP 8.0.0 起移除 unset
转换。
向前兼容 (binary)
转换和 b
前缀转换。注意 (binary)
转换和 (string)
相同,但是这可能会改变且不应依赖。
注意:
类型转换的括号中的空格将被忽略。 因此,以下两个转换是等价的:
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
注意: 除了将变量转换为 string 之外,还可以将变量放在双引号内。
<?php
$foo = 10; // $foo 是 int
$str = "$foo"; // $str 是 string
$fst = (string) $foo; // $fst 也是 string
// 打印出 "they are the same"
if ($fst === $str) {
echo "they are the same";
}
?>
有时在类型之间转换时确切地会发生什么可能不是很明显。更多信息见如下不分:
注意: 因为 PHP 的 string 支持使用与 array 索引相同的语法,通过偏移量进行索引,所以以下示例适用于所有 PHP 版本:
请查看章节标题为存取和修改字符串中的字符获取更多信息。<?php
$a = 'car'; // $a 是 string
$a[0] = 'b'; // $a 依然是 string
echo $a; // bar
?>