Reputation: 3927
I've set up a REST service and client in PHP and I'm having a bit of trouble with PUT.
Here's my situation: I'm coding a REST resource that should accept an array of data and an image. The REST resource should update an existing record, so I'm using PUT. I'm sending the data with a PHP curl client I wrote. So - pretty much the same situation as if you were sending a HTML multipart form to a PHP script that does a file upload and accepts some additional POST fields - except with PUT and PHP curl..
Up 'till now I've been sending the PUT request something like this (pseudo code):
$a_some_data = array('name' => 'test', 'user_id' => 4);
$body = http_build_query($a_data);
$fh = fopen('php://memory', 'rw');
fwrite($body);
rewind($fh);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => 'http://myapi/resource/someid',
CURLOPT_PUT => TRUE,
CURLOPT_INFILE => $fh,
CURLOPT_INFILESIZE => strlen($body)
));
curl_exec($ch);
and reading the data on the server like so:
parse_str(file_get_contents('php://input'), $put_data);
..which works just fine.
So now I would like to add a (binary) file into the mix. - How would I implement this on the client side? - How would I deal with the file on the server?
For a test I set up a HTML form with a file input, copied the raw multipart/form-data request it sends, and tried sending that data as a file with curl in a PUT request. That kind of works, but I would have to parse the raw data on the server manually, which I'm not sure is the best idea. Alternatively, I guess I could send the file as the body of the PUT request, and add the other parameters in the URL as a query string - but I guess that kind of defies the point of a PUT REST resource..
Please share your thoughts on this. Thanks!
Upvotes: 2
Views: 3848
Reputation: 58014
There are at least two other ways unless your original version isn't enough (since libcurl should deal just fine with binary files too with that script). Note that how you decide receive the PUT in the receiving end is not a curl issue so I'll leave it out of this response.
1 - Like you started out, but provide a CURLOPT_READFUNCTION with which you feed the data to libcurl that it will send.
2 - Use CURLOPT_POSTFIELDS (with a string) and make it look like a POST, and then you change the HTTP method with CURLOPT_CUSTOMREQUEST to "PUT"
Upvotes: 3