我试图分析一个奇怪的案例,其中一些关于isset()的代码在我的Unix测试服务器(最近更新到PHP 7.0.6)的本地Windows机器(PHP 7.0.3)上表现不同。但是当试图在Windows机器上创建一个更简单的可重现代码片段时,它的行为就像Unix服务器一样。
有问题的行是
if (isset($this->settings[$Model->alias]['Log']->_schema['model'])) {
$this->settings[$Model->alias]['Log']
是一个对象,_schema
是受保护的属性,它是一个数组。密钥model
存在于此数组中。在Unix服务器上,if-condition返回false。在Windows服务器上,它返回true。在更新之前的Unix测试服务器上,以及在我们高效的Web服务器上,它也返回true。
我理解在受保护的属性上执行的isset()
应始终返回false。所以它本来不应该起作用。检查属性本身确实在Windows和Unix上都返回false:
$this->settings[$Model->alias]['Log']->_schema) // false
但检查此数组属性的键的行为有所不同。在Windows和高效服务器上:
$this->settings[$Model->alias]['Log']->_schema['model']) // true
在测试服务器上:
$this->settings[$Model->alias]['Log']->_schema['model']) // false
然后我尝试创建一个更简单的可重现代码片段:
<?php
class Log {
protected $_schema = array(
'model' => array(
'name' => 'change',
),
);
}
class Model {
public $alias = 'Contact';
}
class LogableBehavior {
public $settings = array();
function __construct() {
$Model = new Model();
$this->settings[$Model->alias]['Log'] = new Log();
echo isset($this->settings[$Model->alias]['Log']->_schema)?'true':'false';
echo '<br/>';
echo isset($this->settings[$Model->alias]['Log']->_schema['model'])?'true':'false';
echo '<br/>';
}
}
$obj = new LogableBehavior();
此输出
false
false
在所有机器上。这就是我所期待的。但是在更大的项目中,代码isset($this->settings[$Model->alias]['Log']->_schema['model'])
在我的本地Windows机器和高效服务器上返回true。
我在其他地方读到,在检查数组键时使用isset()
但是有问题的变量实际上是字符串而不是数组,结果可能是意外的。但这不适用于此,因为受保护的属性_schema
在调试时是一个数组。
任何解释的想法?