#php
Вопрос:
У меня есть строка, содержащая позицию ключа массива, которую я пытаюсь использовать для доступа к массиву ($arr).
Пример строки ($str), которая имеет строковое значение svg.1.linearGradient.0.@style
Это было бы эквивалентно ['svg'][1]['linearGradient'][0]['@style']
Как я могу использовать строку для доступа/извлечения данных из $arr, используя указанную выше позицию?
Например, допустим, я хотел сбросить ключ массива unset($arr['svg'][1]['linearGradient'][0]['@style'])
— как я могу добиться этого программно?
Ответ №1:
Вы можете использовать механизм передачи значения по ссылке:
$result = amp;$arr;
$path = explode('.', $str);
for($i = 0; $i < count($path); $i ) {
$key = $path[$i];
if (is_array($result) amp;amp; array_key_exists($key, $result)) {
if ($i == count($path) - 1) {
unset($result[$key]); // deleting an element with the last key
} else {
$result = amp;$result[$key];
}
} else {
break; // not found
}
}
unset($result); // resetting value by reference
print_r($arr);
Комментарии:
1. это выглядит великолепно, спасибо!
2. есть ли способ получить исходное значение ключа с помощью этого также, если я хочу установить новый ключ с тем же значением ?
3. Если вам нужно сохранить значение перед его удалением, просто сохраните его в другой переменной. Если вам нужно заменить значение, просто назначьте новое, а не отменяйте
$result[$key] = 'new value';
его . обновленная скрипка4. я был бы признателен, если бы вы могли обновить скрипку, чтобы показать третий вариант и установить значение $result[$key] под новым именем ключа в той же позиции массива (давайте назовем это @style2)
$arr['svg'][1]['linearGradient'][0][@style2]
.. если, конечно, нет другого способа просто заменить существующее имя ключа? Я бы посмотрел на установку нового ключа со значением, предшествующим сбросу старого ключа
Ответ №2:
Одним из методов может быть разделение строки .
, а затем повторение «ключей» для обхода вашего $arr
объекта. (Пожалуйста, извините мой бедный php, прошло много времени…)
Пример:
$arr = (object)[
"svg" => (array)[
(object)[],
(object)[
"linearGradient" => [
(object)[
"@style" => "testing",
],
],
],
],
];
$str = "svg.1.linearGradient.0.@style";
$keys = explode('.', $str);
$val = $arr;
foreach($keys as $key) {
$val = is_object($val)
? $val->$key
: $val[$key];
}
echo $val;
Сброс ключа с учетом пути:
$arr = (object)[
"svg" => (array)[
(object)[],
(object)[
"linearGradient" => [
(object)[
"@style" => "testing",
],
],
],
],
];
$str = "svg.1.linearGradient.0.@style";
$keys = explode('.', $str);
$exp = "$arr";
$val = $arr;
foreach($keys as $index => $key) {
$exp .= is_object($val)
? "->{'" . $key . "'}"
: "[" . $key . "]";
$val = is_object($val) ? $val->$key : $val[$key];
}
eval("unset($exp);");
Документы
Комментарии:
1. спасибо, это позволяет мне получить доступ к массиву и вернуть значение. Что, если я захочу отключить ключ и его значение?
unset($arr['svg'][1]['linearGradient'][0]['@style'])
?2. да, но фрагмент кода возвращает только пару «ключ» и «значение», я не думаю, что смогу отменить его только с помощью unset($key). мне также понадобится путь к ключу.
3. У меня есть решение, чтобы отключить ключ, но оно не идеально. Требует
eval()
…