php 5.6 发送 chunked post 请求的核心是绕过 curl 自动设置 content-length:必须设 curlopt_upload=true、不设 content-length、提供 curlopt_readfunction 回调返回数据块;用 curlopt_postfields 会强制计算长度而禁用 chunked,手动加 transfer-encoding 头易被服务端拒收。

PHP 5.6 发送 chunked 编码的 POST 请求,核心不是“选什么函数”,而是绕过 cURL 自动计算 Content-Length 的默认行为,强制它用流式分块传输。这在上传大文件、推送实时日志、对接某些 IoT 网关或要求严格 chunked 的 API 时是刚需。
必须满足的三个条件
-
CURLOPT_UPLOAD设为true - 不设置
Content-Length(显式设为空或完全不设) - 提供
CURLOPT_READFUNCTION回调函数,按需返回数据块
缺一不可。只要用了 CURLOPT_POSTFIELDS(无论传数组还是字符串),cURL 就会自动算长度、加 Content-Length 头,chunked 就不会触发。
正确写法示例(不含手动 Transfer-Encoding)
$data = str_repeat("x", 8192); // 模拟 8KB 数据
$offset = 0;
$chunkSize = 1024;
$ch = curl_init('https://api.example.com/chunked-endpoint');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/plain']);
// 不设 Content-Length —— 关键!cURL 会因此启用 chunked
curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($data, &$offset, $chunkSize) {
$remaining = strlen($data) - $offset;
if ($remaining <h3>常见误区提醒</h3>
- 手动加
'Transfer-Encoding: chunked'头 → 多数服务端会拒收或报 400 - 用
file_get_contents()或http_build_query()直接塞进CURLOPT_POSTFIELDS→ 必然带Content-Length,chunked 失效 - 用
CURLFile或@/path→ 这是 multipart 文件上传路径,和 chunked 无关,且 PHP 5.6+ 已废弃@语法 - 回调函数返回
0或false表示错误,应返回空字符串''表示流结束
怎么验证是否真发了 chunked?
用 curl_setopt($ch, CURLOPT_HEADER, true) 获取完整响应头,再配合抓包工具(如 Wireshark 或 Charles)看原始请求体——你会看到类似这样的分块结构:
400\r\n [4096 bytes of data]\r\n 400\r\n [another 4096 bytes]\r\n 0\r\n \r\n
不复杂但容易忽略
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











