I have Backbone application. When model updates PUT request goes to my server.
Client-side looks good. But on the server side (PHP) I have some trouble. When I first time test this request in PHPStorm:
file_get_contents('php://input')
return what I expect. But on the other times it always return empty. I restarted Apache - nothing helps.
I know that
Note: A stream opened with php://input can only be read once;
But I thinked that mean one by request. Not once per life :) Where is my mistake?
It was Kohana problem. In Kohana_Request class there is piece of code, that already opened php://input stream
if ($method !== HTTP_Request::GET)
{
// Ensure the raw body is saved for future use
$body = file_get_contents('php://input');
}
You should be using $this->request->body() to get the request body.
Related
We have a contact.html form that uses reCaptcha v2, whose backend processing is in a php file.
I've taken enough steps to understand that when we send the verification to google's api, the response comes back empty. Below is code that gave me this proof.
$url = 'https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST["g-recaptcha-response"].'&remoteip='.$_SERVER['REMOTE_ADDR'];
$verify = file_get_contents($url);
echo $url;
if (empty($verify)) echo 'Failed to fetch data';`
However, when I manually enter the url into a browser, I get a JSON response back that indicates success.
What, then, is the difference? Why would file_get_contents return empty if a simple get request from a Chrome browser give me trouble?
I have read that file_get_contents is synchronous, so I wouldn't expect this is just a noob error on waiting for the response.
Any help would be appreciated, this is my very first time working with PHP. It's not hard, but I may be missing something vital.
Sorry everyone, I can't understand why, but the problem was in the method used to access the site verify.
Using curl syntax, I finally got it working.
Change the configuration in php.ini file and don't need curl.
allow_url_fopen=0 to allow_url_fopen=1
My environment is PHP 5.5.9, Nginx 1.4.6-1ubuntu3.2, localhost.
I'm trying to get data from PATCH method, but that just return an empty string...
With POST method that's work fine, this is a piece of my script :
case 'POST':
case 'PATCH':
$this->data = file_get_contents("php://input");
$this->data is empty when PATCH method is used and complete when POST, i use the POSTMAN chrome extension and i push RAW data (not multipart/form-data)
I think Nginx was in fault...but nothing into the log file...
Any help will be much appreciated !
I recently ran into a similar issue trying to access php://input for a PUT request. The issue was simply that I had already accessed it once previously (in a logging function that ran prior to the code in question).
POST acts differently than the other methods, which explains the discrepancy:
Note: Prior to PHP 5.6, a stream opened with php://input could only be read once; the stream did 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.
source: http://php.net/manual/en/wrappers.php.php
The solution was simple: Store the value of php://input from the initial grab to a PHP variable, and don't try to run file_get_contents("php://input") more than once for a non-POST request.
I wrote a program that reads a binary file into the RAM and then sends it using an HTTP request to my server. It uses the PUT method and the binary file is (in) the body.
Now how can I tell my server to receive and safe the file in a folder?
If possible without any additional libraries that I would need to download (unless it's more efficient).
I know, there are some similar threads to this one, but they either they where about receiving text or they were about doing it with libraries or there simply was no sufficient answer.
I'd also like to know, if it would be more efficient or smarter to use the POST method or any other instead of PUT.
You can get at the data by opening a stream to php://input, like so:
$datastr = fopen('php://input',rb);
if ($fp = fopen('outputfile.bin', "wb")){
while(!feof($datastr)){
fwrite($fp,fread($datastr,4096)) ;
}
}
As to whether to use POST or anything else depends on what is happening with the data, and whether you care about being RESTful or such. See other questions/answers, indempotency.
The advantage I would see with using POST is that it's more commonly used (on most submission forms where you upload a file), and therefore has more support from within PHP and html.
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.
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.
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".
});
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
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
framework is here
http://luracast.com/products/restler/
i'm using restler as restful api for my work,
when i use backbone model save to a url, it sends and update my data as json by using 'HTTP PUT' request method, and i want to get a response from what i've putted...
if it's a HTTP POST request method i can use
// to getting content from a POST
$post_data = json_decode(file_get_contents('php://input'), true);
to get my content, but cant get anything from HTTP PUT
// can't get anything from a PUT
function putpatients($id) {
$post_data = file_get_contents('php://input');
$post_data = json_decode($post_data, true);
echo $post_data['name'];
}
the browser response blank
how do i return my data as json ???
As I commented on your question, php://input is a stream, if you read from it, it empties it.
I've never used Restler before but looking at the few examples provided in their download, it seems to indicate the submitted data is automatically passed as a parameter to your put handler..
In Restler's crud example, the Author class has a put request like this:
function put($id=NULL, $request_data=NULL) {
return $this->dp->update($id, $this->_validate($request_data));
}
so i'm guessing that restler has already read the php://input stream, and hence emptied it.
so, your put handler should maybe be more like in their example:
function putpatients($id, $request_data = NULL) {
/* do something with the $request_data */
var_dump($request_data);
}
Edit: There's actually a previous SO question from #deceze that talks about why reading twice from php://input doesn't work - for PUT requests - which explains why your code worked with a POST request. Either way, you should really use the facility provided by Restler rather than re-inventing the rest wheel.
Does the developer tool of your choice (firebug etc.) show a response?
If so it could help if you put echo json_encode($post_data['name']); instead of your echo.
try to use print_r() function for displaying the values of the variable example:
print_r($post_data);