在我的脚本中,特定的数组元素(例如,$foo['bar']
)可以采用不同的值,或者根本没有值。如果$foo['bar']
的值不等于,则会触发特定操作,例如,42。以下代码
if (!isset($foo['bar']) || ($foo['bar'] != '42')) action()
并不理想,因为php会发出关于何时未设置$foo['bar']
的警告。
问题:有没有一种优雅的方法来测试这种情况?
答案 0 :(得分:4)
此代码:
if (!isset($foo['bar']) || $foo['bar'] != 42) {
}
由于短路逻辑,实际上不会发出任何警告,因为它会在第一个条件下跳过,在这种情况下,如果未定义$foo['bar']
则会发生这种情况。
这也可以从编译器为您的代码生成的操作码中看出:
compiled vars: !0 = $foo
line # * op fetch ext return operands
------------------------------------------------------------------------------
3 0 > ZEND_ISSET_ISEMPTY_DIM_OBJ 1 ~0 !0, 'bar'
1 BOOL_NOT ~1 ~0
2 > JMPNZ_EX ~1 ~1, ->6
3 > FETCH_DIM_R $2 !0, 'bar'
4 IS_NOT_EQUAL ~3 $2, 42
5 BOOL ~1 ~3
6 > > JMPZ ~1, ->8
4 7 > > JMP ->8
8 > > RETURN 1
以下操作码很重要:
2 > JMPNZ_EX ~1 ~1, ->6
isset($foo['bar'])
的反转结果会被检查,如果代码跳过实际检查$foo['bar']
值的下几个语句,从而避免任何通知。
这也意味着如果你要反转||
的两个操作数,你将得到通知,而第二个操作数无论如何都是无用的。
由于0
,false
,[]
等值也不等于42
,因此您也可以使用empty()
:
if (empty($foo['bar']) || $foo['bar'] != 42) {
}
这可以说代码更容易阅读。
答案 1 :(得分:2)
可以这样
$bar = isset($foo['bar']) ? $foo['bar'] : NULL;
你没有收到警告而你正在设置变量。
然后你做检查
if($bar != 42 && !empty($bar)){
//do something
}
如果(expr1) ? (expr2) : (expr3)
评估为expr2
,则expr1
表达式评估为TRUE
;如果expr3
评估为expr1
,则表达式FALSE
答案 2 :(得分:1)
我认为这就是你想要的:
if (!(isset($foo['bar']) && ($foo['bar'] = '42'))) action();
答案 3 :(得分:1)
对于PHP 5.3+,您可以使用Emilio Gort answer的优化版本:
$bar = isset($foo['bar']) ?: '';
if ($bar != 42) action();