Miles Per Hour

programming at the speed of 1011000.

Dec

5

Reading Backbone.js POST variables from PHP

By mike@mike-miles.com

For a recent project, I had to read POST variables sent from Backbone.js to PHP. Now is turns out Backbone.js does not simply send normal POST variables (retrievable from $_POST). Instead it sends a json object of the variables.

So simply querying the global $_POST object for the variables you are looking for will not work, PHP will say that the $_POST is empty.Enter “php://input” .

“php://input” is the input stream that allows you to read raw data from the request bod. Basically you can read in the raw POST data this way. so for example if you called file_get_contents(“php://input”); it would return the POST data.

Now as I said before, Backbone.js sends the POST data as a json object. So reading in the contents of the php://input will get your the values that are posted. Let’s look at an example.

Let’s say that Backbone.js was sending us the following variables:
category_id: 1
sub_catagory_id: 34
title: “my saved data”

Say Backbone.js was sending the following through POST

{"catagory_id":1,"sub_catagory_id":34,"title":"my saved data"}

Notice, Backbone.js sends only a json string, not variable name to access. the POST is the string. so trying to view the $_POST with say a print_r would return false. But using “php://input” with file_get_contents, we can get the raw POST data and place it into a variable.

<?php
  $post_data = file_get_contents("php://input");
?>

and $post_data would then be a json string

<?php
  echo $post_data; //{"catagory_id":1,"sub_catagory_id":34,"title":"my saved data"}
?>

And now you can simply use json_decode($post_data) to retrieve a the json object of values. (passing a second argument returns an associative array instead of an object.)

<?php
  $post_data = file_get_contents("php://input");
  $post_data = json_decode($post_data,true);
/* $post_data returns the following
  array(
   "catagory_id":1,
   "sub_category_id":34,
   "title":"my saved data",
  );
*/

But wait, that may solve our problem if we know for sure that “php://input” contains data from Backbone.js (a json string). But what if it doesnt? wouldn’t it make sense to cover our bases. How about writing a function that can return the POST data no matter what?  Well then a function like the following might suffice.

<?php
function get_post_data(){
	if ($input = file_get_contents("php://input")){
		//test for json
		if ($json_post = json_decode($input,true)){
			return $json_post;
		}else{
			parse_str($input,$variables);
			return $variables;
		}
	}
	return false;
}
?>

One additional function to note I am using is “parse_str“. parse_str parses a string as if it were the query string passed via a URL and sets variables in the current scope. Passing the second argument sets the parsed data into a variable. So with this function, if the POST data is a json string, it gets parsed into an associate array, and if it is normal POST data, it gets parsed into an associative array. A win win for all cases.

Comments are closed.