Recently I started writing a REST service. I began in the usual way, writing a php script, calling it with a GET request, accessing the variables using the PHP superglobal variable $_GET. I wrote code to handle a POST request and used the variables I found in $_POST. Then I tried to write a PUT request.

PHP doesn't have a built-in way to do this, and at first I was a little confused as to how I could reach this information. It turns out that this can be read from the incoming stream to PHP, php://input.

file_get_contents("php://input");

The above line provided me with a query string similar to what you might see on the URL with a GET request. key/value pairs separated by question marks. I was rescued from attempting to parse this monster with a regex by someone pointing out to me that parse_str() is intended for this purpose (seriously, I write a lot of PHP, I don't know how I miss these things but its always fun when I do "discover" them) - it takes a query string and parses out the variables. Look out for a major health warning on str_parse() - by default it will create all the variables all over your local scope!! Pass in the second parameter though and it will put them in there as an associatvive array instead - I'd strongly recommend this approach and I've used it here with my $post_vars variable.

parse_str(file_get_contents("php://input"),$post_vars);

This loads the variable $post_vars with the associative array of variables just like you'd expect to see from a GET request.

Simple Example

Its a bit of a contrived example but it shows use of the REQUEST_METHOD setting from the $_SERVER variable to figure out when we need to grab the post vars. Firstly, here's the script:

if($_SERVER['REQUEST_METHOD'] == 'GET') { echo "this is a get request

"; echo $_GET['fruit']." is the fruit

"; echo "I want ".$_GET['quantity']." of them



"; } elseif($_SERVER['REQUEST_METHOD'] == 'PUT') { echo "this is a put request

"; parse_str(file_get_contents("php://input"),$post_vars); echo $post_vars['fruit']." is the fruit

"; echo "I want ".$post_vars['quantity']." of them



"; }

And here's what happened when I request the same script using two different HTTP verbs. I'm using cURL to show the example simply because I think it shows it best.

Via GET:

curl "http://localhost/rest_fruit.php?quantity=2&fruit=plum" this is a get request plum is the fruit I want 2 of them

Via PUT:

curl -X PUT http://localhost/rest_fruit.php -d fruit=orange -d quantity=4 this is a put request orange is the fruit I want 4 of them

Purists will tell me that I shouldn't be returning data from a PUT request, and they'd be right! But this does show how to access the incoming variables and detect which verb was being used. If you're going to write a REST service then the correct naming of resources and the correct response to each resource being accessed in various ways is really important, but its a story I'll save for another day. If you use this, or perhaps you access the variables another way, then do post a comment - there aren't a lot of resources available on this topic for PHP.