0

I create an object in Javascript to pass as the argument to a PHP script.

var pattern = new Object();
pattern['@id'] = '';
pattern['@num'] = '';
pattern.cprop = new Object();
//pattern.aprop = new Object();
pattern['@id'] = id;
pattern['@num'] = pn;
pattern.cprop.$ = pb.find('input[name="subject"]').val() || '';
var json = {'pattern': pattern};

My Ajax call is

url: clr_url_base+'storepat.php?data='+encodeURIComponent($.toJSON(json))

In my PHP script, I use

$pat = json_decode(str_replace ('\"','"', $data), true);
$prep = $pat["pattern"]["@id"];
$sense = $pat["pattern"]["@num"];
$cprop = $pat["pattern"]["cprop"]["$"];
//$aprop = $pat["pattern"]["aprop"]["$"];

This works, but when I add the aprop value, it no longer works.All values are strings. Any suggestions as to what's going wrong.

Here are the two JSON strings:

{\"pattern\":{\"@id\":\"against\",\"@num\":\"1(1)\",\"cprop\":{\"$\":\"a person or thing (often abstract) opposed\"}}}
{\"pattern\":{\"@id\":\"against\",\"@num\":\"1(1)\",\"cprop\":{\"$\":\"a person or thing (often abstract) opposed\"},\"aprop\":{\"$\":\"verbs (to which \'against\' introduces idea of opposition); nouns denoting conflict\"}}}

The first has only has the value for cprop, while the second adds the value for aprop. Note that aprop has single-quotes. It is this kind of data that seems to beg for encoding in the Javascript and decoding in the PHP. The second bombs. I have some 20 fields from a form, so it would get quite complex to create the JSON by hand, rather than as fields in pattern. When the second bombs, the value of $pat is NULL.

6
  • 1
    it seems silly to JSON encode data that could easily be part of the query string. Commented Nov 8, 2013 at 18:16
  • 1
    I think you should post the json data instead of sending it by query string. Just a suggestion :) Commented Nov 8, 2013 at 18:17
  • 2
    Does your server have magic quotes and register globals on... Commented Nov 8, 2013 at 18:21
  • 2
    You should prefer {} over new Object(), and you don't have to initialize your properties before setting them to your real value. Replace your entire first example with this: json = { pattern: { '@id': id '@num': pn, 'cprop': { '$': bp.find('input[name="submit"]').val() || '' } } }. And since you're using jQuery, just use url: pattern instead. Commented Nov 8, 2013 at 18:40
  • And, did you check json_last_error() (us2.php.net/function.json_last_error)? It may tell you outright what the problem is, or at least give guidance. Commented Nov 8, 2013 at 20:53

2 Answers 2

1

I would strongly suggest POSTing the data via jQuery rather than passing in query string. Why? Because then you don't have to worry about URL encoding and such.

This may look like this in javascript/jQuery. Obviously the concept is basically the same for any sort of AJAX sending mechanism.

$.ajax({
    type: 'POST',
    url: clr_url_base+'storepat.php?',
    contentType: 'application/json',
    dataType: 'json', // if you expect JSON in return
    data: json,  // your JSON string here
    success: // your success handler
    error: // your error handler
});

On the PHP-side, since you are not dealing with form-encoded data, you would need to read PHP's raw input. Luckily this is very simple and converting the POST data into a PHP object/array is very trivial. It is as simple as this:

$json = file_get_contents('php://input');
$variable = json_decode($json);
Sign up to request clarification or add additional context in comments.

5 Comments

@NiettheDarkAbsol You might be correct in that jQUery was not desired. I was simply assuming that was being used based on the post mentioning the definition of url property. Certainly other frameworks might use similar notation. I have edited my post to indicate this is a specific jQUery example but the concept would be similar regardless of mechanism used. Really the most important takeaway is to POST the data and work with the raw input on PHP side.
What I don't understand is what the argument of file_get_contents should be. (No need for dataType since I'm not expecting JSON in return (I'm putting the data into a MySQL database.)
The argument IS php://input This allows you to grab the content POSTed to the PHP script by reading from the raw input stream. See this link for more information php.net/manual/en/wrappers.php.php it is necessary to read the data this way as when you are not using one of the form-encoded contentType headers in the request, PHP does not populate the $_POST superglobal. You must get the POSTed content from the raw input stream.
@KenLit I would still suggest that your script return some sort of message to the calling javascript to indicate success/failure of DB update/insert. Whether you use JSON format for this return message is certainly up to you.
Ok, I've gotten the data "pattern%5B%40id%5D=against&pattern%5B%40num%5D=1(1)&pattern%5Bcprop%5D%5B%24%5D=a+person+or+thing+(often+abstract)+opposed" for my simple case. But, this doesn't look as if it's been decoded into an array, just a string that I need to decode further. Am I missing something?
0

You have a number of problems, but number one is that you have Magic Quotes enabled. That's why you have all those backslashes. Your crude attempt to "fix" it with str_replace is a bad idea, because there are other things besides " that gets escaped by Magic Quotes. You should find the setting in your php.ini file, and disable it. The same goes for "register globals", a very unsafe feature to be using. Reference $_GET['data'] instead.

With that out of the way, the next thing I would suggest is using POST instead of GET. This means you don't have to mess around with escaping data, as that always comes with the risk of screwing it up.

You should be able to implement these changes without too much trouble.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.