PHP, PUTs, POSTs, and Backbone.js

PHP has a small error where it does not put querystring results for a HTTP PUT inside a superglobal such-as $_PUT[] or $_POST[]. The second issue is that Backbone.js likes to send JSON vs a querystring.

Therefore the following code was written to use $_POST[] to access PUT and POST data payloads of json or querystring variety:

if($_SERVER['REQUEST_METHOD'] == 'PUT' || $_SERVER['REQUEST_METHOD'] == 'POST') {  
  $postStr = file_get_contents("php://input");
  //json_decode throws error or returns null if input is invalid json
  try {
    $json = json_decode($postStr, true);
    if(empty($json)) { 
      throw new Exception("not valid json");
    }

  //must not be json, try query str instead 
  } catch(Errfor $e) { 
    $postVars = parse_str($postStr);
    foreach($postVars as $key=>$data) {
      $_POST[$key] = $data;
    }
  }
}

This code basically checks if the HTTP method is a PUT or POST. Then it gets the data payload $postStr.

json_decode will throw an exception if its inputted invalid json, or return null (Rant: PHP why can't you just stick with one output for 'not json'). Which is why the try catch is used.

If json_decode 'fails', the 'catch' will run code to parse out the post query string.

After this code has been run, all POST and PUT requests with a payload of querystring or json will be accessible using the PHP Superglobal $_POST.