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? Когда я использую каждый и почему?
Ответы
Ответ 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
.