如何使用cURL发送原始的POST数据?(PHP)

6

我想用$HTTP_RAW_POST_DATA向一个页面发送原始的POST数据,但我的尝试失败了,并出现了未定义索引的提示。

我尝试过以下操作:

curl_setopt($handle, CURLOPT_POSTFIELDS, 'Raw POST data');   // Doesn't seem to work at all.
curl_setopt($handle, CURLOPT_POSTFIELDS, array('Raw POST data'));   // 0 => Raw POST data

我进行了一些研究,有些人建议在请求中发送一个头部 (Content-Type: text/plain),但似乎没有影响任何内容。

这个问题是否有解决方案?

2个回答

4

当你的发送/接收循环中出现响应错误时,这可能非常可能是“发送方”(未发送正确的请求)的问题,也可能是接收PHP脚本配置不正确的问题。即使请求是正确的,接收方可能仍然无法使用HTTP_RAW_POST_DATA

参见:http://www.php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data

始终填充包含原始POST数据的$HTTP_RAW_POST_DATA。 否则,该变量仅填充未识别的数据MIME类型。但是,访问原始POST数据的优选方法是php://input。$HTTP_RAW_POST_DATA在enctype="multipart/form-data"中不可用。

因此,首先要检查的是$HTTP_RAW_POST_DATA是否已填充,从上面的页面可以知道,这要求:

  1. .ini变量always_populate_raw_post_data为True,或者
  2. POST是使用POST处理程序不识别的Content-Type发送的(也许可以使用"text/raw")

此时,发送数据的正确方法是:

curl_setopt($handle, CURLOPT_POSTFIELDS, urlencode('Raw POST data'));

然而,请注意推荐接收此数据的方法不是依赖于$HTTP_RAW_POST_DATA,而是读取虚拟文件php://input的内容。

php://input是一个只读流,允许您从请求正文中读取原始数据。对于POST请求,最好使用php://input而不是$HTTP_RAW_POST_DATA,因为它不依赖于特殊的php.ini指令。此外,在那些$HTTP_RAW_POST_DATA默认未填充的情况下,它是一种潜在更少占用内存与激活always_populate_raw_post_data相比较的替代品。


这个回答似乎与原问题无关,原问题实际上是关于如何使用libcurl从PHP执行HTTP请求,而不是访问运行在Web服务器中的PHP脚本发送的POST数据。 - Shadocko
@Shadocko - 原始问题确实描述了在运行于 Web 服务器中的 PHP 脚本访问 POST 数据时出现未定义索引错误。我很乐意承认,在这种特定情况下,错误出现在发送脚本中,但我提供的解决方案与我亲眼观察到并知道发生的情况有关。虽然它不是针对这个特定案例的答案,但对于寻找相同解决方案的其他人来说,它可能非常有用。 - LSerni
@lserni - 您的回答现在更加清晰了,我已经为它点赞,即使这不是我在这里偶然发现时正在寻找的答案。 - Shadocko
哇,谢谢!但是你在找什么呢?我很乐意帮忙 :-) - LSerni
@lserni - 我的问题是将大文件作为原始POST主体发布。最终我解决了它:https://dev59.com/YG_Xa4cB1Zd3GeqP595d#31696809 - Shadocko
显示剩余4条评论

2

出于某种奇怪的原因,上述标题似乎可以解决问题。以前它不起作用,我不确定为什么现在它能起作用。

无论如何,对于那些不知道的人,这是代码:

curl_setopt($handle, CURLOPT_HTTPHEADER, array('Content-Type: text/plain'));

我实际上需要一个不同的Content-Type,但这让我走上了正确的轨道。 - Matthew Lock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接