PHP 8.0.30类型检查疑问:为何仅首次操作触发类型校验?
为什么PHP在这个场景下只有testCLSFatal触发类型错误?
这和"PHP仅在首次操作时进行类型检查"没关系,核心原因是两个类的赋值逻辑差异,以及PHP逻辑运算符的特性:
先看testCLS的执行逻辑
在testCLS的构造函数里:
$this->isVar = self::func1() || self::func2();
这里的||是逻辑或运算符,它有两个关键特性:
- 短路求值:如果左边表达式的布尔值为
true,就不会执行右边的表达式;如果左边是false,才会执行右边。 - 返回布尔值:不管左右两边的原始值是什么类型,
||最终都会返回一个布尔值(true或false)。
具体到你的代码:
self::func1()返回0,在PHP里0被视为布尔值false,所以会继续执行右边的self::func2()self::func2()返回数组['some_val'],非空数组在PHP里被视为布尔值true- 整个
||运算的结果是true,这个布尔值被赋值给$isVar(属性类型就是bool),类型完全匹配,所以不会触发错误。
你可以看var_dump($obj->isVar)的输出,结果是bool(true),说明最终赋值的是布尔值,不是数组。
再看testCLSFatal的执行逻辑
构造函数里是直接赋值:
$this->isVar = self::func2();
self::func2()返回的是数组['some_val'],直接赋值给类型为bool的$isVar,类型不匹配,所以触发致命错误。
总结
两个类的差异根本不是"首次操作的类型检查",而是:
testCLS中赋值的是逻辑运算后的布尔值,和属性类型匹配testCLSFatal中赋值的是原始数组,和属性类型不匹配
如果想让testCLS触发类似错误,你可以直接把self::func2()的结果赋值给$isVar,或者用不做类型转换的运算(比如|按位或,但数组不能参与按位运算,会直接报错)。
内容的提问来源于stack exchange,提问作者user28100452
相关产品推荐
相关产品推荐

