isset和!=在同一个if子句中

时间:2013-10-02 03:18:03

标签: php

在我的脚本中,特定的数组元素(例如,$foo['bar'])可以采用不同的值,或者根本没有值。如果$foo['bar']的值不等于,则会触发特定操作,例如,42。以下代码

if (!isset($foo['bar']) || ($foo['bar'] != '42')) action()

并不理想,因为php会发出关于何时未设置$foo['bar']的警告。

问题:有没有一种优雅的方法来测试这种情况?

4 个答案:

答案 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']值的下几个语句,从而避免任何通知。

这也意味着如果你要反转||的两个操作数,你得到通知,而第二个操作数无论如何都是无用的。

由于0false[]等值也不等于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
 }

阅读Ternary Operator

如果(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();