抛出问题

php 的 == | === | isempty() 等对变量的判断一直是比较烦人的。今天是遇到了一个关于 == 的简单问题:

var_dump('0' == false); // true
var_dump(null == false); // true
var_dump(null == '0'); // false

问题来了,为什么 null == '0' 会是 false 呢?毕竟大家都会把 0, '', '0', false, null, array() 都当做“空”来解读。

找到答案

之前有遇到过好奇为什么 isset() 函数的变量不能是一个方法,而 empty() 可以。然后就简单搜索了下,并跟着文章看了下 php 源码。这次依然是这样,直接从源码中寻找答案。

首先,在zend_language_scanner.l 中搜了下 ==,发现了 T_IS_EQUAL,很暴力的在整个目录中搜了下 T_IS_EQUAL,各个文件烦了下,在 zend_language_parser.y 中找到了 ZEND_IS_EQUAL。依然老方法,文件夹搜ZEND_IS_EQUAL,找到了其最后对应函数compare_function
就这么一层一层往下找,最后在 zend_operators.c 中约1880行的位置找到了这个函数,其中相关代码如下:

            case TYPE_PAIR(IS_NULL, IS_STRING):
                ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
                return SUCCESS;

            case TYPE_PAIR(IS_STRING, IS_NULL):
                ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
                return SUCCESS;

现在再来解释问题,就很容易了。PHP 当遇到 null 和字符串比较时,其实相当于计算了字符串长度是否为0。也就是默认了只有'' == null 是成立的。