在我的印象中只有 isset 可以判断一个变量是否设置,empty 去判断一个变量是否为空。并且,如果是数组下标未定义的变量,empty 判断还是会报错的。

之后遇到反驳,说效果都一样,他测试过。测试环境是 laravel 5.2 + php 7.1 的 production 环境,确实没有报错,甚至修改成 development 开发模式,打开 app_debug,依然不会报错。

想起之前开发过的项目,想到了两个测试环境,一个是全裸的 php 脚本直接执行,还有一个是其他框架,比如 tp、yii2 等。

首先测试的是全裸 php 脚本

测试 demo 如下:

$a = [0, 1];
// 直接输出为空,所以给它包一层
echo json_encode(['res' => $a[2]]);

PHP 5.6、php7.0 ~ 7.4 结果:

{"res":null}

但到了 php8.0 结果发生了变化:

Warning: Undefined array key 2 in D:\Projects\test\ept_ist.php on line 17
{"res":null}

在 php8.0 的时候收货了一个 warning 级别的报错。想到之前裸框架 php 会在公共文件中加两行代码来控制环境中错误输出:

ini_set("display_errors", "On");//若页面不报错的话,请设置php.ini 的display_errors 为 On

error_reporting(E_ALL);//报所有的错误

本地环境测试发现 display_errors 默认开启的,然后不同 php 版本重新测了一遍,然后对于 php8.0 以下版本,又收货了一个 notice 级别的报错:

Notice: Undefined offset: 2 in D:\Projects\test\ept_ist.php on line 17
{"res":null}

所以,是会存在数组索引下标未定义的错误的,只不过在 php8.0 以下级别较低,一般都会被忽略掉。

tp 等框架测试

测试 tp 5.1,demo 如下:

Route::get('ept-ist', function () {
    $a = [0, 1];
    return $a[2];
});

不管是切换到什么 PHP 版本,亦或关闭 app_debug,都会有报错信息,其中将 app_debug 打开时,报的错误为:未定义数组下标: 2

测试了 laravel 8.73.2,但因为其依赖的 php 已经到了 8.0,所以无意外地报错了。APP_DEBUG 关闭时,报错:500 SERVER ERROR,开启时报错:Undefined array key 2

总结

写到这,我突然意识到,我是在证明下标未定义的错误是否会有警告,而不是 empty 一个未定义下标的数组变量是否会报错。

再次测试,尴了个尬,没有任何报错。

然后赶紧去翻 empty 的手册定义,果然有这么一条参数说明:

注意:

在 PHP 5.5 之前,empty() 仅支持变量;任何其他东西将会导致一个解析错误。换言之,下列代码不会生效: empty(trim($name))。 作为替代,应该使用trim($name) == false.

没有警告会产生,哪怕变量并不存在。 这意味着 empty() 本质上与 !isset($var) || $var == false 等价。

所以结论就是,empty 在判断一个未定义的数组变量时不会警告报错。

文章目录