为什么在if语句中带有赋值null值的PHP变量为false?

时间:2013-04-10 21:52:00

标签: php null

我只是在调试一些代码,并发现

$id = null;
$field = $id === null ? true : false;
$field = $id ? true : false;

两者都应将$ field设置为TRUE值。但由于某种原因,它不能按预期工作。第一个返回true,另一个返回false。

编辑1:我在编写问题时不小心误解了一些事情。这应该是它与众不同的原因。

Edit2:我问我的问题,因为这个行为在2个不同的服务器上有所不同。 第二个示例应该返回True,但不知何故,它在我的一台服务器上不会返回true。

Edit3:这是真正的代码。它在Prestashop 1.5中的类/ ObjectModel.php

/* Copy the field, or the default language field if it's both required and empty */
        if ((!$this->id_lang AND isset($this->{$field}[$id_language]) AND !empty($this->{$field}[$id_language])) 
        OR ($this->id_lang AND isset($this->$field) AND !empty($this->$field)))
            $fields[$id_language][$field] = $this->id_lang === null ? pSQL($this->$field) : pSQL($this->{$field}[$id_language]);
        elseif (in_array($field, $this->fieldsRequiredLang))
            $fields[$id_language][$field] = $this->id_lang === null ? pSQL($this->$field) : pSQL($this->{$field}[Configuration::get('PS_LANG_DEFAULT')]);
        else
            $fields[$id_language][$field] = '';

预期的行为(在大多数服务器上都是如此)是,如果将$ this-> id_lang设置为null,则应使用$ this-> $ field而不是$ this-> $ field [$ id_language] 。 但是,在我在CentOS机器上设置的服务器上,这种行为有所不同,当值设置为null时,它会将$ this-> $ field [$ id_language]作为值。

2 个答案:

答案 0 :(得分:4)

声明(遗憾的是你编辑过)与:

相同
$id = null;
if($id === null) {
    $field = true;
} else {
    $field = false;
}

你还在期待假吗? :)

您的问题中的陈述是使用所谓的三元运算符。要了解您的示例,您应该阅读此documentation(章节:三元运算符

三元运算符是if语句的简写,允许缩短代码,尤其是条件赋值。但是,您提出这个问题的事实就是一个很好的例子,因为它的缺点是:它的可读性较差;)

答案 1 :(得分:3)

关于编辑3,如果您在使用相同代码和数据集的不同发行版上遇到不同的结果,那么我的猜测是您正在使用的CentOS二进制文件已被其开发人员修改并且已经引入了一个错误,可能在运算符中优先级。

作为一般规则,我个人更喜欢在括号中附上每个条款或一组条款,以减少发生此类事件的可能性,因此我建议尝试以下方法:

if ((!$this->id_lang && isset($this->{$field}[$id_language]) && !empty($this->{$field}[$id_language])) || ($this->id_lang && isset($this->$field) && !empty($this->$field))) {
    $fields[$id_language][$field] = (($this->id_lang === null) ? pSQL($this->$field) : pSQL($this->{$field}[$id_language]));
} else if (in_array($field, $this->fieldsRequiredLang)) {
    $fields[$id_language][$field] = (($this->id_lang === null) ? pSQL($this->$field) : pSQL($this->{$field}[Configuration::get('PS_LANG_DEFAULT')]));
} else {
    $fields[$id_language][$field] = '';
}

这样,您可以强制解析器按照您定义的顺序评估各种子句和运算符,而不是解析器认为应该处理它们的顺序。

原始答案

$ field被设置为true,因为===运算符比较两个值,如果它们包含相同的值和相同的类型,则返回true。

通过将$ id设置为null,您基本上就是运行它:

$field = (null === null);

您可以扩展当前代码以阐明逻辑如下:

if ($id === null) {
    $field = true;
} else {
    $field = false;
}

或者,你可以简单地运行:

$field = ($id === null);