1

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

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

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

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

4

4 回答 4

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) {
}

这可以说使代码更易于阅读。

于 2013-10-02T03:20:55.220 回答
2

可以这样

$bar = isset($foo['bar']) ? $foo['bar'] : NULL;

在那里你没有收到警告,你正在设置变量。

然后你做检查

 if($bar != 42 && !empty($bar)){
    //do something
 }

读取三元运算符

表达式的(expr1) ? (expr2) : (expr3)计算结果为expr2ifexpr1计算结果为TRUE,并且expr3ifexpr1计算结果为FALSE

于 2013-10-02T03:26:01.477 回答
1

我认为这就是你想要的:

if (!(isset($foo['bar']) && ($foo['bar'] = '42'))) action();
于 2013-10-02T04:00:27.120 回答
1

对于 PHP 5.3+,您可以使用Emilio Gort 答案的优化版本:

$bar = isset($foo['bar']) ?: '';
if ($bar != 42) action();
于 2013-10-02T04:13:14.893 回答