Assume that I have below json response fetched from an API.
{
"owner": "Jane Doe",
"pets": [
{
"color": "white",
"type": "cat"
},
{
"color": "black",
"type": "dog"
}
]
}
From the below PHP code I have converted the json string into a json object. And displayed the pet types.
$jsonObject = json_decode($json);
foreach($jsonObject->pets as $pets){
echo 'Pet type:'.$pets->type.'</br>';
}
However in some cases the response json from the API is in below format
{
"owner": "John Doe",
"pets": {
"color": "white",
"type": "cat"
}
}
in this case above php foreach iteration fails with below message
*Notice: Trying to get property of non-object *
I'm looking for a easy way to do this because the actual json response which i'm handling has lot of these occurrences.
You need to check whether $jsonObject->pets is an array or object. If it's an object, replace it with an array containing that object, then the loop will work.
if (!is_array($jsonObject->pets)) {
$jsonObject->pets = array($jsonObject->pets);
}
You could also do it with a conditional in the foreach:
foreach (is_array($jsonObject->pets) ? $jsonObject->pets : [jsonObject->pets] as $pet) {
...
}
If you don't want to have to write all that every time, you could put it in a function:
function as_array($x) {
return is_array($x) ? $x : [x];
}
and then use:
foreach (as_array($jsonObject->pets) as $pet) {
...
}
I'd also complain to the API designer. It's ridiculous to return inconsistent data formats like this.
Related
I'm facing an error when trying to post JSON data into PHP. I am new at this.
any helps makes good for us
the JSON looks like this:
[
{
"sections": [
{
"section_id": "62",
"section_name": "English Language",
}
]
},
{
"questions": [
{
"section_id": "62",
"questionid": "1231",
},
{
"section_id": "62",
"questionid": "1232",
"time_spent": "0",
"status": "unseen",
"testsession_id": "whqgo41nsyurpi2"
},
{
"section_id": "62",
"questionid": "1233",
}
]
}
]
below is the code I wrote. Please correct the PHP code to access those JSON values.
$data = json_decode(file_get_contents("php://input"),true);
foreach ($data['sections'] as $value){
echo $value[section_id];
}
foreach ($data['questions'] as $value){
echo $value[section_id];
}
You are missing the array aspect of the JSON. The JSON is made up of an array firstly, which contains 2 objects, which have parameters of sections in the first, and questions in the second.
sections and questions are both arrays, which can be iterated over using foreach, which returns each of the elements as an object.
Your code after decoding the JSON should be like this.
foreach ($data[0]['sections'] as $value){
echo $value['section_id'];
}
foreach ($data[1]['questions'] as $value){
echo $value['section_id'];
}
I am working on a project that requires reading data from this terrible API that responds with terrible structured JSON data:
"finn-contanct": {...}
"finn-adata": {
"#attributes": {
"model": "https://cache.api.finn.no/iad/ad/model/car-used-sale"
},
"finn-field": [
{
"#attributes": {
"name": "authorized_dealership",
"value": "true"
}
},
{
"#attributes": {
"name": "body_type",
"value": "Stasjonsvogn"
}
},
{
"#attributes": {
"name": "car_location",
"value": "Norge"
}
},
{
"#attributes": {
"name": "engine"
},
"finn-field": [
{
"#attributes": {
"name": "effect",
"value": "90"
}
},
{
"#attributes": {
"name": "fuel",
"value": "Diesel"
}
}
]
},
{...},
]
}
How can i dynamically get the values under each attribute based on the siblings name value? Ideally with a function that accepts one parameter that finds the value in there by providing a key corresponding to the value i'm looking for.
Here is an example of what i'm expecting:
Given a function that expects one parameter: getAttrValue('key') I want to get the value under the #attributes sibling. So if I use the function like this: getAttrValue('body_type') i'm simply expecting this back: Stasjonsvogn. I don't really care about nested items. So if I do this: getAttrValue('fuel') I'm simply expecting: Diesel
I found this answer here on SO. But the problem with that method is that it doesn't work well with nested items. So does anyone have a method that would work with the data-structure I got above here?
The response is a total mess and I don't know how to handle it, nor how to Google it properly. So any help would be appreciated greatly.
Collect attributes into associative array recursively:
function collectAttributes($data)
{
$attributes = [];
$nodeAttribute = isset($data['#attributes']) ? $data['#attributes'] : [];
//collect current node attribute value
if (isset($nodeAttribute['name'])) {
$attributes[$nodeAttribute['name']] = isset($nodeAttribute['value']) ? $nodeAttribute['value'] : '';
}
//collect nested attributes recursively
foreach ($data as $nestedNode) {
if (is_array($nestedNode)) {
$attributes = array_merge($attributes, collectAttributes($nestedNode));
}
}
return $attributes;
}
And then use result as simple associative array:
$data = json_decode($inputJson, true);
$atttributes = collectAttributes($data);
echo $attributes['fuel']; //don't forget isset checking if you are not sure about content
But if you have attributes with same name you'll see only latest this way.
How can I decode a json database file that contains references to other json files using PHP? The goal is to get a single object with all references loaded.
Example of a json database file with references:
{
"id": 12,
"title": "Credit card number disclosure",
"severity": "medium",
"description": {
"$ref": "#/files/description/12"
},
"fix": {
"effort": 50,
"guidance": {
"$ref": "#/files/fix/57"
}
},
"cwe": [
"200"
],
"references": [
{
"url": "http://en.wikipedia.org/wiki/Luhn_algorithm",
"title": "Wikipedia - Luhn algorithm"
},
{
"url": "http://en.wikipedia.org/wiki/Bank_card_number",
"title": "Wikipedia - Bank card number"
}
]
}
file_get_contents() with a json_decode() will not automatically load the references.
<?PHP
$json_file = file_get_contents("db.json");
$json = json_decode($json_file);
function walkObject($obj) {
foreach($obj as $prop => $value) {
if (is_object($value))
$obj->$prop = walkObject($value);
if ($prop == "\$ref")
$obj->$prop = walkObject(json_decode(file_get_contents($value)));
}
return $obj;
}
This will load your initial json file, decode it and walk over it recursively. Every time it sees a $ref property - it will try to read the file it points to decode it and walk over it recursively...
You should implement checks for errors for file_get_contents and json_decode..
I have the following deocoded JSON array.
I need to access the "type" inside the context, as well as I need to loop through each of the values in the payload. How do I do that?
{
"RequestHeader":
{
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context" :
{
"type": "friends,circles"
}
"payload" [ {12345},{12345} ,{2345} ]
}
I tried the following, but it doesn't work
$decoded = json_decode($json_string);
for ($i=0;$i<payload.length;++$i)
{
$id=$decoded->payload[$i];
//do some operation with the id
}
First of all the JSON you provided is invalid. Supposedly the valid one should look like this
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
After you've fixed the problem with JSON provider it will be quite easy to access data
<?php
$json = <<<'JSON'
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
JSON;
$data = json_decode($json, true);
$type = $data['context']['type'];
var_dump($type);
foreach($data['payload'] as $id) {
var_dump($id);
}
Remember to make sure you check that the data actually exists before accessing it, e.g. isset($data['context']['type']) unless you are absolutely sure in it's integrity.
When you use json_decode method, the output will be nested arrays
So for example to access context type you need to do the following
echo $decoded["context"]["type"];
And to loop on payload you need to do the following
for ($i=0;$i<$decoded["payload"].length;++$i)
{
$id=$decoded["payload"][$i];
//do some operation with the id
}
i need to extract data from this array of objects
{
"data": [
{
"id": "136104923104306",
"from": {
"name": "GetWith.It",
"category": "Website",
"id": "136132969751208"
},
"message": "Do u know y **LOVE IS BLIND**\nbcoz..\n''ur mom started to love u before seeing ur face''....!",
"updated_time": "2010-10-05T13:41:42+0000",
"comments": {
"data": [
{
"id": "136104923104306_1075253",
"from": {
"name": "Hressence Ec",
"id": "1464305271"
},
"message": "this I would agree..love is surely blind..",
"created_time": "2010-10-12T01:40:47+0000",
}
]
}
}
My current code:
$data=json_decode(file_get_contents('https://myurl/where/this/data/is'));
foreach($data as $dts){
echo "$dts->message";
};
i need to extract the comments ..
and when i try
foreach($data->comments->data as $dts){
echo "$dts->message";
};
it returns null!
help please
Your $data is actually an object with a data property that is an array containing another object with the comments object you are looking for. So:
foreach ($data->data as $item) {
foreach ($item->comments->data as $comment) {
echo $comment->message;
}
}
I suggest you transform it into an associative array:
$data=json_decode(file_get_contents('https://myurl/where/this/data/is'), true);
and have a look at the structure.
I think your loop must look like this:
foreach($data['data'] as $dts) {
echo $dts['message'];
}
Update: Although I was able to fix the JSON (at least it seems to be good now) json_decode still returns null. No clue way. First make sure your JSON string is valid!