PHP 8.2 新特性 — true 类型
PHP 8.2 允许将 true
作为单独的类型使用,也可以作为联合类型的一部分。
- PHP 7.0 添加了标量类型支持,比如
string
、int
、bool
,扩展了 PHP 类型表达式。 - PHP 8.0 引入了联合类型,
false
也作为联合类型的一部分引入。 - PHP 8.2 起,可以把
true
、null
和false
作为单独的类型使用。
PHP 8.2 起,true
可以在任何接收类型的地方作为类型使用:
class Foo {
private true $processed;
public function process(string|int|true $value): true {
}
}
true 类型非强制转换
参数、属性或者返回类型被声明为 true
时,PHP 并不会强制将其他类型转化为 true
。即使 PHP 脚本禁用严格类型(strict_types), 且即使值在非严格比较下会被转换为 true
,都是这种情况。
比如,以下函数调用不强制将整数值 1 转换为 true
,且会导致类型错误 TypeError
:
function foo(true $value) {}
foo(1);
TypeError: foo(): Argument #1 ($value) must be of type true, int given, called in ... on line ... and defined in ...:...
在联合类型使用 true
true
类型可以作为联合类型的一部分,只要 true
类型不冗余或者不是与 false
类型同时使用。
下面是使用 true
类型作为联合类型的例子:
function sendEmail(true|string): true {
return true;
}
sendEmail(true);
PHP 的 bool
类型本质上是 true|false
联合类型。不过,为了避免含混不清,以下两种约束是强制的。
布尔类型的冗余检测
true
类型不能与 bool
类型一起组成联合类型,因为 bool
类型已经包含了 true
类型。尝试声明会导致编译时致命错误:
function foo(true|bool $value) {}
Fatal error: Duplicate type true is redundant in ... on line ...
不允许 true|false
联合类型
由于 bool
类型本质上就是 true|false
,所以不允许使用 true|false
作为联合类型:
function foo(true|false $value) {}
Fatal error: Type contains both true and false, bool should be used instead in ... on line ...
在交叉类型中使用 true
类型
true
类型也不能用于交叉类型(Inspection type)。使用 true
类型作为交叉类型会出现编译时错误:
function foo(true&false $value) {}
Fatal error: Type true cannot be part of an intersection type in ... on line ...
true Type 方差
true
类型被当作 bool
类型的子类型,PHP 遵循标准的协方差和逆变规则,对 true
类型同样适用。
方差规则的例子中,返回类型为 bool
被 true
类型所取代,联合类型在子类中被缩小了。
class Foo {
public function test(): bool {}
public function test2(): string|true {}
}
class FooBar extends Foo {
public function test(): false {}
public function test2(): true {}
}
逆变规则的例子中, ture
类型参数被扩展至 bool
类型,联合类型也被扩展了:
class Foo {
public function test(true $value): void {}
public function test2(true|string $value): void {}
}
class FooBar extends Foo {
public function test(bool $value): void {}
public function test2(true|string|int $value): void {}
}
向后兼容性影响
true
是 PHP 保留的关键词,在 PHP 8.2 中添加 true
作为有效类型不会导致已有应用的任何兼容问题。
注意,PHP 8.2 以前的版本不能将 true
类型作为单独类型或联合类型使用,会导致编译时致命错误:
Fatal error: Cannot use 'true' as class name as it is reserved in ... on line ...
需要使用 true
类型的 PHP 应用,要添加表达式可以使用 PHPDoc 注释,并诉诸于使用 bool
类型来兼容老版本 PHP:
/**
* @param true $value
*/
function foo(true $value) {}