Accessing Incoming PUT Data from PHP
Wednesday, July 30. 2008
You might want to consider checking the Content-Type header, as well (to see if it is application/x-www-form-urlencoded; not sure how to deal with multipart/form-data; AFAIK that’s not supposed to be PUTted anyway, but hey…)
Interesting post, thanks.
Now I wonder why there is no $_PUT superglobal in PHP. Anyone?
Well i never worked with put, but interesting.
The line break inside the
"curl -X PUT http://localhost/rest_fruit.php -d fruit=orange -d quantity=4" statement is iritating a bit first i thought: Where is the value for quantity transfered and thought of some magic stuff until i saw it belongs to the same line.
might be worth having a look over:
http://uk.php.net/manual/en/function.http-get-request-body-stream.php
...although a comment note also says that it has probs with multipart/form-data.
Might also be worth having a chat with Zoe Slattery at phplondon if you make it down as she was looking into REST quite a lot recently.
Cheers,
paul
Thanks everyone for dropping in and adding comments :)
David: I am leaning towards hoping I don’t need to deal with multipart PUTs!
Balu: The impression I got from the PHP internals people was that it wasn’t really used enough so nobody had bothered to make one, but that it could be done.
Johny: Actually now you mention it, the way that has wrapped is kind of annoying!
Mark: You can retrieve the data for DELETE requests in the same way as PUT requests. Is that what you were asking?
Paul: Hello! Not sure if I’ll make it down for PHP London, but I can probably track Zoe down if I need to pick her brain – thanks for mentioning it!
For people that don’t know what PUT / DELETE are: http://www.artima.com/lejava/articles/why_put_and_delete.html
I would like to here more about the script you wrote that handles $_POST variables. Especially if you have one that sends stuff via $_POST with php!!! email me if you can. thanks!
EllisGL: thanks for adding the additional link to resources, very helpful :)
Glen: These examples use cURL from the command line to send the data – but PHP has a wrapper for this that you can use – look at http://uk.php.net/manual/en/book.curl.php and read the reader-contributed notes as well to see some examples.
Great post Lorna!
This would also give you a great place to filter input variables.
But you do know that apache doesn’t support PUT by default?
I’d love to hear more about your REST implementation.
No problem. I had to actually figure out what those two verbs where. Of course I feel like PUT/DELETE can pose as some major risks, yes you can secure the page, but feel like they are too much of a "strait to the point" operation that can cause some issues. I don’t know, never had the need to use those verbs.
Just my 2 cents.
Boy: Hey there, thanks for dropping in. Perhaps I should write a more comprehensive tutorial about the REST implementation I’ve been doing, its a wrapper for a library class similar to how the SOAP wrappers wrap classes.
EllisGL: The PUT and DELETE verbs are only as direct as you let them be. Just as with a POST operation, you would check all the data, the user credentials and so on, you do the same for these and its no different to work with.
parse_str() is therefore capable of the same evil that ‘extract()’ is.
Unfortunately I maintain some code that loves ‘extract()’ :-(
LornaJane: Ah OK.
David: Sounds like some code I had to maintain at my last job. Yeah extract can be evil and can make debugging a nightmare..
I am curious as to why extract() is so bad – I agree that it is for incoming data because of never trusting the client and the need for cleansing data before you use it elsewhere.
However if you pull out database records as an associative array (i.e. the source is trusted) then extract() is really useful…? I code a lot of PHP as well so would be interested in your thoughts on this!
Mark
Mark: I always think it is best to access the variables in their associative array, so that its very clear that you are using the "name column from the result set $foo" rather than "this variable called $foo that could have come from anywhere and its not declared so you can’t debug it"! Its too easy, especially on large systems, to accidentally use the same variable twice, or to be unclear where its coming from – so I always teach that extract is a BAD thing.
David: I am lucky enough to have dodged code like that most of the time. Untraceable variable soup really scares me … maybe because I didn’t start using PHP until after register_globals was off by default!
Hi,
if you are going to use the $SERVER[] array like this, why not go the whole hog and use $_SERVER[‘QUERY_STRING’] to get the parameters, instead of going through the file_get_contents() which seems (slightly) more complicated ?
shaun: good question! I’m not sure that PUT requests would populate this in the same way as GET does (for example). The file_get_contents just opens the stream to php://input, its an easy way to do this.
ok, I’ve been experimenting with this, ‘switch’ing on the REQUEST_METHOD to implement post, get, put, delete for a db resource; so far I’ve not had problems using $_SERVER[‘QUERY_STRING’] and parse_str()... what problems do you anticipate? (I’m not sending files, everything fits in the string). I was surprised to discover that cURL allows ANY string to be sent as the method e.g. curl ‘http://my.web.page/’ -X OBLITERATE would invent a new ‘obliterate’ request method.
shaun: I didn’t anticipate problems, I just didn’t think it worked in that way – but I’m completely happy to be told otherwise :) Don’t be surprised that curl lets you do weird and wonderful things, lots of tools are like that and it allows you to use them in ways that the original author hadn’t thought of. And if you feed them rubbish, well they will probably response with rubbish :) This is a common approach with the unix type apps, kind of "use at your own peril"!
Thanks a lot LornaJane! I’ve been hitting my head on the deck with this issue for a long time now.
About the multipart, as far as I know, this is the assumed way a PUT request should work.
PUT is not supposed to work with multipart/form-data, because you can send the raw contents of a file as the request body without encoding it. With curl, you’d specify the file with CURLOPT_INFILE and CURLOPT_INFILESIZE options. Or you can set CURLOPT_POSTFIELDS to a raw text/content and recieve it in php://input too.
Very useful! Thanks LornaJane! I’m thinking more about web services since your talk at the PHP UK Conference last month. I enjoyed it a lot by the way, I’ve lost count of how many HORRIBLE ‘web services’ I’ve encountered!
Rowan: Thanks for the comment, I’m glad the talk and this post were useful. I totally agree on the horrible services front, personally I am hoping that as the field becomes more established, the standards become more accepted.



I recently had reason to write a REST server in PHP , which was very interesting. There aren’t a whole lot of resources on this topic around so I thought I’d write an outline of what I did. There is quite a lot to it so I’m publishing in multiple section
Tracked: Aug 31, 20:19