php 5.6 不支持直接将流资源(如 php://input)传给 curlopt_postfields,必须先用 stream_get_contents() 或 file_get_contents() 读取为字符串再提交;上传文件应使用 curlfile 类,禁用 @语法;发 json 需手动设 content-type 请求头。

PHP 5.6 本身不支持直接用 php://input 或原生 Stream 对象作为 CURLOPT_POSTFIELDS 的值来发送原始流数据(比如已打开的文件句柄或内存流),因为 cURL 要求传入的是字符串或数组,不能直接接受资源类型。但你可以通过“读取流内容为字符串”再 POST,这是最稳妥、兼容 PHP 5.6 的做法。
用 file_get_contents 读取 stream 内容再 POST
适用于:你有一个 php://memory、php://temp、stream_socket_client 返回的流,或 fopen('php://input', 'r') 等资源,需要把它作为请求体发出。
- 先用
stream_get_contents($stream)或file_get_contents(stream_get_meta_data($stream)['uri'])把流内容完整读成字符串 - 设置
CURLOPT_POSTFIELDS为该字符串,并手动指定Content-Type - 务必关闭流(如果不再需要),避免资源泄漏
上传文件时用 CURLFile(PHP 5.6+ 推荐)
如果你的“Stream”实际是本地文件,别试图用 fopen 后传资源——PHP 5.6 开始应使用 CURLFile 类:
$file = new \CURLFile(realpath('/path/to/image.jpg'), 'image/jpeg', 'avatar');-
$post_data = ['file' => $file, 'size' => '228*150'];(按服务端要求补字段) - 注意:
@/path语法在 PHP 5.6+ 已被弃用,会触发 E_DEPRECATED
发 JSON 或自定义二进制流体
若你构造的是 JSON、XML、Protobuf 等纯文本/二进制流体:
- 直接赋值给
CURLOPT_POSTFIELDS:例如$json_str = json_encode($data); curl_setopt($ch, CURLOPT_POSTFIELDS, $json_str); - 必须加请求头:
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); - 不要传数组,否则会被自动 urlencode 成表单格式,后端收不到
php://input
不推荐:尝试传 stream 资源本身
以下写法在 PHP 5.6 中无效且会出错:
-
curl_setopt($ch, CURLOPT_POSTFIELDS, $fp);—— cURL 不识别资源类型,可能返回 false 或空响应 -
curl_setopt($ch, CURLOPT_POSTFIELDS, stream_get_contents($fp));才是对的
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











