PHP Only Returning Last JSON Object - php

I'm attempting to do something I've done many times before (access objects in a JSON file with PHP) and for some reason json_decode is only returning the last item in the JSON array. Here's the JSON:
{
"person": {
"lname": "smith",
"fname": "bob"
},
"person": {
"lname": "jones",
"fname": "jane"
}
}
And the PHP:
<?php
//access and dump
$json = file_get_contents('people.json');
$filey = json_decode($json, true);
var_dump($filey);
?>
The result is only the last item in the array:
array (size=1)
'person' =>
array (size=2)
'lname' => string 'jones' (length=5)
'fname' => string 'jane' (length=4)
Using json_last_error returns no errors and I'm valid according to jsonlint. I'm also not finding any console errors when I load the page.
I'm totally stumped and can't see anything different from the times I've done this before - can anyone identify what I'm missing here?

That's because your json object names "person" within json array are similar so json decode will override the values with latest.
Consider something like
{
"person1": {
"lname": "smith",
"fname": "bob"
},
"person2": {
"lname": "jones",
"fname": "jane"
}
}
and your code will work fine.

Marcatectura, I know you've already accepted the answer that suggests using different object keys but I thought you should know. If you want an array in PHP, You don't even need object names. The following JSON will do:
[
{
"lname": "Dawes",
"fname": "April"
},
{
"lname": "Colin",
"fname": "Dick"
}
]
A trick I use when I'm designing my JSON is to build a sample PHP array in the shape I want json_decode to give me, encode that array and output the result to screen. So what I posted above is the result of:
$arr = [
['lname'=>'Dawes','fname'=>'April'],['lname'=>'Colin','fname'=>'Dick'],
];
$json = json_encode($arr);
echo $json;
Since I built a JSON by encoding an array having the shape I want, I can be confident that even as my data change, json_decode($json,true) will give me the array shape I expect.
Happy coding.

When you use json_decode(true), your json is now an array.
You cannot have two array keys that are the same, in this case "person".
If you still want to use json_decode(true), then change "person" to "person1" or so.
Try both var_dump($filey) and var_dump($json), you will see what I'm talking about.

Related

JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 50 of the JSON data

when i use....
var jsonData = JSON.parse(xhttp.responseText);
i get an error => "JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 50 of the JSON data"
this is my JSON data from a php script
{"results":[{"oldID":5,"oldMain":"News papers"}]}{"results":[{"oldID":3,"oldMain":"Construction"}]}{"results":[{"oldID":2,"oldMain":"Banking Files"}]}{"results":[{"oldID":1,"oldMain":"Technologies"}]}
Can some please help?.... Thanks
A little bit late to the party, but #igniz87 and #Benjamin James Kippax's answers open your website to security issues, and it is so dangerous to follow their example.
As Owasp reads,
ALWAYS RETURN JSON WITH AN OBJECT ON THE OUTSIDE
Hence, so as to be a layer protected from the barbarism of hackers, you need to ALWAYS have the outside primitive be an object for JSON strings. As you can clearly see, the mentioned people's answers do not follow this crucial security rule.
Owasp, moreover, brings an example and says that a JSON like the following is EXPLOITABLE:
[{"object": "inside an array"}]
Yet, the following JSONs are not,
{"object": "not inside an array"}
{"result": [{"object": "inside an array"}]}
You need to remove the duplicate key element and change it in the following way so you will have an object on the outside.
{
"results": [{
"oldID": 5,
"oldMain": "News papers"
}],
"resultss": [{
"oldID": 3,
"oldMain": "Construction"
}]}
Here, actually you should have brought you php code, as the problem is with that php code which is sending the JSON. When you want to send the JSON try to make an array of your data. I do the following way.
$data = [];
foreach ($results as $res) {
$t = [];
$t['oldID'] = $res['oldID'];
$t['oldMain'] = $res['oldMain'];
$data[] = $t;
}
echo json_encode(['results' => $data]);
You'd better send your php code which is lacking here. My php script does not contain all of your code, but it gives you idea how to do it.
I have had the same problem for the past several years.
Sometimes the problem is not related to invalid JSON .. like me now.. the problem is that I must use stringify before JSON.parse
var db = JSON.stringify(data);
var db = JSON.parse(db);
And sometimes in php you must use json_encode($data) correctly.
And sometimes your JSON is not valid ( Online JSON Validator )
The JSON is not valid. If it is possible, you can update the JSON as following
{
"results": [{
"oldID": 5,
"oldMain": "News papers"
}],
"resultss": [{
"oldID": 3,
"oldMain": "Construction"
}]}
And also JSON should not contain duplicate key elements. Also you can club the JSON to JSONArray like this
[{
"results": [{
"oldID": 5,
"oldMain": "News papers"
}]
},
{
"results": [{
"oldID": 3,
"oldMain": "Construction"
}]
}]
it's not a valid json, you must wrap it in array. the valid json is like this
[{
"results": [{
"oldID": 5,
"oldMain": "News papers"
}]
}, {
"results": [{
"oldID": 3,
"oldMain": "Construction"
}]
}, {
"results": [{
"oldID": 2,
"oldMain": "Banking Files"
}]
}, {
"results": [{
"oldID": 1,
"oldMain": "Technologies"
}]
}]
take a look at the bracket [ ] at the start and the end of string , and the , to split the object.
this some online json linter here to check if your json is valid.
Your code is invalid.
Your code;
{"results":[{"oldID":5,"oldMain":"News papers"}]}{"results":[{"oldID":3,"oldMain":"Construction"}]}{"results":[{"oldID":2,"oldMain":"Banking Files"}]}{"results":[{"oldID":1,"oldMain":"Technologies"}]}
Your code validated;
[{"results":[{"oldID":5,"oldMain":"News papers"}]},
{"results":[{"oldID":3,"oldMain":"Construction"}]},
{"results":[{"oldID":2,"oldMain":"Banking Files"}]},
{"results":[{"oldID":1,"oldMain":"Technologies"}]}]
The problem is that you had multiple JSON root elements. These also weren't comma separated. They also need wrapping in [], which will turn it into an object. If you don't want to wrap your response in [], you can return the string without the [] and instead do this;
JSON.parse('['+yourreponse+']') which will parse the JSON correctly.
Above answer are correct i.e. your json syntax is incorrect. Correcting your syntax would solved the problem (as suggested)
My case was a little different. I was returning json in response to ajax calls. Those jsons where returned by php using a if else construct. Where I mistakenly omitted one else;
if (!empty($_GET['arg1']))
echo getTrainings($filter, 'arg1');
elseif (!empty($_GET['arg2']))
echo getTrainings($filter, 'arg2');
if (empty($_GET['arg3']))
echo getTrainings($filter, 'arg3');
elseif (empty($_GET['arg4']))
echo getTrainings($filter, 'arg4');
So in fact two json where being returned instead of one, that caused problem for $.parseJSON(result);
var par = $.parseJSON(result);

Pass Form PHP Variables to JSON Encode

I have a form with these values:
$firstName = strip_tags(trim($_POST['first-name']));
$lastName = strip_tags(trim($_POST['last-name']));
$email = filter_var(trim($_POST['user-email']),FILTER_SANITIZE_EMAIL);
I'm trying to pass these values onto this:
$request_body = json_decode('[{
"first_name" : "Tom",
"last_name" : "Hanks",
"email" : "example#gmail.com"
}]');
Tried saving the form values to an array and passing it into json_decode where $userArray are the form values, but not go. Example:
$request_body = json_decode($userArray, true);
All of this is to pass these form values into an API (SendGrid), but it's just not working for me and their documentation is not very descriptive. I guess they want a specific request format. Here's an example of their request body from their Github page. I can have these values hard coded in and it works fine, but the idea is for the form to pass in these user name and email values automatically.
$request_body = json_decode('[
{
"age": 25,
"email": "example#example.com",
"first_name": "",
"last_name": "User"
},
{
"age": 25,
"email": "example2#example.com",
"first_name": "Example",
"last_name": "User"
}
]');
Any ideas what I'm doing wrong? Thanks!
The way you sent your post :
$array[0]['email'] = filter_var(trim($_POST['user-email']),FILTER_SANITIZE_EMAIL);
$array[0]['first_name'] = strip_tags(trim($_POST['first-name']));
$array[0]['last_name'] = strip_tags(trim($_POST['last-name']));
echo json_encode($array);
Result :
[{"email":"john.doe#exemple.com","first_name":"John","last_name":"Doe"}]
The [0] might have been an issue, it produce the "[" "]" when you read the json_decode output and reproduce the exact same array when decoded with json_decode.
So if their script is looking for integers as keys, if you omit the [0], they will get an array in the following format $array['email'] etc. This might be an issue.
If you would like to reproduce that in a loop and send multiple entries at once
you could write it this way instead :
$array[] = array('email' => filter_var(trim($_POST['user-email']),FILTER_SANITIZE_EMAIL),
'first_name' => strip_tags(trim($_POST['first-name'])),
'last_name' => strip_tags(trim($_POST['last-name']))
);
You will still be missing the "age". Make sure it is not a mandatory field!
I think you might be getting a little confused while using json_decode() and json_encode().
json_encode() encodes a PHP array into a JSON array.
Whereas json_decode() decodes a JSON array back into a PHP array.
In regards to your situation the following should produce the same output:
$array = array(
"first_name" => "Tom",
"last_name" => "Hanks",
"email" => "example#gmail.com"
);
echo json_encode($array);
Produces:
{"first_name":"Tom","last_name":"Hanks","email":"example#gmail.com"}
Using these functions to build the array then encode/decode to/from JSON is far better than manually creating the JSON array. As this avoids any syntax errors that you may create.
Hope this helps.

extracting json in php

From MySQL row, I have this json formatted data:
$row['details'] =
{
"previous_employer":[
{"employer":"string1","address":"address1"},
{"employer":"string2","address":"address2"},
{"employer":"string3","address":"address3"}],
"profile":[
"firstname":"John",
"lastname":"Adams",
"gender":"male",
"age":"35",
"contact":"123456789"]
}
I want to extract employer and address on the previous_employer array of objects,
but when I do this:
$json = json_decode($row['details'],true); //decode into array
foreach($json['previous_employer'] as $d){
echo "employer:".$d['employer']."<br>address:". $d['address']."<br>";
}
it gives me an error of
Warning: Invalid argument supplied for foreach()
How can I fix this? Pls advise.. thanks!
You JSON is invalid, "profile" must be
An Object:
"profile": {
"firstname": "John",
"lastname": "Adams",
"gender": "male",
"age": "35",
"contact": "123456789"
}
or an Array of Object (here his length == 1)
"profile": [{
"John",
"Adams",
"male",
"35",
"123456789"
}]
or a Simple Array (not associative array/map)
"profile": [
"John",
"Adams",
"male",
"35",
"123456789"
]
Now, your posted code will work as a charm without any modifications ... :)
json_decode() does not necessarily succeed (just imagine you feed it with complete garbage, why should it return something?). You need to do the following error checking:
Verify its return value:
Returns the value encoded in json in appropriate PHP type. Values
true, false and null are returned as TRUE, FALSE and NULL
respectively. NULL is returned if the json cannot be decoded or if the
encoded data is deeper than the recursion limit.
If valid data can be expected to return null some times, call json_last_error() and check whether it's JSON_ERROR_NONE.
Last but not least, you can explore any variable with var_dump(). You don't need to make assumptions about its content.

Accessing value inside multi-dimension JSON array using PHP

I read several posts on here and have been unable to find success in resolving the problem I am having.
I am trying to figure out how to get the NAME field from the UploadImage array.
I have the following JSON being passed to me from a Webhook.
{
"$version":5,
"Entry":{
"Number":"11",
"Order":null,
"Origin":
{
"City":"Portland",
"CountryCode":"US",
}
,
"Message":"the message",
"UploadImage":[
{
"ContentType":"image/png",
"Id":"F-lMbiCYdwiYS8ppkQS4gsyE",
"Name":"Screen.png",
"Size":55907
}
],
"Subject":"here is the subject"
}
I have no problem grabbing the value of Subject or Message, but I cannot figure out how to grab the NAME within UploadImage.
$contact = json_decode($json);
$subject=$contact->{'Subject'};
When I do
$uploadimage=$contact->{'UploadImage'};
it just writes out ARRAY.
I can do
echo $contact->{'Entry'}->{'Number'};
and it works, so it has to be something with the bracket being there before the curly bracket. I know this has to be something simple that I am missing.
Any help is GREATLY appreciated.
$uploadimage=$contact->{'UploadImage'}[0]->{'Name'};
Firstly try
$contact = json_decode($json, true);
Adding the second argument returns an array instead of an object which will make things easier. Objects with numerical keys are troublesome... Now you can,
print_r($contact);
to see exactly what you've got. I imagine that
echo $contact['UploadImage'][0]['Name'];
Will get you what you're looking for.
Notice that UploadImage contains an array of objects (or an array of arrays after conversion).
another solution is:
$contact = json_decode($text);
$name = '';
foreach($contact->UploadImage as $k=>$v){
foreach($v as $k2=>$v2){
echo $k2.' - '.$v2.'<br />';
if($k2=='Name'){ $name = $v2;}
}
};
var_dump($name);
//response
ContentType - image/png
Id - F-lMbiCYdwiYS8ppkQS4gsyE
Name - Screen.png
Size - 55907
//name
string 'Screen.png' (length=10)
Have you try to use like below:
$uploadimage=$contact->UploadImage[0]->Name;
In JSON the square braces [] mark an array section and the curly braces {} mark an object. In your JSON string UploadImage is an array, which contains a single object.
Try changing your JSON as follows:
{
"$version": 5,
"Entry": {
"Number": "11",
"Order": null,
"Origin": {
"City": "Portland",
"CountryCode": "US"
},
"Message": "the message",
"UploadImage": {
"ContentType": "image/png",
"Id": "F-lMbiCYdwiYS8ppkQS4gsyE",
"Name": "Screen.png",
"Size": 55907
},
"Subject": "here is the subject"
}
}

how to decode json sting including array and object in PHP?

I want to decode json string including array and object in PHP. When i decoded with
$array = json_decode($json, true);
print_r($array);
it return NULL. Let me know, the way to decode json in PHP. This is my json string.
{
success: 1,
message: "Successful!",
save_date: "2013-09-11 04:09:26",
test: [
{
test_id: "1",
test_date: "2013-09-12",
test_name: "Test 1"
},
{
test_id: "2",
test_date: "2013-09-11",
test_name: "Test 2"
}
]
}
That's not a valid JSON object. JSON objects must enclose all property names in double quotes:
{ "success": 1, "message": "Successful!" }
PHP provides the handy json_last_error_msg function to tell you that.
There's also the online tool JSONLint to validate JSON strings.
Your JSON is invalid, the property names need to be in quotes too.
Like this:
{
"success": 1,
"message": "Successful!",
"save_date": "2013-09-11 04:09:26",
"test": []
}
Hint: use JSONLint to validate your JSON.
your json string should be like the following :
$sJson = '{"success": 1,"message": "Successful!","save_date": "2013-09-11 04:09:26",
"test": [ {"test_id": "1","test_date": "2013-09-12","test_name": "Test 1"},
{"test_id": "2","test_date": "2013-09-11","test_name": "Test 2"}]}';
Use this
$result=(array)json_decode('your json string');
I think it's working for you

Categories