Подтвердить что ты не робот

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";  

Но есть ли более простой способ?

Я расскажу подробнее об этом:

  • Можно ли выполнить эту проверку в одном заявлении?
  • Нужно ли использовать array_key_exist или я могу использовать что-то вроде isset? Когда я использую каждый и почему?
4b9b3361

Ответ 1

isset() - это канонический метод тестирования, даже для многомерных массивов. Если вам не нужно точно знать, какое измерение отсутствует, то что-то вроде

isset($arr[1][2][3])

вполне приемлемо, даже если элементы [1] и [2] отсутствуют (3 не может существовать, если только 1 и 2 не существуют).

Однако, если у вас

$arr['a'] = null;

затем

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

комментарий:

Может быть, эта аналогия поможет. Подумайте о переменной PHP (фактическая переменная, элемент массива и т.д.) В виде картонной коробки:

  • isset() смотрит в поле и выясняет, может ли содержимое ящика привести к чему-то, что "не равно нулю". Не имеет значения, существует ли коробка или нет - она ​​заботится только о содержимом коробки. Если ящик не существует, то он, очевидно, ничего не может содержать.
  • array_key_exists() проверяет, существует ли сама коробка или нет. Содержимое коробки не имеет значения, оно проверяет наличие следов картона.

Ответ 2

У меня была такая же проблема, за исключением того, что мне это нужно для некоторых вещей 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']

следует отметить, что только потому, что "#object" называется объектом, это не значит, что это так. Мой рекурсивный поиск также вернет true, если это место существует

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

Ответ 3

Если вы хотите проверить $arr['dim1Key']['dim2Key']['dim3Key'], чтобы быть в безопасности, вы должны проверить, существуют ли все массивы перед dim3Key. Тогда вы можете использовать array_key_exists.

Так что да, есть более простой способ использования одного оператора if подобный следующему:

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

Ответ 4

Для быстрого одного лайнера, который вы можете использовать, имеет метод из этой библиотеки массивов:

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

Большим преимуществом является то, что вы можете использовать точечную нотацию для указания ключей массива, что делает вещи проще и элегантнее.

Кроме того, этот метод будет работать, как ожидается, для null значения, потому что он внутренне использует array_key_exists.