Как извлечь данные из JSON с помощью PHP?
Предполагается, что это общий справочный вопрос и ответ, охватывающий многие бесконечные вопросы "Как получить доступ к данным в моем JSON?" вопросы. Это здесь, чтобы справиться с широкими основами декодирования JSON в PHP и доступа к результатам.
У меня есть JSON:
{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}
Как мне декодировать это в PHP и получить доступ к полученным данным?
9 ответов
вступление
Во-первых, у вас есть строка. JSON не является массивом, объектом или структурой данных. JSON - это текстовый формат сериализации - такая необычная строка, но все же просто строка. Расшифруйте его в PHP с помощью json_decode()
,
$data = json_decode($json);
Там вы можете найти:
- скаляры: строки, целые числа, числа с плавающей запятой и bools
- нули (особый тип)
- составные типы: объекты и массивы.
Это те вещи, которые могут быть закодированы в JSON. Точнее, это версии PHP вещей, которые можно кодировать в JSON.
В них нет ничего особенного. Они не являются "объектами JSON" или "массивами JSON". Вы расшифровали JSON - теперь у вас есть базовые повседневные типы PHP.
Объекты будут экземплярами stdClass, встроенного класса, который является просто общей вещью, которая здесь не важна.
Доступ к свойствам объекта
Вы получаете доступ к свойствам одного из этих объектов так же, как и к общедоступным нестатическим свойствам любого другого объекта, например $object->property
,
$json = '
{
"type": "donut",
"name": "Cake"
}';
$yummy = json_decode($json);
echo $yummy->type; //donut
Доступ к элементам массива
Вы получаете доступ к элементам одного из этих массивов так же, как и для любого другого массива, например $array[0]
,
$json = '
[
"Glazed",
"Chocolate with Sprinkles",
"Maple"
]';
$toppings = json_decode($json);
echo $toppings[1]; //Chocolate with Sprinkles
Переберите его с foreach
,
foreach ($toppings as $topping) {
echo $topping, "\n";
}
глазированный
Шоколад с окропляет
кленовый
Или возиться с любой из встроенных функций массива bazillion.
Доступ к вложенным элементам
Свойства объектов и элементов массивов могут быть больше объектов и / или массивов - вы можете просто продолжать получать доступ к их свойствам и элементам, как обычно, например, $object->array[0]->etc
,
$json = '
{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}';
$yummy = json_decode($json);
echo $yummy->toppings[2]->id; //5004
Переходя true
в качестве второго аргумента для json_decode ()
Когда вы сделаете это, вместо объектов вы получите ассоциативные массивы - массивы со строками для ключей. Снова вы получаете доступ к его элементам, как обычно, например, $array['key']
,
$json = '
{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}';
$yummy = json_decode($json, true);
echo $yummy['toppings'][2]['type']; //Maple
Не знаю, как структурированы данные
Прочитайте документацию о том, что вы получаете JSON.
Посмотрите на JSON - где вы видите фигурные скобки {}
ожидать объект, где вы видите квадратные скобки []
ожидать массив.
Хит декодированные данные с print_r()
:
$json = '
{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}';
$yummy = json_decode($json);
print_r($yummy);
и проверьте вывод:
stdClass Object
(
[type] => donut
[name] => Cake
[toppings] => Array
(
[0] => stdClass Object
(
[id] => 5002
[type] => Glazed
)
[1] => stdClass Object
(
[id] => 5006
[type] => Chocolate with Sprinkles
)
[2] => stdClass Object
(
[id] => 5004
[type] => Maple
)
)
)
Он скажет вам, где у вас есть объекты, где у вас есть массивы, а также имена и значения их членов.
Если вы можете зайти так далеко, прежде чем заблудитесь - зайдите так далеко и нажмите print_r()
:
print_r($yummy->toppings[0]);
stdClass Object
(
[id] => 5002
[type] => Glazed
)
Разбейте проблему на части, которые легче обернуть вокруг.
json_decode()
возвращается null
Это происходит потому, что либо:
- JSON состоит исключительно из этого,
null
, - JSON недействителен - проверьте результат
json_last_error_msg
или поместите это через что-то вроде JSONLint. - Он содержит элементы, вложенные более 512 уровней. Эту максимальную глубину по умолчанию можно изменить, передав целое число в качестве третьего аргумента
json_decode()
,
Если вам нужно изменить максимальную глубину, вы, вероятно, решаете не ту проблему. Узнайте, почему вы получаете такие глубоко вложенные данные (например, запрашиваемая служба, которая генерирует JSON, содержит ошибку) и убедитесь, что этого не происходит.
Имя свойства объекта содержит специальный символ
Иногда у вас будет имя свойства объекта, которое содержит что-то вроде дефиса -
или в знак @
который не может быть использован в литеральном идентификаторе. Вместо этого вы можете использовать строковый литерал в фигурных скобках для адресации.
$json = '{"@attributes":{"answer":42}}';
$thing = json_decode($json);
echo $thing->{'@attributes'}->answer; //42
Если у вас есть целое число как свойство, см.: Как получить доступ к свойствам объекта с именами, такими как целые числа? как ссылки.
Кто-то положил JSON в ваш JSON
Это смешно, но это случается - в вашем JSON есть кодировка в виде строки. Расшифруйте, получите доступ к строке как обычно, расшифруйте ее и в конечном итоге получите то, что вам нужно.
$json = '
{
"type": "donut",
"name": "Cake",
"toppings": "[{ \"type\": \"Glazed\" }, { \"type\": \"Maple\" }]"
}';
$yummy = json_decode($json);
$toppings = json_decode($yummy->toppings);
echo $toppings[0]->type; //Glazed
Данные не помещаются в памяти
Если ваш JSON слишком велик для json_decode()
чтобы справиться сразу все становится сложнее. Увидеть:
Как это отсортировать
См.: Справочник: все основные способы сортировки массивов и данных в PHP.
Вы можете использовать json_decode() для преобразования строки json в объект / массив PHP.
Например.
Входные данные:
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
var_dump(json_decode($json, true));
Выход:
object(stdClass)#1 (5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
array(5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
Несколько моментов для запоминания:
json_decode
требует, чтобы строка была действительнойjson
иначе он вернетсяNULL
,- В случае невозможности декодирования,
json_last_error()
может быть использован для определения точного характера ошибки. - Убедитесь, что вы проходите в
utf8
содержание илиjson_decode
может выдать ошибку и просто вернутьNULL
значение.
<?php
$jsonData = '{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}';
// Decode the JSON
$data = json_decode($jsonData, true);
// Access the data
$type = $data['type'];
$name = $data['name'];
$toppings = $data['toppings'];
// Access individual topping details
$firstTopping = $toppings[0];
$firstToppingId = $firstTopping['id'];
$firstToppingType = $firstTopping['type'];
// Print the data
echo "Type: $type\n";
echo "Name: $name\n";
echo "First Topping ID: $firstToppingId\n";
echo "First Topping Type: $firstToppingType\n";
?>
В этом примере json_decode() используется для декодирования данных JSON в ассоциативный массив PHP. После этого вы сможете получить доступ к отдельным элементам массива, как и к любому массиву PHP.
// Using json as php array
$json = '[{"user_id":"1","user_name":"Sayeed Amin","time":"2019-11-06 13:21:26"}]';
//or use from file
//$json = file_get_contents('results.json');
$someArray = json_decode($json, true);
foreach ($someArray as $key => $value) {
echo $value["user_id"] . ", " . $value["user_name"] . ", " . $value["time"] . "<br>";
}
Мы можем декодировать строку json в массив, используя функцию json_decode в php
1) json_decode ($ json_string) // возвращает объект
2) json_decode($json_string,true) // возвращает массив
$json_string = '{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}';
$array = json_decode($json_string,true);
echo $array['type']; //it gives donut
Рассмотрите возможность использования JSONPath
https://packagist.org/packages/flow/jsonpath
Существует довольно четкое объяснение того, как его использовать и анализировать JSON-файл, избегая всех предложенных циклов. Если вы знакомы сXPath
за XML
вам понравится этот подход.
Я написал пакет с именем JSON
( GitHub, Packagist). Если вы хотите предотвратить накладные расходы на использование json_*
функции, вы должны попробовать это.
пример
use MAChitgarha\Component\JSON;
$jsonStr = <<<JSON
{
"type": "donut",
"name": "Cake",
"toppings": [
{ "id": "5002", "type": "Glazed" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5004", "type": "Maple" }
]
}
JSON;
// Create an instance
$json = new JSON($jsonStr);
// Get a nested element using dots
$json->get("toppings.1.type"); // Chocolate with Sprinkles
$json["toppings.1.type"]; // Chocolate with Sprinkles
// Iterate over an element
foreach ($json->iterate("toppings") as $item)
echo "{$item->id}: {$item->type}", PHP_EOL;
// Change an element
$json->set("toppings.3", [
"id" => "5000",
"type" => "Unknown"
]);
// Get data as JSON string, array or object, respectively
$json->getDataAsJson();
$json->getDataAsArray();
$json->getDataAsObject();
Посмотрите вики или краткое руководство, чтобы ознакомиться с ним.
Кроме того, если вы хотите прочитать файлы JSON и извлечь их данные (как вам кажется, вы пытаетесь это сделать), посмотрите пакет JSONFile, который я тоже написал.
Принятый ответ очень подробный и правильный в большинстве случаев.
Я просто хочу добавить, что я получал ошибку при попытке загрузить текстовый файл JSON, закодированный с помощью UTF8, у меня был хорошо отформатированный JSON, но 'json_decode' всегда возвращал мне NULL, это было связано с меткой спецификации .
Чтобы решить эту проблему, я сделал эту функцию PHP:
function load_utf8_file($filePath)
{
$response = null;
try
{
if (file_exists($filePath)) {
$text = file_get_contents($filePath);
$response = preg_replace("/^\xEF\xBB\xBF/", '', $text);
}
} catch (Exception $e) {
echo 'ERROR: ', $e->getMessage(), "\n";
}
finally{ }
return $response;
}
Затем я использую его так, чтобы загрузить файл JSON и получить из него значение:
$str = load_utf8_file('appconfig.json');
$json = json_decode($str, true);
//print_r($json);
echo $json['prod']['deploy']['hostname'];
https://paiza.io/projects/X1QjjBkA8mDo6oVh-J_63w
Проверьте код ниже для преобразования JSON в массив в PHP
Если JSON верен, то json_decode()
работает хорошо, и вернет массив, но если искаженный JSON, то он вернет NULL
,
<?php
function jsonDecode1($json){
$arr = json_decode($json, true);
return $arr;
}
// In case of malformed JSON, it will return NULL
var_dump( jsonDecode1($json) );
Если JSON искажен, и вы ожидаете только массив, вы можете использовать эту функцию,
<?php
function jsonDecode2($json){
$arr = (array) json_decode($json, true);
return $arr;
}
// In case of malformed JSON, it will return an empty array()
var_dump( jsonDecode2($json) );
Если JSON искажен, и вы хотите остановить выполнение кода, то вы можете использовать эту функцию,
<?php
function jsonDecode3($json){
$arr = (array) json_decode($json, true);
if(empty(json_last_error())){
return $arr;
}
else{
throw new ErrorException( json_last_error_msg() );
}
}
// In case of malformed JSON, Fatal error will be generated
var_dump( jsonDecode3($json) );
Вы можете использовать любую функцию в зависимости от ваших требований,