file_get_contents('php://input') 总是返回一个空字符串
Posted
技术标签:
【中文标题】file_get_contents(\'php://input\') 总是返回一个空字符串【英文标题】:file_get_contents('php://input') always returns an empty stringfile_get_contents('php://input') 总是返回一个空字符串 【发布时间】:2013-10-09 10:20:26 【问题描述】:我正在构建一个 php RESTful API,遵循 this 教程。以下函数在使用 'put' 方法时应返回随请求发送的数据,但每次都返回 null:
file_get_contents('php://input')
。
我什至已经下载并测试了教程中的完整代码示例,但它仍然返回 null。
我正在使用 cURL 和以下命令来测试 'put' 方法:
curl -i -X PUT -d '"address":"Sunset Boulevard"' http://localhost/clients/ryan
.
我在这上面浪费了好几天,仍然没有得到它来读取 json 数据。我做错了什么?
【问题讨论】:
您不会多次阅读php://input
的消息吗?请参阅此处的注意 - php.net/manual/…
@Phil Nope,我只读过一次。
【参考方案1】:
作为noted elsewhere on the web,如果请求被重定向,php://input
内容不会通过。也许您的 Web 服务器具有从以 www 开头的 URL 到不带 www 的 URL 的重定向,或者从使用 HTTP 的 URL 到使用 HTTPS 的 URL 的重定向。检查您的网络服务器日志以验证这一点,并采取相应措施以避免在调用网络服务时重定向。
【讨论】:
我不相信这可能是我的问题,但 curl 的测试证实确实存在从 example.com/test 到 example.com/test/ 的 301(添加了一个斜杠):facepalm : 是的,你拯救了我的一天。一直在互联网上搜索并找到了这个。我的通过 htaccess 从 http:// 重定向到 https://。非常感谢。 你是救生员。我在名为“extraction”的文件夹中创建了一个 index.php 文件,并在 Postman 中将 URL 提供为http://my-project/extraction
。将 index.php 更改为 extract.php,并将 URL 更改为 http://my-project/extraction/extract.php
为我解决了这个问题。我推断当应用程序 URL 中仅提供文件夹名称时,文件夹中的任何 index.php 文件都会发生 HTTP 重定向
为你加星。非常感谢
你真是个救命恩人!!谢谢朱利奥【参考方案2】:
首先,我能够运行这段代码并且运行良好:
--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 设置:
-
您使用的 curl url,确保该 url 确实有效并且没有返回错误。
打开另一个终端/控制台窗口并运行
tail -f /path/to/the/php/log/file
,这样您就可以实际看到这些 php 调用的输出。
通常人们会收到此错误:file_get_contents(file://input): failed to open stream: no suitable wrapper could be found
,这可能表示“file://input”字符串的拼写错误或allow_url_fopen
在 php 中被禁用的事实(如果不确定,请参阅 #5)
确保您的代码是正确的,我的意思是确保您没有输入不正确的参数和东西......在 netbeans 中不一定会加下划线的东西。
请记住,file_get_contents
仅在您的 PHP 设置中将 allow_url_fopen
设置为 true 时才有效。这是在 php.ini 中设置的内容,但您也可以在运行时更改设置,方法是在其他代码之前按照以下代码行编写一些内容:
ini_set("allow_url_fopen", true);
【讨论】:
我拿走了你的代码并运行了它,这就是我得到的全部:C:\Users\Igor\Desktop\curl>curl -i -X PUT -d '"address":"Sunset"' http://local host/server.php HTTP/1.1 200 OK Date: Thu, 03 Oct 2013 07:53:54 GMT Server: Apache/2.2.21 (Win64) PHP/5.3.8 X-Powered-By: PHP/5.3.8 Content-Length: 0 Content-Type: text/html
仍然没有。 allow_url_fopen 也开启了。
尝试在没有 -i
标志的情况下运行 curl 并添加 -v
标志以查看发生了什么。我几乎从不在 Windows 上运行 *amp 堆栈,所以那里可能会发生一些奇怪的事情。另外,请尝试在该响应中输出任意字符串,以确保您完全可以看到输出。另外,您是否查看了您的 php_log 以查看是否发生了任何错误?
我用-v
替换了-i
标志,仍然得到相同的结果。我还添加了 print_r('error') 以查看它是否会显示并且确实会显示,但 $data
仍然是空的。日志文件也是空的。也许我应该重新安装 wamp???
我什至在另一台机器上安装了 XAMP 和 WAMP 并运行了这段代码,我得到了空字符串。使用-v
标志向我显示所有字节都已发送。我不明白。
你还没有回答关于查看你的php错误日志的问题【参考方案3】:
确保没有重定向。
file_get_contents(php://input)
不会通过重定向传递正文内容。
检查重定向的一种快速方法是使用 curl 检查 url。在命令行上:
curl -IL http://example.com/api
【讨论】:
这真的很有帮助。 301 重定向可以更改为 308(如果需要重定向并且要求允许)。请参阅 MDN developer.mozilla.org/en-US/docs/Web/HTTP/Status/301 上的文档“因此,建议仅将 301 代码用作 GET 或 HEAD 方法的响应,而将 308 永久重定向用于 POST 方法,因为在此状态下明确禁止更改方法。 " 我的 http 请求被重定向到 https,因此删除了表单内容。谢谢提示【参考方案4】:对我来说,这个问题突然开始了。 我已经安装了 ssl 证书。 当我检查它向我显示 301 的响应代码时,我意识到并更改了http://到https://并得到了所有请求返回 file_get_contents('php://input')。
在您的示例 curl 调用中:
在 http 后面加上 s 如下图:curl -i -X PUT -d '"address":"Sunset Boulevard"' https://localhost/clients/ryan
【讨论】:
【参考方案5】:我也遇到了这个错误,我的解决方案是将数据格式更改为原始格式。
我是从php doc 那里得到的
php://input
不适用于 enctype="multipart/form-data"。
【讨论】:
【参考方案6】:我用这段代码写了一个头文件:
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"];
【讨论】:
带有所有参数的函数示例对我很有用:$data = file_get_contents("php://input", false, stream_context_get_default(), 0, $_SERVER["CONTENT_LENGTH"]);
【参考方案7】:
我遇到了同样的问题。 最终,我发现问题是在客户端我没有对 json 对象进行字符串化(之前我使用了 nodejs 服务器,还可以)。 一旦我这样做了,我就收到了 $_POST 中的数据(不是 json),作为常规参数。
【讨论】:
【参考方案8】:FWIW 我使用 Postman 发送值。在正文选项卡上,我应该使用“原始”选项卡发送 json "ID":1234,"Type":"Blah" 但我愚蠢地使用表单数据选项卡输入键/值使 php://input 结果为 NULL。一旦我切换到使用带有 JSON 的原始选项卡,那么一切都按预期工作。
【讨论】:
【参考方案9】:正确的函数调用是:
file_get_contents("php://input");
您应该会收到一条错误消息,指出 php:input
不存在...
无论如何,PUT
用于将文件上传到服务器,假设服务器支持它。通常你会使用POST
和适合内容的Content-Type
标头。
【讨论】:
对不起,我使用的是file_get_contents('php://input')
,我已经编辑了问题。
再次抱歉,来晚了,我累了
查看manual 中的注释,看起来PUT
请求并不适合这个。请改用POST
。
刚刚做了。它再次返回 null。
但是...null
不是file_get_contents
的有效返回值。它可以返回一个字符串,或false
。从不null
。你确定你没有错别字吗?比如你用来存储字符串的变量名?【参考方案10】:
在 Windows 上,“单“双”引号的组合似乎不起作用。在您的 json 数据中使用转义引号(如下所示)& 它应该可以工作
curl -X PUT -d "\"address\":\"Sunset Boulevard\"" http://localhost/clients/ryan
【讨论】:
【参考方案11】:随意编辑
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;
【讨论】:
当你想调用$post->p1
时,json_decode(file_get_contents('php://input'))
在 p1=1&p2=blabla$p3=false 等参数时返回空或 null。 例如:JQUERY $.post(url, $('form').serialize());
因为它需要 JSON 类型
你真的应该采取“回归早期原则”,大多数else
和else if
可以避免,缩进可以显着变平,只有在极少数情况下你才需要else
或@987654328 @ - 改变你的方法:)【参考方案12】:
我看到了问题,
您需要在请求url的末尾添加filename.php或需要重写.htaccess文件中的服务器规则来解决这个问题。
curl -i -X PUT -d '"address":"Sunset Boulevard"' http://localhost/clients/ryan/filename.php
用适当的文件名替换 filename.php。 :)
【讨论】:
【参考方案13】:
"action":"get_events_by_category",
"category_id":2
您的行字符串数据必须是双引号 "" 不能使用单个 ''
【讨论】:
以上是关于file_get_contents('php://input') 总是返回一个空字符串的主要内容,如果未能解决你的问题,请参考以下文章
file_get_contents 通过 php 失败,通过浏览器工作
php PHP Image出力(file_get_contents)