aladin
aladin

Reputation: 133

PHP get PUT request body

I'm currently developing a Restful Json-API in PHP. I want to send a PUT-Request to items/:id to update a record. The data will be transferred as application/json.

I want to call the API with

curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid"

On the server side, I'm not able the retrieve the request body. I tried

file_get_contents("php://input");

but this returns an empty string. Also a fopen()/fread() combination doesn't work.

When calling via POST, everything works great, I can read the json perfectly on the server side. But the API isn't Restful anymore. Does anyone have a solution for this? Is there another way to send and receive Json?

btw, I'm developing the API with the Slim Framework.

Upvotes: 13

Views: 22114

Answers (4)

deceze
deceze

Reputation: 522005

php://input is only readable once for PUT requests:

Note: A stream opened with php://input can only be read once; the stream does not support seek operations. However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. This is only possible if the request body data has been saved. Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND.

http://php.net/manual/en/wrappers.php.php

The Slim framework already reads the data upon request. Take the data from the Request object, into which it has been read.

Upvotes: 14

GordonM
GordonM

Reputation: 31730

The example from the PHP manual uses fopen to access php://input in read mode. Have you tried doing it that way instead?

EDIT: The manual page for PHP:// says some stuff that seems to suggest that PUT data might not be available in some cases!

Note: A stream opened with php://input can only be read once; the stream does not support seek operations. However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. This is only possible if the request body data has been saved. Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND.

I don't know where this will leave you regarding PUT processing. One page seems to say it's possible, the other seems to imply that it won't work under the wrong set of circumstances

Upvotes: 0

Berry Langerak
Berry Langerak

Reputation: 18859

On the server side, I'm not able the retrieve the request body. I tried file_get_contents("php://input");

You can only use file_get_contents( 'php://input', 'r' ); once per request. Retrieving its values will truncate the values as well, so if you call it twice, it'll return an empty string. Slim's request object contains the values you need, so:

<?php
$app = new Slim( );

$app->put( '/items/someid', function () use ( $app ) {
    echo $app->request( )->put( 'example' ); // should display "data".
});

Upvotes: 2

Jake
Jake

Reputation: 4374

I was reading the SLIM framework documentation the other day and it said that some browsers have problems with PUT and DELETE.

Excerpt:

Unfortunately, modern browsers do not provide native support for PUT requests. To work around this limitation, ensure your HTML form’s method is “post”, then add a method override parameter to your HTML form like this:

<form action="/books/1" method="post">
    ... other form fields here...
    <input type="hidden" name="_METHOD" value="PUT"/>
    <input type="submit" value="Update Book"/>
</form>

Source: http://www.slimframework.com/documentation/stable

Upvotes: -1

Related Questions