Итерация по JSON: применение цикла foreach в PHP
Основы перебора JSON с помощью foreach
Самый распространённый и эффективный способ перебора JSON в PHP – преобразовать данные в ассоциативный массив функцией json_decode() с параметром true, а затем применить цикл foreach. Такой подход позволяет обращаться к элементам по ключам и значениям, как к обычному массиву.
$jsonString = '{"name":"Иван","age":30,"city":"Москва"}';
$array = json_decode($jsonString, true);
foreach ($array as $key => $value) {
echo "$key: $value\n";
}
Php foreach json (перебор json с помощью foreach в php)
name: Иван age: 30 city: Москва
Этот метод подходит для большинства случаев, когда требуется простая итерация по всем полям JSON-объекта.
Как выполнить итерацию по JSON-объекту, не преобразуя его в массив?
Если второй аргумент json_decode() опущен или равен false, возвращается экземпляр класса stdClass. Его тоже можно перебирать через foreach, но доступ к значениям осуществляется через свойства (->).
$obj = json_decode($jsonString); // без true
foreach ($obj as $key => $value) {
echo "$key: $value\n";
}
Результат будет таким же, как и в предыдущем примере. Однако вложенные объекты останутся объектами, что может потребовать дополнительных проверок.
Типичная ошибка – попытка обратиться к несуществующему ключу или свойству. Перед использованием проверяйте наличие ключа с помощью isset() или array_key_exists().
Как перебрать все элементы вложенного JSON (многомерная структура)?
Для вложенных массивов или объектов потребуется несколько вложенных циклов foreach. Важно на каждом уровне знать, какие данные ожидаются.
$json = '[{"id":1,"tags":["a","b"]},{"id":2,"tags":["c"]}]';
$data = json_decode($json, true);
foreach ($data as $item) {
echo "ID: " . $item['id'] . "\n";
foreach ($item['tags'] as $tag) {
echo " tag: $tag\n";
}
}
ID: 1 tag: a tag: b ID: 2 tag: c
Если структура заранее неизвестна, может возникнуть ошибка Invalid argument supplied for foreach, когда элемент не является массивом или объектом. Всегда проверяйте тип данных до входа в цикл: is_array() или is_object().
Как рекурсивно обойти JSON произвольной вложенности?
Для глубокого обхода, когда уровни вложенности неизвестны, удобно написать рекурсивную функцию, которая вызывает себя для каждого элемента-массива или объекта.
function traverse($data, $depth = 0) {
foreach ($data as $key => $value) {
echo str_repeat(' ', $depth) . "$key: ";
if (is_array($value) || is_object($value)) {
echo "\n";
traverse($value, $depth + 1);
} else {
echo $value . "\n";
}
}
}
$json = '{"user":{"name":"Петр","contacts":{"phone":"123","email":"p@e.ru"}},"active":true}';
traverse(json_decode($json, true));
user:
name: Петр
contacts:
phone: 123
email: p@e.ru
active: 1
Как применить callback к каждому элементу JSON без явного цикла?
Функции array_walk() и array_walk_recursive() позволяют обрабатывать элементы массива с помощью пользовательской функции. Они принимают первым аргументом массив (после json_decode($json, true)).
$data = json_decode('[10,20,30]', true);
array_walk($data, function(&$value, $key) {
$value = $value * 2;
});
print_r($data);
Array
(
[0] => 20
[1] => 40
[2] => 60
)
array_walk_recursive() обходит все вложенные массивы, но не заходит в объекты (они должны быть преобразованы в массивы). Этот вариант полезен для массового изменения или извлечения данных.
Как получить только ключи или только значения при итерации?
Иногда требуется перебрать только ключи или только значения. Для ключей можно использовать array_keys(), а затем foreach по ним. Для значений – array_values() или сразу foreach($array as $value) без указания ключа.
$array = json_decode('{"a":1,"b":2,"c":3}', true);
// Только ключи
foreach (array_keys($array) as $key) {
echo "$key ";
}
echo "\n";
// Только значения
foreach (array_values($array) as $value) {
echo "$value ";
}
a b c 1 2 3
Расширенные примеры перебора JSON с foreach
Пример 1: Фильтрация данных с использованием foreach
Предположим, имеется JSON список товаров с ценами. Необходимо отобрать товары дешевле 100 рублей.
$json = '[{"name":"ручка","price":50},{"name":"тетрадь","price":120},{"name":"ластик","price":30}]';
$items = json_decode($json, true);
$cheap = [];
foreach ($items as $item) {
if ($item['price'] < 100) {
$cheap[] = $item['name'];
}
}
print_r($cheap);
Array
(
[0] => ручка
[1] => ластик
)
Пример 2: Изменение значений в JSON-массиве через foreach с ссылкой
Чтобы изменить исходные данные во время итерации, используется синтаксис &$value. Например, увеличить все цены на 10%.
$items = json_decode($json, true);
foreach ($items as &$item) {
$item['price'] = round($item['price'] * 1.1, 2);
}
unset($item); // важно для удаления ссылки после цикла
print_r($items);
Array
(
[0] => Array ( [name] => ручка [price] => 55 )
[1] => Array ( [name] => тетрадь [price] => 132 )
[2] => Array ( [name] => ластик [price] => 33 )
)
Пример 3: Итерация по JSON, содержащему NULL и булевы значения
Значения null, true, false корректно обрабатываются. При выводе true преобразуется в 1, false – в пустую строку, а null – в пустую строку. Чтобы избежать этого, стоит использовать строгое сравнение.
$json = '{"a":null,"b":true,"c":false,"d":0}';
$data = json_decode($json, true);
foreach ($data as $key => $value) {
if ($value === null) {
echo "$key: null\n";
} elseif ($value === true) {
echo "$key: true\n";
} elseif ($value === false) {
echo "$key: false\n";
} else {
echo "$key: $value\n";
}
}
a: null b: true c: false d: 0
Пример 4: Использование SPL-итераторов для перебора JSON
Класс ArrayIterator позволяет оборачивать массив в объект и использовать методы, такие как current(), key(), next(). Это полезно, если требуется более тонкий контроль над итерацией.
$array = json_decode('[{"x":1},{"x":2}]', true);
$iterator = new ArrayIterator($array);
foreach ($iterator as $item) {
echo $item['x'] . "\n";
}
// Или вручную:
$iterator->rewind();
while ($iterator->valid()) {
echo $iterator->current()['x'] . "\n";
$iterator->next();
}
1 2 1 2
Пример 5: Обработка JSON с произвольными ключами и сортировка перед перебором
Иногда требуется отсортировать ассоциативный массив по ключам или значениям перед foreach. Например, ksort() или asort().
$json = '{"c":3,"a":1,"b":2}';
$data = json_decode($json, true);
ksort($data);
foreach ($data as $key => $value) {
echo "$key => $value\n";
}
a => 1 b => 2 c => 3
Пример 6: Обработка очень больших JSON через генератор (построчная загрузка)
Для больших файлов лучше использовать потоковую загрузку (например, fgets()), а затем json_decode каждой строки. Однако если весь JSON уже в памяти, foreach по массиву остаётся эффективным; главное – не копировать данные без необходимости.
// Пример с фейковым большим массивом (демонстрация подхода)
$bigJson = '[' . implode(',', array_fill(0, 10000, '{"id":1}')) . ']';
$data = json_decode($bigJson, true);
$count = 0;
foreach ($data as $item) {
$count++;
}
echo "Обработано элементов: $count\n";
Обработано элементов: 10000