user2635961
user2635961

Reputation: 379

Decoding JSON in PHP

I am trying to decode a JSON file.

An extract of the JSON is shown below. To more accurately describe this JSON it is 3 X sets of JSON code. I am trying to extract the values associated with "main_train_uid" and "assoc_train_uid" eg G90491 and G90525 from the first row.

I have been trying to copy examples of code shown in various parts of stackoverflow but am failing

I realise this should be relatively easy but I just cannot get it. The output I am getting is Json decoding failed with error: 0. This would indicate nothing wrong but I am not getting the values out. I keep getting confused between arrays and objects. My code is shown after the JSON extract.

{"JsonAssociationV1":{"transaction_type":"Delete","main_train_uid":"G90491","assoc_train_uid":"G90525","assoc_start_date":"2013-09-07T00:00:00Z","location":"EDINBUR","base_location_suffix":null,"diagram_type":"T","CIF_stp_indicator":"O"}}
{"JsonAssociationV1":{"transaction_type":"Delete","main_train_uid":"P20328","assoc_train_uid":"P21318","assoc_start_date":"2013-08-23T00:00:00Z","location":"MARYLBN","base_location_suffix":null,"diagram_type":"T","CIF_stp_indicator":"C"}}
{"JsonAssociationV1":{"transaction_type":"Delete","main_train_uid":"L13077","assoc_train_uid":"L13045","assoc_start_date":"2013-08-23T00:00:00Z","location":"STPANCI","base_location_suffix":null,"diagram_type":"T","CIF_stp_indicator":"C"}}

The JSON snippet is stored in json.txt

<?php

$file = "json.txt";
$trains = file_get_contents($file);

foreach (explode("\n", $trains) as $line) {

  $train = json_decode($line,true);

  if (is_array($train)) {

    foreach($train as $item=>$value) {

      foreach($value as $entry) {
        echo $entry->main_train_uid;
        echo $entry->assoc_train_uid;

      }
    }   
  } 
}               


if (is_null($json_train)) {
  die("Json decoding failed with error: ". json_last_error());
}

?>

Thanks in anticipation John

EDIT

Thanks to Barmar

My new code is as below

<?php
$file = "json.txt";


$trains = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($trains as $train) {
$json=json_decode($train,true);

foreach($json as $item=>$value) {
print_r($item);
foreach($value as $entry) {
echo '<br>';
print_r($entry);


}
}   
}   



if (is_null($json)) {
die("Json decoding failed with error: ". json_last_error());
}

?>

I am now getting the following output (ie the values) with no errors which is great

JsonAssociationV1
Delete
G90491
G90525
2013-09-07T00:00:00Z
EDINBUR

T
OJsonAssociationV1
Delete
P20328
P21318
2013-08-23T00:00:00Z
MARYLBN

T
CJsonAssociationV1
Delete
L13077
L13045
2013-08-23T00:00:00Z
STPANCI

T
C 

However I still cannot single out certain individual values to echo on their own (I need to do that to put them into a database later) . So for example I still cannot get at just showing the values for main_train_uid

Also because one of the values is NULL it seems to be pushing certain values down into the next set of JSON. For example the T and C shown in the out put above

Any further help appreciated

Thanks

Upvotes: 2

Views: 321

Answers (2)

Raymond Nijland
Raymond Nijland

Reputation: 11602

because you get an error when decoding a json based message ive posted an way to throw an Exception when it happens so you can handle the error on a better way.

You could also extend the class so it can handle the encode also

class Json {

   public static function decode($jsonString, $returnArray = true) {  
       if ((string)$jsonString !== $jsonString) {  // faster !is_string check
          throw new Exception('input should be a string');
       }

       $decodedString = json_decode($jsonString, $returnArray)

       if ((unset)$decodedString === $decodedString) { // faster is_null check, why NULL check because json_decode return NULL with failure. 
           $errorArray = error_get_last(); // fetch last error this should be the error of the json decode or it could be a date timezone error if you didn't set it correctly   

           throw new Exception($errorArray['message']); 
       }
       return $decodedString;
   }
}



try {
   Json::decode("ERROR");
} catch (Exception $e) {  }

Just replace this line for example

$json=json_decode($train,true);

With this

try {
   Json::decode($train,true);
} catch (Exception $e) {
  // handle json decode exception here note if you don't try catch the code will terminate
  // here you can handle what you want want to do
}

Upvotes: 0

Barmar
Barmar

Reputation: 780673

Two problems that I see with this:

First, if the file ends with a newline, explode("\n", $trains) will return an array that ends with an empty string. When you call json_decode() on that element, it will return NULL with json_last_error() == 0. Try:

foreach (array_filter(explode("\n", $trains) as $train)) {
    ...
}

Or, instead of using file_get_contents(), you could use file():

$trains = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($trains as $train) {
    ...
}

Second, if (is_null($json_train)) is testing a variable that has never been set. The correct variable is $train.

To get a specific field out of the JSON, use $value['main_train_uid']

foreach ($trains as $train) {
    $json=json_decode($train,true);
    foreach ($json as $key => $value) {
        echo $key . "<br>" . $value['main_train_uid'] . "<br>";
    }
}

Upvotes: 2

Related Questions