To JSON and json_decode in PHP and JavaScript - php

I'm trying to pass a JavaScript object to a PHP script through jquery.ajax(), basically:
var bigArray = new Object();
//Dode
//Start loop
bigArray[x] = {name: exname, id: exID, order:e, set: setBox, inc: incBox, example: exampleBox, day: i};
So it's pretty much an array of these objects.
var anotherTest = $.toJSON(bigArray);
var ajxFile = "routineajax.php";
$.ajax({
type: 'POST',
processData: false,
url: ajxFile,
data: anotherTest,
success: function(data) {
$('#result').html(data);
alert('Load was performed.');
}
});
});
The PHP side script
print_r($_POST);
$params = json_decode($_POST);
print_r($params)
The Ajax call is going through, and I can see in Firebug, but print_r($_POST) is returning an empty array. While if I change it to $_GET in both the $.ajax function and PHP script it works. My main problem is I'm getting this error message:
Warning: json_decode() expects parameter 1 to be string, array given in
How do I fix this problem?
After adding this snippet to the PHP file
$data = file_get_contents('php://input');
var_dump($data);
var_dump(json_decode($data));
I'm getting this output
string'{"0"{"name":"Decline`Abs","id":"54","order":0,"set":"","inc":"","example":"","day":1}}' (length=87)`
object(stdClass)[2]
public '0' =>
object(stdClass)[4]
public 'name' => string 'Decline Abs' (length=11)
public 'id' => string '54' (length=2)
public 'order' => int 0
public 'set' => string '' (length=0)
public 'inc' => string '' (length=0)
public 'example' => string '' (length=0)
public 'day' => int 1
So at least it's going through, I'm not sure how to access it though, a step in the right direction!

I think the problem is that normally POST data is sent encoded as key=value&key2=value2, and you're sending it as JSON. Try accessing the raw post data as follows:
$data = file_get_contents('php://input');
var_dump($data);
var_dump(json_decode($data));
and see if that works. If not, please post in your question what it returns, if anything.
Based on the comment below and additions to the OP.
Did the var_dump of $data copy-paste correctly? The reason I ask is that this: string'{"0"{"name" does not look right to me. That isn't valid JSON or a properly encoded POST string. It might be that some of the characters got encoded when you copied and pasted.
Either way, you're now getting the result you need. The stdClass is just a blank container that it puts the data into, which you can access using the normal object syntax. In this case, you'd have to do $data->{0}->name I think, because of that 0. If you do $data = json_decode($data, true) it will be an associative array, and you can access the POST'ed data as $data[0]['name'].
If you want to keep exploring this, it might be helpful to show the results of doing window.console.dir(data) right before you do the ajax request, and make sure when you var_dump(data), you view the source of the page to copy and paste. window.console.dir(data) will show data's properties in the Firebug window (you are using Firebug, right?). It also works in Chrome's debugger, and maybe others as well. Like I said though, it looks like you're probably getting what you need already, so investigating isn't necessary.

Turn processData to true. I don't believe your JSON is being passed through correctly. Also note that it won't come through as a json, but rather the key value pairs of your JSON will be the contents of $_POST when you get to it.
Also, are the values of your bigArray easily convertable to string? If you're passing in DOM elements or something, you're going to have issues.

Isn't it clear enough? json_decode() expects parameter one to be string, not array. But $_POST and $_GET are always arrays. You can pass a member of this array to json_decode().
To see an array's contents, use this snippet:
echo "<pre>";
print_r($_GET);
echo "</pre>";

Related

angularJS - POST array after JSON.stringify()

I want to POST 3 parameters to my PHP web service. One of which is an array, so I used JSON.stringify() first and then added it as the parameter. The problem is, PHP isn't receiving the stringify'ed parameter.
My array is created by fetching IDs of each element in an object.
Converting it into a string:
var cid = JSON.stringify(cids);
Output as in the console for cid:
["1","2","3"]
And my $http.post call:
var dataObj = {
wid: wid,
type: type,
cid: cid
};
$http.post("my.php", dataObj);
From what I understand, the array gets converted into a string, which must get POSTed alike other strings, but when I echo back $_POST['cid'], it turns out to be blank; while the wid & type are proper.
From my understanding all post data is converted to JSON anyway. Manually changing your array to JSON and including is just the same as:
$http.post("my.php", {
wid: wid,
type: type,
cid: [1, 2, 3]
}
At the other side of the connection the JSON is converted back to objects(arrays) if possible. PHP doesn't print anything because arrays aren't converted to strings that well. Although you should expect the string 'array'. Try echo'ing $_POST['cid'][0]
EDIT:
As stated in the comments and this post the following code is required to get PHP and AngularJS to play together:
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);

Cannot json_decode a GET parameter

All,
I'm trying to pass a stringified json object as a GET parameter but the receiving URL seems unable to decode it, I am not sure why.
Here is the relevant code:
Client side Json object production (works fine):
function createJson(){
// This works fine. It creates a json objects with three elements, the third being an array.
//(omitted code for brevity)
return jsonData;
}
Client side ajax call (works fine):
function recordSetGet(jsonData){
request = createRequest();
var rawSet=JSON.stringify(jsonData);
var encodedSet=encodeURIComponent(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
request.open("GET", url, true);
request.onreadystatechange = function(){}
request.send(null);
}
This yield the following URL: Ajax_recordSetGet.php?set=%7B%22setTitle%22%3A%22test%22%2C%22setTags%22%3A%22test%20%22%2C%22set%22%3A%5B%7B%22first%22%3A%22Joe%22%2C%22last%22%3A%22Doe%22%2C%22checked%22%3Atrue%7D%5D%7D"
Server side treatment:
<?php
header('Content-Type:text/html; charset=UTF-8');
if(!session_id()){
session_start();
}
if(isset($_GET['set'])){
$set=$_GET['set'];//This is the URI encoded string
var_dump ($set);
var_dump (json_decode($set));
var_dump ("Json last error is ".json_last_error());
}
?>
The result of the var_dumps are:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)
So why is json_decode() failing here? The json_last_error() result suggests a syntax error.
Edit: Note that json_decode also fails if I send a non encoded string:
If I build the param string without encoding it like this:
var rawSet=JSON.stringify(jsonData);
var params="set="+rawSet;
var url= "Ajax_recordSetGet.php?"+params;
Then the URL becomes Ajax_recordSetGet.php?set={"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"
And the receiving URL var_dump yield the same error:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)
I don't know why, but you have a trailing double quote in your URL that messes up the JSON decode process.
...%7D%5D%7D" <- Trailing double quote
This quote also shows up in your dump of the set variable:
...true}]}"' (length=90) <- double quote is inside the string, the single quote is part of the var_dump output.
This double quote must be introduced in the Javascript code, although I cannot see a spot where that should happen. But your debugging should take place in that part of the system.
Note that you MUST NOT urldecode the string passed as the "set" parameter, as PHP has done the decoding for you already. But with the trailing double quote you cannot call json_decode().
As a quick proof of concept, try using $set = rtrim($set, '"') in your PHP code before decoding to remove that quote character.
http://php.net/manual/en/function.urldecode.php
The superglobals $_GET and $_REQUEST are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results.
Try a different way. I suggest base64-encoding the json string.
Instead of this:
var rawSet=JSON.stringify(jsonData);
var encodedSet=encodeURIComponent(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
do this:
var rawSet=JSON.stringify(jsonData);
var encodedSet=btoa(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
But pay attention to the caveats!
And in your serverside:
$decodedSet=json_decode(base64_decode($set));

AS3, PHP & JSON - Decoding one object is fine, an array returns null

I've been hunting around for a few hours and I still have no idea what's going on. I'm new to PHP, but fairly comfortable with simple Flash stuff.
I'm passing a JSON object from PHP into Flash AS3 using URLLoaders, etc. This is my PHP-created test JSON array:
$objJSON = array('sample' => null);
$objJSON['sample'] = "TESTING";
$objJSON['sample2'] = "TESTING2";
$objJSON = json_encode($objJSON);
I return it to flash with
echo "arrayData=$jsonArray";
When I parse that as a SINGLE object in flash, using
var tempJSON = JSON.decode(event.target.data.arrayData);
I get 'TESTING' as my output (textBox.text = tempJSON.sample; using localhost via WAMP), which is correct. Everything looks good, there's communication, the JSON library is being used right, the object is there and accessible...
BUT! When I treat it as an Array (because that's what it is) by changing the code directly above (and touching NOTHING else) to:
var tempJSON:Array = JSON.decode(event.target.data.arrayData, true);
I throw a compiler error of:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.adobe.serialization.json::JSONTokenizer/nextChar()[....\json\JSONTokenizer.as:545]
Running the swf in localhost gets me no return where I used to get string. Am I making some newbie mistake that the data suddenly becomes null when I treat it like an array?
I've checked the validity of my JSON via the output in PHP and it checks out. I've made sure I have no extra echos in the PHP class being called. I'm just stumped.
FIX'D!
Guided by the comments, I basically wasn't forming my JSON to be an array, just objects with multiple properties. The correct way to do it was:
$objArray = array(
array(
"sample1" => "Testing!",
"sample2" => "Testing2!",
),
array (
"sample1" => "Testing!",
"sample2" => "Testing2!",
)
);
$objArray = json_encode($objArray);
I believe it is because your JSON is decoding into an object and not an array. This will happen if you are using non-integer values as your array keys (ie. 'sample', 'sample2').
I'm not overly familiar with AS3, but you will likely need to cast it into an Object-like instance instead of an Array.
$objJSON = array('sample' => "TESTING", 'sample2' => "TESTING2");
echo json_encode($objJSON);
// Will output
{ "sample": "TESTING", "sample2": "TESTING2" }
This is not array notation using JSON. It is object notation.
I hope this helps!

Accept JSON from backbone.js Sync in PHP

I am implementing Backbone.js, and I am just trying to understand how the sync function works.
To keep it very simple, here is the model.
var Item = Backbone.Model.extend({
defaults: {
name: "Goo"
},
url: "commlink.php"
});
and then
Backbone.sync("create", item);
This is my commlink.php
$item=json_decode($_POST);
$name=$item->name;
$results=$mdb2->query("INSERT INTO list VALUES (NULL, '$name')");
I see a new row show up in my DB, however, the field "name" is blank.
I tried both item.save() and the above method...both ended up with the same blank cell but a new entry.
This is the error in chrome in network/content:
<b>Warning</b>: json_decode() expects parameter 1 to be string, array given in ...XXX...
This is in the request payload:
{"name":"Goo"}
$rawJSONString = file_get_contents('php://input');
$item = json_decode($wrapperString);
//$item->name is the data you want
$item = json_decode(file_get_contents('php://input'), true);
print_R($item);
Found this is more helpful
https://coderwall.com/p/vwvy_a
SECURITY NOTE: as pointed out in the comment this is not the way you should ACTUALLY insert the user provided content into your database, this is simply to show you how to get access to the array information as JSON, you should use prepared statements, a framework database adapter, or some other appropriate solution for escaping the user provided content before sticking it into the database.
You're trying to run an array ($_POST) through a function (json_decode) that only accepts a string. The solution in this specific example would be to do this:
$results=$mdb2->query("INSERT INTO list VALUES (NULL, '{$_POST['name']}')");
This would work because you're accessing $_POST as the associative array that it is.
However what I think you actually want to do is first convert the $_POST array to json, then decode it so you can use it the way you wanted to (accessing it as an object, which the json_decode returns):
$item=json_encode($_POST);
$item=json_decode($item);
$name=$item->name;
$results=$mdb2->query("INSERT INTO list VALUES (NULL, '$name')");
For reference:
http://php.net/manual/en/function.json-decode.php
http://php.net/manual/en/function.json-encode.php

javascript array to php

i want to send a javascript array to php using jquery ajax.
$.post("controllers/ajaxcalls/users.php",
{
links: links
});
where the second 'links' is a javascript array.
when i've got this array:
'1' ...
'1' => "comment1"
'2' => "link1"
'3' => "link2"
'4' => "link3"
'2' ...
'1' => "comment2"
'2' => "link4"
then using:
var jsonLinks = JSON.stringify(links);
alert(jsonLinks);
will give me:
[null,[null,"comment1","link1","link2","link3"],[null,"comment2","link4"]]
seems to me that something is wrong. what are the null:s and i cant use json_decode on php side to get the elements.
what function should i use to convert it to json and how do i access it on the php side?
tried this http://code.google.com/p/jquery-json/ but it will give exactly the same output as JSON.stringify() (they also say that in the documentation).
have struggled with this in some hours now...would appreciate some SPECIFIC help.
i just want to send an array from javascript to php...why is that so damn difficult:/
Answering the null part, JavaScript arrays are numeric and zero based:
>>> var foo = [];
>>> foo[5] = 'Five';
"Five"
>>> foo
[undefined, undefined, undefined, undefined, undefined, "Five"]
On the contrary, PHP allows missing (and mixed) keys:
<?php
$foo = array();
$foo[5] = 'Five';
print_r($foo);
?>
Array
(
[5] => Five
)
If you want to use arrays, I suggest you make them zero-based and prevent missing values. Otherwise, you could probably use objects instead.
There are some jQuery plugin that can encode to JSON (and decode from JSON).
For instance, you can take a look at jquery-json (quoting) :
This plugin exposes four new functions
onto the $, or jQuery object:
toJSON: Serializes a javascript object, number, string, or arry into
JSON.
evalJSON: Converts from JSON to Javascript, quickly, and is trivial.
secureEvalJSON: Converts from JSON to Javascript, but does so while
checking to see if the source is
actually JSON, and not with other
Javascript statements thrown in.
quoteString: Places quotes around a string, and inteligently escapes any
quote, backslash, or control
characters.
I'm not sure how you are trying to read this in your PHP script, but if it is related to you having 1-based arrays rather than 0-based arrays, then in javascript, you can remove the nulls (zeroth element) with:
var jsonLinks = JSON.stringify(links.slice(1));

Categories