How do I access PHP REST API PUT data on the server side?
Asked Answered
D

3

25

-- Question --

I am just starting out with the REST API and am getting pretty confused.

This is what my PHP cRUL client-side looks like for a PUT.

case 'PUT':
    curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
    break;

Now when I look at the server my $_SERVER['REQUEST_METHOD'] shows PUT, but my question is how do I get the $data I sent with CURLOPT_POSTFIELDS.

All I need to do is get the $data sent with a PUT request into the next line. Like

$value = $data['curl_data'];

I have seen so much clutter on this topic that it is giving me a headache. It seems so easy on the php client side, but no one has answers that are working for the php server side.

Thanks for any help!

-- Answer (after help and homework) --

I am new so I can't answer my own question until after 8 hours... odd :)

Okay, after working with the great people here I have to say we ran into the answer. I am kicking myself for it being so easy, at the same time it was confusing.

curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($handle, CURLOPT_POSTFIELDS, http_build_query($data));

The first change (above) I had to add http_build_query() around $data. This took my data from an array to a url friendly string.

Next up I had to add.

parse_str(file_get_contents('php://input'), $put);

Now I can do things like $put['data'].

The answer PaulPRO gave above does work to get the data the same way file_get_contents() did with less lines. We got stuck trying to figure out how to parse the data which was where my lack of http_build_query() I had seen on another site kicked into play.

So This is how it all works.

  1. Data is put into a normal array.
  2. http_build_query() converts it into a nice almost GET like string.
  3. file_get_contents() transports it from the client to the server.
  4. parse_str() then turns it back into an array.

I am seeing a lot of messages about using PUT to send files. I can see how this would work, but from what I read in this entire REST process was that PUT is to update data as post is to create data. Maybe I am mistaken. Am I missing something?

Deflation answered 24/7, 2011 at 7:44 Comment(1)
Maybe these links will help you better understand some of the quirks of REST.Nellenelli
L
15

From the PHP Manual:

PUT data comes from stdin:

$putdatafp = fopen("php://input", "r");

Example usage:

$putfp = fopen('php://input', 'r');
$putdata = '';
while($data = fread($putfp, 1024))
    $putdata .= $data;
fclose($putfp);
Laboratory answered 24/7, 2011 at 7:48 Comment(15)
Okay got a lead with both of these. The upper one returned Resource #11. How do I access that resource. And the bottom returned the data in a messy string, but I see it is there.Deflation
@sylor I edited my post. Is the data correctly in $putdata after that code?Laboratory
I am getting a few errors on the filesize. Warning: filesize() [function.filesize]: stat failed for Resource id #11. It also tells me that file size cant be 0 on fread.Deflation
@shylor Makes sense i guess, since stdin has a variable size. I think you'll have to do it with a loop then. I updated my post again.Laboratory
If I use the file_get_contents I get this chunk of code... my data is in it, but how do I parse it? ------------------------------49d1750468a4 Content-Disposition:_form-data;_name] => \"app_secret\" a3e0701fbbafae60b9ba1922d0ee28def305113f ------------------------------49d1750468a4 Content-Disposition: form-data; name=\"data\" email/1 ------------------------------49d1750468a4--Deflation
Your code will always cause infinite loop, since $putdata is always not empty after first iteration.Mirabelle
@shylor, you're right. That was a stupid overlooked error on my part. I fixed it.Laboratory
Okay, I am now getting the same result from both systems. I just need to be able to parse that long mess of a string. Any ideas?Deflation
I need to get app_secret to = a3e0701fbbafae60b9ba1922d0ee28def305113f and data to = email/1Deflation
@Shylor, no idea. I'm thinking that looks like headers sent by a form POST request but I'm not sure how you'd read that in a PUT request. Have you tried making a PUT request to the page with just a number as input or something and no form data?Laboratory
That is the data coming from opening the input. The data I need is there, just need to parse the junk off it to get it to something I can use.Deflation
Are you submitting an HTML form to make the request? I don't think that's normally how you make a PUT request.Laboratory
Got a lead. I wrapped the data on the client with PHP http_build_query() and it does not look like a mess. It looks more like a GET now.app_secret=a3e0701fbbafae60b9ba1922d0ee28def305113f&data=email%2F1Deflation
@shylor Ah, that's perfect then. You should be able to use PHP's parse_str() function on it now: php.net/manual/en/function.parse-str.phpLaboratory
Bingo got it. I will post up an official answer for all those that follow after me and scream. Thanks a ton!Deflation
H
15

I've the same scenario where in, have to send data to the PHP Server through ReST API using the PUT method. I struggled almost couple of hours to find the solution, but finally found the way :

In CUrl :

$postData = http_build_query($data);
curl_setopt($ch, CURLOPT_POSTFIELDS,$postData); 

We've to parse the data to a variable let say: $putData, Here, is the Parse String procedure :

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

Then print the $putData, will get the same array that you're posting in the curl..

Halftone answered 2/4, 2015 at 11:16 Comment(1)
This answer is the best way I like. parse_str(file_get_contents("php://input"),$putData); Gain
A
2

If you want to get form data with key value like $_POST.

function PUT(string $name):string{

    $lines = file('php://input');
    $keyLinePrefix = 'Content-Disposition: form-data; name="';

    $PUT = [];
    $findLineNum = null;

    foreach($lines as $num => $line){
        if(strpos($line, $keyLinePrefix) !== false){
            if($findLineNum){ break; }
            if($name !== substr($line, 38, -3)){ continue; }
            $findLineNum = $num;
        } else if($findLineNum){
            $PUT[] = $line;
        }
    }

    array_shift($PUT);
    array_pop($PUT);

    return mb_substr(implode('', $PUT), 0, -2, 'UTF-8');

}

For Example rest-api.php

$title = PUT('title');
Alien answered 18/10, 2020 at 2:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.