Hi folks, long time no speak!

I'm trying to put together a simple form which I intend to use from a mobile phone. So, I'm taking a "kind of" app approach and using JSON to pass data up and down.

To aid that I'm using Knockout.js to help populate the form, validate it and serialize the data into JSON.

For those that don't know much about Knockout, I have a Javascript object (ViewModel) which represents the form data. Knockout then exposes a function

ko.toJSON(viewModel);

which, unsurprisingly, serializes the ViewModel into JSON. This is what the JSON looks like:

{"Amount":"44.55","Date":"2013-03-03","Account":"Food","StatusMessage":"New Expense"}

I then use jQuery to post that data to a PHP script on the server:

$.post("/save.php", ko.toJSON(viewModel), function(returnedData) {});

Using Chrome's Developer Tools to inspect the Network traffic, I can see the AJAX request has the JSON Form Data exactly as expected, i.e. as per the above representation.

My question is, how can my PHP script consume the Form Data? My previous experience has been posting individual fields of data which can then be accessed with

$_POST["fieldname"];

but the JSON object here doesn't have a name.

This feels like a really easy thing to achieve, and I'd expect finding a solution to be easy too but I just can't get the search terms correct.

    Whatever is being posted, it's in the [font=monospace]$_POST[/font] array; use [man]var_dump[/man] to look at a sample (and compare it with whatever Knockout's documentation says about its Ajax method).

      Weedpacket;11025563 wrote:

      Whatever is being posted, it's in the [font=monospace]$_POST[/font] array; use [man]var_dump[/man] to look at a sample (and compare it with whatever Knockout's documentation says about its Ajax method).

      That's what I was expecting, but it doesn't appear to be the case. I'm baffled. Totally baffled.

        I've done some further investigation and tests and it would seem that the format of the data being posted is the issue. If I post the javascript object like so

        Name=Rich&Colour=Blue

        then PHP can handle it fine with $_POST["Name"].

        If I serialize the object to JSON and post it, then it seems that PHP can't handle it. It doesn't appear in the $_POST in any shape or form.

        {"Name":"Rich","Colour":"Blue"}

        I can appreciate that, to some extent, but it does leave me a little confused. I should be able to post JSON objects, rather than just a string literal representation.

          Rodders;11025577 wrote:

          I should be able to post JSON objects, rather than just a string literal representation.

          You can, but you shouldn't expect it to work the same way a properly formatted POST body would. There's nothing to put in the $_POST array since you haven't given PHP any POST'ed data it knows how to parse.

          Instead, you'll have to get at the raw body of the request and parse it manually. Try doing:

          echo file_get_contents("php://input");

          to see if you get the raw data you sent.

            That's interesting, so thanks for your response.
            Does this mean that something is handling the request and preparing the posted data into the PHP $_POST global? Is that an Apache thing, or part of PHP? That makes total sense to me, but I'd like to read more about it to increase my understanding.

            I did what you suggested and it did reveal the JSON object as hoped. It feels a bit dirty to do it that way though. Is this a normal practise?

              Rodders;11025583 wrote:

              Does this mean that something is handling the request and preparing the posted data into the PHP $_POST global?

              Yes, the core of PHP is receiving the body of your POST request (as passed along by Apache/your webserver). It's not in the RFC standards to guess that the data is in JSON and attempt to decode it, thus PHP doesn't do that.

              Rodders;11025583 wrote:

              It feels a bit dirty to do it that way though. Is this a normal practise?

              Like I said, if you encode POST'ed data differently than the standards dictate, then you'll have to take responsibility to decode it on the other side as well. This is one of the reasons why PHP provides the 'php://' wrapper - nothing "dirty" about it.

                On the other hand, it would be weird if Knockout provided a .post method but neglected to provide any method for properly encoding data for use in that method. Looking at Knockout's site it would seem the documentation is a bit shabby on the topic: its [font=monospace].toJSON[/font] method doesn't produce a JSON object, but a string representation of a JSON object. The [font=monospace].post[/font] method is actually that of jQuery, and the documentation there should be used.

                The only hints in Knockout's documentation itself that you don't need to use [font=monospace].toJSON[/font] to serialise the JSON object as a string before sending it to [font=monospace].post[/font] is that the former is only mentioned after the latter, and the use of the phrase "JSON string".

                  Thanks for your help with this guys.
                  I've certainly gained a better understanding of how all the technologies fit together which will allow me to find a clean solution to my problem.

                  My current thought is that I'll post the JSON string to my PHP script, which will then grab it with the [man]file_get_contents[/man] function and then I can use [man]json_decode[/man] to map it to a PHP object of my choosing.

                  There are numerous approaches I could take, but this one feels like it would allow me to swap PHP for ASP.NET MVC or Ruby on Rails more easily. That is a serious possibility for me as I'm more experienced with .Net than anything else currently.

                  Consider this thread resolved.

                    Write a Reply...