27

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

file_get_contents('php://input').

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

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

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

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

4

13 回答 13

36

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

于 2019-01-17T16:25:17.650 回答
10

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

--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);

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

  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”字符串的错字或在 php 中被禁用的事实allow_url_fopen(如果不确定,请参阅#5)
  4. 确保你的代码是正确的,我的意思是确保你没有输入不正确的参数和东西......在netbeans中不一定会加下划线的东西。
  5. 请记住,file_get_contents只有allow_url_fopen在 PHP 设置中设置为 true 时才有效。这是在 php.ini 中设置的内容,但您也可以在运行时更改设置,方法是在其他代码之前按照以下代码行编写一些内容:

    ini_set("allow_url_fopen", true);
    
于 2013-10-02T23:15:15.793 回答
10

确保没有重定向。

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

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

于 2019-08-05T20:07:17.980 回答
5

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

我从php doc那里得到它,它说

php://input不适用于enctype="multipart/form-data"

于 2017-12-14T06:28:38.887 回答
5

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

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

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

于 2019-09-25T15:14:49.093 回答
4

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

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;
}

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

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

例子:

 echo $_POST_JSON["address"];
 // or
 echo $_REQUEST["address"];
于 2015-07-09T15:40:45.803 回答
2

FWIW 我正在使用 Postman 发送值。在 Body 选项卡上,我应该使用“Raw”选项卡发送 json {"ID":1234,"Type":"Blah"} 但我愚蠢地使用表单数据选项卡输入键/值使 php://input 结果为 NULL。一旦我切换到使用带有 JSON 的原始选项卡,那么一切都按预期工作。

于 2021-02-02T23:47:06.203 回答
2

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

于 2019-05-24T07:54:57.253 回答
1

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

curl -X PUT -d "{\"address\":\"Sunset Boulevard\"}" http://localhost/clients/ryan
于 2015-02-12T03:29:19.520 回答
1

正确的函数调用是:

file_get_contents("php://input");

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

无论如何,PUT用于将文件上传到服务器,假设服务器支持它。通常你会使用适合内容POSTContent-Type标题。

于 2013-10-02T21:19:46.207 回答
1

随心所欲地编辑

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;
}
于 2019-06-28T05:34:30.863 回答
0
{
  "action":"get_events_by_category",
  "category_id":2
}

您的行字符串数据必须是双引号 "" 不能使用单 ''

于 2020-08-28T18:12:22.283 回答
0

我看到了问题,

您需要在请求 url 的末尾添加 filename.php 或者需要在 .htaccess 文件中重写服务器规则来解决这个问题。

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

用适当的文件名替换 {filename.php}。:)

于 2018-12-20T12:42:12.250 回答