1

私のスクリプトでは、特定の配列要素 (たとえば、$foo['bar']) が異なる値を取ることも、まったく値を持たないこともあります。$foo['bar']の値が42 と等しくない場合、特定のアクションがトリガーされます。次のコード

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']通知を回避します。

||これはまた、2 つのオペランドを逆にする、通知が表示され、2 番目のオペランドはとにかくほとんど役に立たないことも意味します。

0false、などの値[]も等しくないため、次のように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)評価されるexpr2場合expr1は に評価されTRUE、評価されるexpr3場合は にexpr1評価され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 answerを使用できます。

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