曾经踩过的 PHP 一个小坑:null 合并运算符 ??
什么是 null
合并运算符?
由于在日常使用中会使用大量的三元表达式(比如 ThinkPHP
框架)和 isset() 的场景, PHP 7
增加了 null
合并运算符 ??
。变量存在且值不为 null
,它就会返回自身的值,否则返回它的第二个操作数。简化了代码,提升了效率。
$_SESSION['user'] ?? 'none';
等价于
isset($_SESSION['user']) ? $_SESSION['user'] : 'none';
但一次在工作中不小心踩了一个坑,逻辑是这样的:如果返回值为空,则使用第二个操作数。但是实际明知返回值为空的情况下,却始终拿不到第二个操作数的值。
原因是把 null
与 false
、空字符串等价了。
$arr = [false, '', 0, 0.0];
foreach ($arr as $v) {
echo empty($v) . '<br />';
echo (null == $v) . '<br />';
}
以上代码输出结果全为 1 ,表明在 null
与这些数据类型在使用 ==
运算符的情况下是等价的。但 isset() 只认变量值是否为 null
,只有在变量值被设置且为 null
的情况下才返回第二个操作数。
但是有种情况会有一种麻痹作用,那就是逻辑上如果变量被设置且为 null
就返回一个空字符串。虽然语法和结果都正确,但实际是一段有瑕疵的代码。
// 如果 session 值不存在就返回空值,实际上返回的是 session 的空值
// 虽然结果正确,只是碰巧而已
isset($_SESSION['user']) ? $_SESSION['user'] : '';
如果采用考虑数据类型的 ===
强等于运算符,结果则都为 false
。
$arr = [false, '', 0, 0.0];
foreach ($arr as $v) {
echo (null === $v) . '<br />';
}
如果确定变量被设置且为 null
,推荐使用 ??
。如果不确定则使用 empty() 。
!empty($_SESSION['user']) ? $_SESSION['user'] : '';
但是 empty() “杀伤力”不小,尤其是在处理与数据库有关的业务中,慎用 empty() 。例如
if(!empty($data['params'])) {
$update['id'] = ltrim($data['params']);
}
因为数据库的表中有的字段数据值可以是 0 以及字符串类型 "0"
等等 。所以此时采用 isset() 为佳。
if(isset($data['params'])) {
$update['id'] = ltrim($data['params']);
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
有踩过,关于 false、null 和 0