file_get_contents('php://input') 总是返回一个空字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19146984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 18:54:26  来源:igfitidea点击:

file_get_contents('php://input') always returns an empty string

phpjsonrestcurlrestful-architecture

提问by Igor

I'm building a PHP RESTful API, following thistutorial. The following function, which should return the data sent with the request when the 'put' method is used, returns null every time:

我正在按照教程构建一个 PHP RESTful API 。下面的函数应该在使用 'put' 方法时返回随请求发送的数据,每次都返回 null:

file_get_contents('php://input').

file_get_contents('php://input').

I've even downloaded and tested the full code example in the tutorial and it still returns null.

我什至下载并测试了教程中的完整代码示例,但它仍然返回 null。

I'm using cURL and the following command in order to test the 'put' method:

我正在使用 cURL 和以下命令来测试 'put' 方法:

curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/clients/ryan.

curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/clients/ryan.

I've wasted days on this and still haven't gotten it to read the json data. What am I doing wrong?

我在这上面浪费了几天,但仍然没有让它读取 json 数据。我究竟做错了什么?

回答by Giulio Piancastelli

As noted elsewhere on the web, php://inputcontent does not get through if request is redirected. Maybe your web server has a redirect from an URL starting with www to an URL without www, or from URLs using HTTP to URLs using HTTPS. Check your web server logs to verify this, and act accordingly to avoid the redirection when making calls to the web service.

正如网络上其他地方所述php://input如果请求被重定向,内容将无法通过。也许您的 Web 服务器已从以 www 开头的 URL 重定向到不带 www 的 URL,或者从使用 HTTP 的 URL 重定向到使用 HTTPS 的 URL。检查您的 Web 服务器日志以验证这一点,并在调用 Web 服务时采取相应措施以避免重定向。

回答by Kristian

First off, i was able to run this code and it worked fine:

首先,我能够运行此代码并且运行良好:

--Terminal---------
//I ran this curl request against my own php file:
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/test.php


--PHP--------------
//get the data
$json = file_get_contents("php://input");

//convert the string of data to an array
$data = json_decode($json, true);

//output the array in the response of the curl request
print_r($data);

If that doesn't work, check the console for errors and your php settings:

如果这不起作用,请检查控制台是否有错误和您的 php 设置:

  1. the curl url you used, make sure that url is actually working and not returning errors.
  2. open up another terminal / console window and run tail -f /path/to/the/php/log/fileso you can actually see the output of these php calls.
  3. often people get this error: file_get_contents(file://input): failed to open stream: no suitable wrapper could be foundwhich can indicate either a typo of the "file://input" string or the fact that allow_url_fopenis disabled in php (see #5 if unsure)
  4. make sure your code is correct, and by that I mean make sure you're not typing in incorrect arguments and things... stuff that doesn't necessarily get underlined in netbeans.
  5. remember, file_get_contentsonly works when allow_url_fopenis set to true in your PHP settings. thats something that is set in php.ini, but you can also change settings at run time by writing something along the lines of the following code before the other code:

    ini_set("allow_url_fopen", true);
    
  1. 您使用的 curl url,请确保 url 实际工作并且不返回错误。
  2. 打开另一个终端/控制台窗口并运行,tail -f /path/to/the/php/log/file这样您就可以实际看到这些 php 调用的输出。
  3. 通常人们会收到此错误:file_get_contents(file://input): failed to open stream: no suitable wrapper could be found这可能表明“file://input”字符串的拼写错误或allow_url_fopen在 php中被禁用的事实(如果不确定,请参阅 #5)
  4. 确保你的代码是正确的,我的意思是确保你没有输入不正确的参数和东西......在netbeans中不一定要加下划线的东西。
  5. 请记住,file_get_contents只有allow_url_fopen在 PHP 设置中设置为 true时才有效。这是在 php.ini 中设置的内容,但您也可以在运行时更改设置,方法是在其他代码之前编写以下代码行中的内容:

    ini_set("allow_url_fopen", true);
    

回答by sifr_dot_in

for me this problem started, suddenly.
i had installed ssl certificate.
when i checked the response code it showed me 301, then i realized and changed
http://
to
https://
and got all the request back with file_get_contents('php://input').

对我来说,这个问题突然开始了。
我已经安装了 ssl 证书。
当我检查响应代码时,它显示了 301,然后我意识到并将
http://更改

http s://
并使用 file_get_contents('php://input') 取回所有请求。

in your example curl call:
put s after http as shown below:
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' https://localhost/clients/ryan

在您的示例 curl 调用中:
将 s 放在 http 之后,如下所示:
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' https://localhost/clients/ryan

回答by billrichards

Make sure there are no redirects.

确保没有重定向。

file_get_contents(php://input)doesn't pass the body content through redirects.

file_get_contents(php://input)不通过重定向传递正文内容。

One quick way to check for redirects is to check the url with curl. On the command line: curl -IL http://example.com/api

检查重定向的一种快速方法是使用 curl 检查 url。在命令行上: curl -IL http://example.com/api

回答by Radon8472

I wrote a headerfile with this code:

我用这段代码写了一个头文件:

if($_SERVER["REQUEST_METHOD"] == "POST" && $_SERVER["CONTENT_TYPE"] == "application/json")
{
  $data = file_get_contents("php://input", false, stream_context_get_default(), 0, $_SERVER["CONTENT_LENGTH"]);
  global $_POST_JSON;
  $_POST_JSON = json_decode($_REQUEST["JSON_RAW"],true);

  // merge JSON-Content to $_REQUEST 
  if(is_array($_POST_JSON)) $_REQUEST   = $_POST_JSON+$_REQUEST;
}

It checks for the correct content-type and it reads only as much post input, like specified in Content-Length header. When receiving a valid JSON it created an global Array $_POST_JSON.

它检查正确的内容类型,并且只读取与 Content-Length 标头中指定的一样多的帖子输入。当接收到有效的 JSON 时,它会创建一个全局数组 $_POST_JSON。

So you can work with your JSON-Content the similiar like you do it with url-encoded POST values.

因此,您可以像使用 url 编码的 POST 值一样使用您的 JSON-Content。

Example:

例子:

 echo $_POST_JSON["address"];
 // or
 echo $_REQUEST["address"];

回答by Timtcng.sen

I had got this error too, my solution is to change the data format to raw.

我也有这个错误,我的解决方案是将数据格式更改为原始格式。

I get it from php docwhere it say

我从php doc那里得到它

:php://input is not available with enctype="multipart/form-data".

回答by Shlomo

I had the same problem. Eventually, I found that the problem was that in the client side I didn't stringify the json object (previously I used nodejs server and it was OK). Once I did that, I received the data in $_POST (not as json), as regular parameters.

我有同样的问题。最终,我发现问题是在客户端我没有对json对象进行字符串化(之前我使用的是nodejs服务器,还可以)。一旦我这样做了,我就收到了 $_POST 中的数据(不是 json),作为常规参数。

回答by sambha

On Windows the combination of 'single "double" quotes' does not seem to work. Use escape for quotes in your json data (as below) & it should work

在 Windows 上,“单“双”引号的组合似乎不起作用。在您的 json 数据中使用转义引号(如下所示)并且它应该可以工作

curl -X PUT -d "{\"address\":\"Sunset Boulevard\"}" http://localhost/clients/ryan

回答by Niet the Dark Absol

The correct function call is:

正确的函数调用是:

file_get_contents("php://input");

You should be getting an error message saying that php:inputdoesn't exist...

您应该收到一条错误消息,php:input说不存在...

In any case, PUTis intended for uploading files to the server, assuming the server supports it. Usually you'd use POSTwith a Content-Typeheader appropriate to the content.

在任何情况下,PUT都用于将文件上传到服务器,假设服务器支持它。通常您会使用适合内容POSTContent-Type标题。

回答by Shanaka Madusanka

Edit as you wish

随心所欲编辑

function getPostObject() {
    $str = file_get_contents('php://input');
    $std = json_decode($str);
    if ($std === null) {
        $std = new stdClass();
        $array = explode('&', $str);
        foreach ($array as $parm) {
            $parts = explode('=', $parm);
            if(sizeof($parts) != 2){
                continue;
            }
            $key = $parts[0];
            $value = $parts[1];
            if ($key === NULL) {
                continue;
            }
            if (is_string($key)) {
                $key = urldecode($key);
            } else {
                continue;
            }
            if (is_bool($value)) {
                $value = boolval($value);
            } else if (is_numeric($value)) {
                $value += 0;
            } else if (is_string($value)) {
                if (empty($value)) {
                    $value = null;
                } else {
                    $lower = strtolower($value);
                    if ($lower === 'true') {
                        $value = true;
                    } else if ($lower === 'false') {
                        $value = false;
                    } else if ($lower === 'null') {
                        $value = null;
                    } else {
                        $value = urldecode($value);
                    }
                }
            } else if (is_array($value)) {
                // value is an array
            } else if (is_object($value)) {
                // value is an object
            }
            $std->$key = $value;
        }
        // length of post array
        //$std->length = sizeof($array);
    }
    return $std;
}