Как я могу разобрать файл JSON с PHP?

336

Я попытался разобрать файл JSON с помощью PHP. Но я застрял сейчас.

Это содержимое моего файла JSON:

{
    "John": {
        "status":"Wait"
    },
    "Jennifer": {
        "status":"Active"
    },
    "James": {
        "status":"Active",
        "age":56,
        "count":10,
        "progress":0.0029857,
        "bad":0
    }
}

И вот что я пробовал до сих пор:

<?php

$string = file_get_contents("/home/michael/test.json");
$json_a = json_decode($string, true);

echo $json_a['John'][status];
echo $json_a['Jennifer'][status];

Но поскольку я не знаю имен (например, 'John', 'Jennifer') и всех доступных ключей и значений (например, 'age', 'count'), я думаю, мне нужно создать некоторый цикл foreach.

Я был бы признателен за это.

  • 47
    Вы на правильном пути. Посмотрите синтаксис для foreach (вы должны получить ключи и значения). Не сдавайся пока!
  • 9
    @Stefan Mai: foreach($variable as $key => $val) должно быть тем, что вы хотите :-)
Показать ещё 7 комментариев
Теги:

17 ответов

315
Лучший ответ

Чтобы перебрать многомерный массив, вы можете использовать RecursiveArrayIterator

$jsonIterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(json_decode($json, TRUE)),
    RecursiveIteratorIterator::SELF_FIRST);

foreach ($jsonIterator as $key => $val) {
    if(is_array($val)) {
        echo "$key:\n";
    } else {
        echo "$key => $val\n";
    }
}

Вывод:

John:
status => Wait
Jennifer:
status => Active
James:
status => Active
age => 56
count => 10
progress => 0.0029857
bad => 0

запускается в кодексе

  • 10
    Предлагает ли этот подход какое-то особое преимущество перед старым добрым foreach?
  • 11
    @ Альваро, очевидно. С foreach вы можете использовать только один уровень глубины. С вышеупомянутым подходом вы можете использовать многоуровневый массив. Кроме того, все это заключено в ООП, поэтому вам лучше использовать его повторно, и вы можете легко смоделировать его в UnitTests. Кроме того, вы можете объединять итераторы с другими итераторами, делая разные вещи, такие как ограничение, кэширование, фильтрация и т. Д. В дополнение к любым пользовательские итераторы, которые вы можете захотеть создать.
Показать ещё 5 комментариев
106

Я не могу поверить, что многие люди публикуют ответы, не читая JSON должным образом.

Если вы хотите использовать только итерацию $json_a, у вас есть объект объектов. Даже если вы передаете true в качестве второго параметра, у вас есть двумерный массив. Если вы зацикливаете первое измерение, вы не можете просто вторить второму измерению. Так что это неправильно:

foreach ($json_a as $k => $v) {
   echo $k, ' : ', $v;
}

Чтобы отобразить статусы каждого человека, попробуйте следующее:

<?php

$string = file_get_contents("/home/michael/test.json");
$json_a = json_decode($string, true);

foreach ($json_a as $person_name => $person_a) {
    echo $person_a['status'];
}

?>
  • 3
    Если файлы php и json находятся в одном и том же каталоге, мы можем прочитать json с помощью file_get_contents("test.json"); (Не нужно ставить путь).
42

Самое элегантное решение:

$shipments = json_decode(file_get_contents("shipments.js"), true);
print_r($shipments);

Помните, что json файл должен быть закодирован в UTF-8 без спецификации. Если у файла есть спецификация, то json_decode вернет NULL.

В качестве альтернативы:

$shipments = json_encode(json_decode(file_get_contents("shipments.js"), true));
echo $shipments;
  • 3
    Довольно круто, но все из-за Билла о материалах (BOM) меня совершенно запутало. эээ ... о чем ты говоришь? Неужели я единственный, кого раздражает использование загадочных необъяснимых сокращений? Хорошо, чтобы использовать сокращения, но, пожалуйста, объясните, когда впервые используется (WFU) ... спасибо.
  • 5
    BOM = метка порядка байтов.
Показать ещё 2 комментария
17

Try

<?php
$string = file_get_contents("/home/michael/test.json");
$json_a=json_decode($string,true);

foreach ($json_a as $key => $value){
  echo  $key . ':' . $value;
}
?>
  • 1
    Попробуйте Это ответы не очень важны для StackOverflow, потому что они очень мало делают для обучения ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
  • 0
    Как доказано в ответе BoltClock, этот ответ неверен для выборочных данных вопроса.
16

Это полностью вне меня, что никто не указал, что ваши "теги" вашего происхождения ошибочны. Вы создаете объект с {}, в то время как вы можете создать массив с [].

[ // <-- Note that I changed this
    {
        "name" : "john", // And moved the name here.
        "status":"Wait"
    },
    {
        "name" : "Jennifer",
        "status":"Active"
    },
    {
        "name" : "James",
        "status":"Active",
        "age":56,
        "count":10,
        "progress":0.0029857,
        "bad":0
    }
] // <-- And this.

При этом изменении json будет анализироваться как массив вместо объекта. И с этим массивом вы можете делать все, что хотите, например, циклы и т.д.

  • 0
    Вы правы для указания на массив.
  • 0
    О мой Я должен добавить, что вы, кажется, удалили ключ в json ОП при преобразовании в массив. Так что ОП прав.
Показать ещё 2 комментария
15

Попробуйте это

$json_data = '{
"John": {
    "status":"Wait"
},
"Jennifer": {
    "status":"Active"
},
"James": {
    "status":"Active",
    "age":56,
    "count":10,
    "progress":0.0029857,
    "bad":0
  }
 }';

 $decode_data = json_decode($json_data);
foreach($decode_data as $key=>$value){

        print_r($value);
}
  • 2
    Попробуйте Это ответы не очень важны для StackOverflow, потому что они очень мало делают для обучения ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
9

Более стандартный ответ:

$jsondata = file_get_contents(PATH_TO_JSON_FILE."/jsonfile.json");

$array = json_decode($jsondata,true);

foreach($array as $k=>$val):
    echo '<b>Name: '.$k.'</b></br>';
    $keys = array_keys($val);
    foreach($keys as $key):
        echo '&nbsp;'.ucfirst($key).' = '.$val[$key].'</br>';
    endforeach;
endforeach;

И результат:

Name: John
 Status = Wait
Name: Jennifer
 Status = Active
Name: James
 Status = Active
 Age = 56
 Count = 10
 Progress = 0.0029857
 Bad = 0
  • 0
    или может сказать $data = json_decode(file_get_contents("db.json"), true); для первой строки
  • 1
    Ответы только на код имеют низкую ценность в StackOverflow, потому что они очень мало делают для обучения ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
Показать ещё 1 комментарий
9

Try:

$string = file_get_contents("/home/michael/test.json");
$json = json_decode($string, true);

foreach ($json as $key => $value) {
    if (!is_array($value)) {
        echo $key . '=>' . $value . '<br />';
    } else {
        foreach ($value as $key => $val) {
            echo $key . '=>' . $val . '<br />';
        }
    }
}
  • 0
    Попробуйте Это ответы не очень важны для StackOverflow, потому что они очень мало делают для обучения ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
7

Проведите цикл через JSON с помощью цикла foreach в качестве пар ключ-значение. Сделайте проверку типов, чтобы определить, нужно ли делать больше циклов.

foreach($json_a as $key => $value) {
    echo $key;
    if (gettype($value) == "object") {
        foreach ($value as $key => $value) {
          # and so on
        }
    }
}
  • 0
    Или, еще лучше, знать, что это за структура заранее.
3
<?php
$json = '{
    "response": {
        "data": [{"identifier": "Be Soft Drinker, Inc.", "entityName": "BusinessPartner"}],
        "status": 0,
        "totalRows": 83,
        "startRow": 0,
        "endRow": 82
    }
}';
$json = json_decode($json, true);
//echo '<pre>'; print_r($json); exit;
echo $json['response']['data'][0]['identifier'];
$json['response']['data'][0]['entityName']
echo $json['response']['status']; 
echo $json['response']['totalRows']; 
echo $json['response']['startRow']; 
echo $json['response']['endRow']; 

?>
  • 2
    Ответы только на код имеют низкую ценность в StackOverflow, потому что они очень мало делают для обучения ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
  • 0
    Вместо того, чтобы игнорировать примеры данных, предоставленных ФП, пожалуйста, попробуйте ответить на вопрос таким образом, чтобы он немедленно и напрямую имел отношение к опубликованному вопросу.
3

Попробуйте:

foreach ($json_a as $key => $value)
 {
   echo $key, ' : ';
   foreach($value as $v)
   {
       echo $v."  ";
   }
}
  • 0
    Попробуйте Это ответы не очень важны для StackOverflow, потому что они очень мало делают для обучения ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
1

Когда вы декодируете строку json, вы получите объект. а не массив. Таким образом, лучший способ увидеть структуру, которую вы получаете, - сделать var_dump декодирования. (этот var_dump может помочь вам понять структуру, в основном в сложных случаях).

<?php
     $json = file_get_contents('/home/michael/test.json');
     $json_a = json_decode($json);
     var_dump($json_a); // just to see the structure. It will help you for future cases
     echo "\n";
     foreach($json_a as $row){
         echo $row->status;
         echo "\n";
     }
?>
0

Из вашего опубликованного вопроса видно, что вас интересуют только status столбца status... независимо от ключей (имен) первого уровня.

PHP имеет специальную функцию для изоляции столбца данных в массиве.

Код: (Демо)

$json = '{
    "John": {
        "status":"Wait"
    },
    "Jennifer": {
        "status":"Active"
    },
    "James": {
        "status":"Active",
        "age":56,
        "count":10,
        "progress":0.0029857,
        "bad":0
    }
}';

var_export(array_column(json_decode($json, true), 'status'));

Выход:

array (
  0 => 'Wait',
  1 => 'Active',
  2 => 'Active',
)
0

Самый быстрый способ повторить все значения json - использовать цикл в цикле, первый цикл должен получить все объекты, а второй - значения...

foreach($data as $object) {

        foreach($object as $value) {

            echo $value;

        }

    }
0
$json_a = json_decode($string, TRUE);
$json_o = json_decode($string);



foreach($json_a as $person => $value)
{
    foreach($value as $key => $personal)
    {
        echo $person. " with ".$key . " is ".$personal;
        echo "<br>";
    }

}
  • 4
    Привет, это вполне может решить проблему ... но было бы хорошо, если бы вы могли отредактировать свой ответ и дать немного больше объяснений о том, как и почему он работает :) Не забывайте - на переполнении стека есть куча новичков и они могли бы узнать что-то одно или два из вашего опыта - то, что для вас очевидно, может быть не так для них.
0

Вы должны сделать так:

echo  $json_a['John']['status']; 

echo "<>"

echo  $json_a['Jennifer']['status'];

br inside <>

Что дает результат:

wait
active
  • 0
    Do Like This ответы на StackOverflow не имеют большого значения, потому что они очень мало помогают в обучении ОП и будущих исследователей. Если вы собираетесь оставить этот ответ на странице, пожалуйста, объясните, как работает ваш ответ и почему это целесообразно.
  • 0
    Этот ответ, кажется, неправильно понимает вопрос. OP заранее не знает ключей «name», поэтому их нельзя жестко закодировать. Этот ответ неверен.
-1

Я использую приведенный ниже код для преобразования 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) );
?>
  • 0
    empty() - ненужные накладные расходы. Просто используйте !json_last_error() . Кроме того, это не дает ответа на вопрос, заданный ФП. Это не «Как приводить значения в виде массивов», а не «Как проверять наличие ошибок JSON». Я отмечаю этот пост как Не Ответ.
  • 0
    Но никто не рассмотрел вопрос о том, что если json сформирован неверно, поэтому недостаточно только json_decode (), следует также проверять действительный json, это ваш думающий человек, помеченный, если вы хотите, я здесь не для того, чтобы зарабатывать баллы, как для разработчика. решения недостаточно, плюсы и минусы тоже,
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню