Reading JSON returns empty

Asked

Viewed 244 times

2

I am reading a JSON from a URL, as code below:

$link1 = file_get_contents('http://gwmestampas.com.br/arquivo.json');

$obj = json_decode($link1);
echo $obj->event;
echo $obj["event"];


 foreach($obj as $link){
    $event = $link->event;
    $event2 = $link["event"];
    //$numOrd =  $link->resource->payment->_links->order->title;
    //$tipoPag =  $link->resource->payment->events->type;
    //$numPag =  $link->resource->payment->id;        
}; 

echo $event.'-<br>';
echo $event2.'-<br>';
echo $numOrd.'-<br>';
echo $tipoPag.'-<br>';
echo $numPag.'-<br>';

I tried several ways but always returns empty.

  • foreach($obj as $link){ the returned json is not an array that you can face make a foreach, came to study the return json? could simply read the direct Node, thus: $obj->event

  • don’t know I didn’t understand or you, but in the code above I try to do the direct reading, but it does not return anything and if I try to do the reading inside the foreach also returns empty.

  • even $link1 is empty?

  • if it is, it may be that the file_get_contents cannot read the url as if it were a file, so you need to enable it before the command: ini_set("allow_url_fopen", true);. Do a test, if it works I can explain it better in a reply

  • $link1 receives normal data from $link1 = file_get_contents(.... but after that it doesn’t go ahead, after $obj = json_decode($link1); for example using only echo $obj->Event; you should at least show something knowing that the structure is the following { "date": "", "env": "", "Event": "ORDER.CREATED", and so on and so forth.

  • taking the result of the url and validating the json here: https://jsonlint.com/ and here https://jsonformatter.curiousconcept.com/ claims it is invalid, this may be the problem

  • I receive this content from Wirecard, I will contact them, but I believe it will not solve, but we will try. Thank you

Show 2 more comments

1 answer

4


The returned JSON is invalid. It has multiple "loose" objects, one followed by the other:

{"date":"","env":"" ... }{"date":"","env":"", ... } 

Note that after the first object is closed with }, another object with {. This is not a valid JSON.

The correct thing would be for these objects to be inside some other structure, like an array, for example:

[ {"date":"","env":"" ... }, {"date":"","env":"", ... }, ... ]

That would be a valid JSON. In the example above, we have an array: it is delimited by [] and there are commas separating the elements.

Ideally, the URL should return a JSON in the correct format. If you have no control over the URL you are accessing, the only way is to manually manipulate the string.


Attention: the code below has been made specifically for the JSON in question. The premise is assumed that JSON always comes like this: objects always start with {"date": and there are no spaces between them. If there is the slightest change in format, it no longer works (so ideally the URL should return a valid JSON).

The idea is to transform this string, which contains objects in sequence, into an array. For this we need to put [ at first, ] at the end and a comma between the objects:

$link1 = file_get_contents('http://gwmestampas.com.br/arquivo.json');
$obj = json_decode('['. preg_replace('/((?<!^)\{"date":)/', ',$1', $link1). ']', true);

Regular expression takes string {"date": (provided it is not at the beginning) and puts a comma before it. I also put the [ and ] and pass on the result to json_decode.

Thus, $obj will have all objects, simply iterate by the same:

foreach ($obj as $link) {
    echo $link['event'];
    if (array_key_exists('payment', $link['resource'])) // nem todo resource tem payment
        echo ', '. $link['resource']['payment']['_links']['order']['title'];
    echo PHP_EOL;
}

From what I’ve seen, resouce may or may not have payment or other fields, but then just go testing if they exist before accessing them.


Remembering again that this is a limited solution. If the string changes (for example, it returns an object that does not start with {"date":, or any other change that no longer matches our premises), it no longer works. If you have any property date inside another internal object, the regex will insert a comma where it should not (luckily it does not, which is why it works in this case). Of course, depending on the change, simply change the regex, but using regex to manipulate JSON is not ideal.

The ideal is that the service returns a valid JSON, so you don’t have to keep doing these tricks to fix the string.

  • 1

    is what I said, this json is poorly formed. this Regex was top to fix :D

  • 1

    Thank you very much for the Answer, I understand that it is not the best option, but I receive so and because it is from an external service, I will implement this code and make a test to see if it is functional due to any changes, and as Ricardo commented was top even the regex

  • @Fabiojonaszech Yeah, if it’s from an outside service and they can’t fix it, then the way is to keep adjusting the regex every time you change something (or hope not to ever change) :-)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.