2

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

4
  • when in doubt, use print_r, ex : $train = json_decode($line,true); echo '<br>' . print_r($train, true) . '<br>'; Commented Aug 30, 2013 at 21:26
  • There's no variable $json_train, the name of the variable is $train. Commented Aug 30, 2013 at 21:34
  • The nulls aren't pushing anything down, they're just printing empty lines for those values. That's how echo and print_r print null and false values, they're printed as empty strings. Use var_dump so you can always see the values. Commented Aug 30, 2013 at 23:12
  • Thanks for your help on this Barmar. With your help I can now pull through individual values. Thanks again Commented Aug 31, 2013 at 9:20

2 Answers 2

2

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>";
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Barmar and OnetoOne. Very helpful. I have put a further edit up. Definitely moving forward. Just had a further query above. Thanks again
0

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
}

1 Comment

That's useful Raymond. How do I call upon it in the script?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.