1

I am trying to post a dictionary using ajax. But I have run into some problems with json and "]" character.

Here's example of my code (javascript):

var dict = {"id":"patient","where":{"name[~]":"J"}};
$.post("./ajax.php",{data:dict},function(data){
});

And ajax.php (this file just deals with the json encoded data in $_POST array):

$where = $_POST["data"]["where"];

Basically i am trying to send json format message to php, and there I want to process with the data.

I tried whole bunch of combination with json_encode and decode on php side, also JSON.stringify() on javascript side, tried to use escape characters with the right bracket.

But when I dump $_POST["data]["where] there's value "J" with key "name[~" and not "name[~]". Right bracket disappears from the key.

Anyone having any advice, please? Thanks for help, I've been struggling with this for hours...

//EDIT: I've figured out, that everything i place after "]" disappears from the key. So the key transforms from "name[~]asdf" -> "name[~"...

Honzys
  • 45
  • 2
  • 6
  • The way you are trying to send the data, you will always see a key value result, I suggest you change your approach to something like `var dict = {"id":"patient","where":"name[~]:J"}};` and then on server side `explode(':', $_POST["data"]["where"]);` – codtex Nov 23 '16 at 23:05
  • @sand Thanks for the response. That's a good idea, but what if I want to send a ":" character as a value? Or more of them? The delimiter : won't work if there's ":" as a value. example `{"where":"name[~]:Jmkl:"}` - This will cuase an error with this approach. I am thinking about the most general way to do this. – Honzys Nov 23 '16 at 23:11
  • @sand This does not help finding the reason, just erases the question. The OP is onto something. I have tested this code with different variations and the OP is right. – Tala Nov 23 '16 at 23:12

3 Answers3

1

When you provide an object to the jQuery AJAX functions, it URL-encodes it. jQuery is sending the data.where parameter as:

data[where][name[~]]=J

and PHP apparently can't deal with nested brackets like that; it just matches the [ before name with the next ].

Probably jQuery needs to double-encode this property name to protect it, but obviously it doesn't.

The workaround is to encode dict as JSON, and decode it in PHP. JS:

$.post("./ajax.php",{data: JSON.stringify(dict)},function(data){

PHP:

$data = json_decode($_POST['data'], true);
$where = $data['where'];
var_dump($where);
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks for answer. But still, I can't make it work, I've allready tried this before posting the problem. The output of json_decode is null string/"". But $_POST["data"] exists. I don't know what I've done wrong. – Honzys Nov 23 '16 at 23:50
  • I just tried it and it works. See http://dev.bridgebase.com/barmar_test/test1.html – Barmar Nov 23 '16 at 23:59
  • Okay, I see, then there have to be problem elsewhere. Because when I run your code I get NULL from var_dump(). Maybe different version of php? Because input for the json_decode is correct, but the function returns NULL. I am using php version 5.6.25. – Honzys Nov 24 '16 at 00:04
  • Are there any Unicode characters in your data? Maybe that causes additional problems. I simply copied and pasted your `var dict` line. – Barmar Nov 24 '16 at 00:07
  • Nope, i am using the same dict as you. it returns `4` according to manual it is `JSON_ERROR_SYNTAX`. – Honzys Nov 24 '16 at 00:19
  • The only difference is that I'm using PHP 5.4 instead of 5.6, but I can't imagine why that would break it. – Barmar Nov 24 '16 at 00:21
  • I've found the problem Thank's for the direction with json_last_error(). The problem is solved with stripslashes(); I've marked your solution as "accepted". Can you please edit the first line to `$data = json_decode(stripslashes($_POST['data'], true));` ? For other people struggling with the same problem ? – Honzys Nov 24 '16 at 00:29
  • I don't know why that would be necessary, nothing adds slashes. This would have been a problem with old versions and `magic_quotes_gpc`, but that went away in 5.3 I think. – Barmar Nov 24 '16 at 00:31
  • Maybe there's some setting in your webserver that's adding slashes? – Barmar Nov 24 '16 at 00:32
  • That's possible, but according to this thread [link](http://stackoverflow.com/questions/17219916/json-decode-returns-json-error-syntax-but-online-formatter-says-the-json-is-ok) I am not the only one having this problems :). – Honzys Nov 24 '16 at 00:35
  • That question is very old, `magic_quotes_gpc` was pretty common then. – Barmar Nov 24 '16 at 00:37
  • I don't want to add it to my answer because it can do damage if the server isn't adding extra slashes in the first place. You really should fix whatever is doing that, not working around it in PHP. – Barmar Nov 24 '16 at 00:38
0

I have tried JSON.stringify in junction with json_decode and the result looks fine:

JS

$.ajax({
        url: './ajax.php',
        method: 'post',
        data: "data="+JSON.stringify(dict)
    });

PHP

json_decode($_POST['data'], true);

I think you should have specified the JSON is associative, setting $assoc parameter to true. See this.

You can also send data as a JSON (not string) and then read the raw post data using php://input stream and use json_decode with $assoc set to true on the retrieved data yourself; since it appears that out-of-the-box method compiled into PHP is inefficient.

Tala
  • 909
  • 10
  • 29
0

Another solution that worked for me:

JS

$.ajax({
        url: 'recAjax.php',
        method: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(dict)
    });

PHP

var_dump(json_decode(file_get_contents('php://input'), true));

json_decode, php://input

Tala
  • 909
  • 10
  • 29