web-dev-qa-db-ja.com

PHP:多次元配列内のセルの存在をテストします

多数の次元を持つ配列があり、セルの存在をテストしたいと思います。

以下のカスケードアプローチは、確実に安全な方法です。

if (array_key_exists($arr, 'dim1Key'))  
  if (array_key_exists($arr['dim1Key'], 'dim2Key'))  
    if (array_key_exists($arr['dim1Key']['dim2Key'], 'dim3Key'))  
      echo "cell exists";  

しかし、もっと簡単な方法はありますか?

これについて詳しく説明します。

  1. このチェックを1つのステートメントで実行できますか?
  2. Array_key_existを使用する必要がありますか、それともissetのようなものを使用できますか?それぞれをいつ使用するのですか、またその理由は何ですか?
31
shealtiel

isset()は、多次元配列の場合でも、テストの標準的な方法です。どのディメンションが欠落しているかを正確に知る必要がない限り、次のようになります。

_isset($arr[1][2][3])
_

_[1]_要素と_[2]_要素が存在しない場合でも(1と2が存在しない限り3は存在できません)、完全に受け入れられます。

ただし、

_$arr['a'] = null;
_

その後

_isset($arr['a']); // false
array_key_exists('a', $arr); // true
_

コメントフォローアップ:

たぶん、このアナロジーが役立つでしょう。 PHP変数(実際の変数、配列要素など)を段ボール箱と考えてください。

  • isset()はボックスの内部を調べ、ボックスの内容を「nullではない」ものにタイプキャストできるかどうかを判断します。ボックスが存在するかどうかは関係ありません。ボックスの内容のみが関係します。ボックスが存在しない場合は、明らかに何も含めることができません。
  • array_key_exists()はボックス自体が存在するかどうかをチェックします。箱の中身は関係ありません、それは段ボールの痕跡をチェックしています。
72
Marc B

同じ問題が発生していましたが、Drupalのものが必要でした。オブジェクトに配列だけでなくアイテムも含まれているかどうかも確認する必要がありました。これが私が作成したコードで、再帰検索です。オブジェクトに配列だけでなく値も含まれているかどうかを確認します。誰かがそれを役立つと思うかもしれません。

function recursiveIsset($variable, $checkArray, $i=0) {
    $new_var = null;
    if(is_array($variable) && array_key_exists($checkArray[$i], $variable))
        $new_var = $variable[$checkArray[$i]];
    else if(is_object($variable) && array_key_exists($checkArray[$i], $variable))
        $new_var = $variable->$checkArray[$i];
    if(!isset($new_var))
        return false;

    else if(count($checkArray) > $i + 1)
        return recursiveIsset($new_var, $checkArray, $i+1);
    else
        return $new_var;
}

使用:たとえば

recursiveIsset($variables, array('content', 'body', '#object', 'body', 'und'))

私の場合、drupalこの場合、次の変数が存在するということです。

$variables['content']['body']['#object']->body['und']

'#o​​bject'がobjectと呼ばれているからといって、そうであるとは限らないことに注意してください。この場所が存在する場合、私の再帰検索もtrueを返します

$variables->content->body['#object']->body['und']
6
user1327498

高速なワンライナーの場合は、 メソッドあり from この配列ライブラリ を使用できます。

Arr::has('dim1Key.dim2Key.dim3Key')

大きな利点は、ドット表記を使用して配列キーを指定できることです。これにより、物事がよりシンプルでエレガントになります。

また、このメソッドは内部でarray_key_existsを使用するため、null値に対して期待どおりに機能します。

0
Minwork

$arr['dim1Key']['dim2Key']['dim3Key']を確認する場合は、安全のために、dim3Keyの前にすべての配列が存在するかどうかを確認する必要があります。次に、array_key_existsを使用できます。

そうです、次のような1つのifステートメントを使用するより簡単な方法があります。

if (isset($arr['dim1Key']['dim2Key']) &&
    array_key_exists('dim3Key', $arr['dim1Key']['dim2Key'])) ...
0
Kwadz