PHP 三元运算很好用也很容易踩雷

PHP 三元运算在日常编码中应用非常频繁,可以很好的减少代码的长度,减少if-else的代码片段。但是好用是很好用,如果用的不恰当也是非常容易踩雷的。今天就看看PHP的三元运算符有什么雷区。

1、怎么执行的?

$type = 2;
echo $type == 1 ? "1" : $type == 2 ? "2"  : $type == 3 ? "3" : "4";

以上内容输出结果为3。

查看php运算符优先级表格,”==”的优先级别高于三元运算符。因此上面的代码等价于:

$res = $type == 1?"1":($type == 2);
//$res = true

$res = $res ?2:($type ==3);
//$res=2

$res = $res ? "3" :4;
//$res = 3

echo $res;

网上很多都以”PHP三元运算符的运算顺序是反的”为标题的文章,其实,执行顺序并不是反的,而是运算符优先级的问题。

2、PHP7中新的三元运算与三元运算简写容易搞错

PHP7中新增三元运算符”??”,在PHP5.3之后,三元运算符可以简写成”?:”的形式,这两者有什么区别呢?

$data = ['type' =>0];
$type1 = $data['type']??-1;
$type2 = $data['type']?:-1;
var_dump($type1,$type2);

以上代码输出内容分别未0,-1。

PHP7新增的三元运算符用于简化判断变量是否设置。上面的代码等价于一下内容:

$data = ['type'=>0];
$type1 = isset($data['type'])?$data['type']:-1;
$type2 = $data['type']?$data['type']:-1;

在日常开发当中,通常需要对数组键值是否存在进行判断。如果使用新的三元运算符就会变得简单很多。如果不使用新的三元运算符,同时没有进行键值检查,PHP会抛出一个NOTICE,比如以下代码:

$data = ['type' =>0];
$type1 = $data['status']??-1;
$type2 = $data['status']?:-1;
var_dump($type1,$type2);

第三行代码,由于没有检查data数组中是否存在键值status,因此运行的时候会抛出NOTICE。

鉴于上面的内容,平常写代码的时候非常容易出现的一个现象就是使用empty检查。

$data = ['type' =>10];
$type1 = !empty($data['type'])?:-1;
$type2 = !empty($data['type'])?$data['type']:-1;
var_dump($type1,$type2);

上面代码输出分别是true,1。要非常小心简写形式的情况。

PHP三元运算简写形式,如果条件成立,是以 判断条件 作为最后赋值结果。这种bug一旦写入代码中,很难发现,因此必须要小心。想明白你写的到底是新的三元运算符还是三元运算符简写形式。

总的来说,写三元运算符的时候,尽量不要嵌套。如果要嵌套,也要明确的用括号指定好运算优先级,避免产生不必要的bug。另外就是要明白简写形式的含义是以判断条件作为最后赋值结果,不要与PHP7新增的三元运算符的含义搞混了。