cURL Multi 是 PHP 实现并发 POST 请求最稳定方案,通过批量调度非阻塞 I/O 完成并行;需正确设置 Content-Type、控制并发数(建议 10–50)、及时处理错误与清理句柄。

用 cURL Multi 实现 PHP 并发 POST 请求
PHP 本身没有原生多线程(pthread 在 Web SAPI 下受限且不推荐),所谓“并发 POST”实际靠 cURL Multi 批量调度多个 cURL 句柄,复用单进程事件循环完成 I/O 并行。这是最稳定、兼容性最好、无需扩展的方案。
关键不是“开线程”,而是避免阻塞等待每个请求返回:
-
curl_multi_init()创建批处理句柄 - 每个请求用独立
curl_init(),设好CURLOPT_POST、CURLOPT_POSTFIELDS、CURLOPT_RETURNTRANSFER - 用
curl_multi_add_handle()全部加入,再调用curl_multi_exec()轮询直到全部完成 - 别漏掉
curl_multi_getcontent()提取响应体,否则拿不到结果
POST 数据格式不匹配导致 400 或空响应
后端接口对 Content-Type 和数据格式敏感,cURL 默认不自动设头,容易踩坑:
- 传 JSON:必须显式设
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],且CURLOPT_POSTFIELDS传json_encode($data)字符串 - 传表单(
application/x-www-form-urlencoded):直接传关联数组,cURL自动编码;若手动拼字符串(如"a=1&b=2"),需确保 URL 编码正确 - 传文件:用
@/path/to/file(PHP 5.6+ 已废弃,改用CurlFile对象)
常见错误现象:HTTP/1.1 400 Bad Request、响应为空、后端收不到字段——先抓包或打日志确认发出的 Content-Type 和 body 是否符合接口文档。
立即学习“PHP免费学习笔记(深入)”;
并发数太高触发限流或连接超时
cURL Multi 不限制并发数量,但操作系统和远端服务有实际约束:
- Linux 默认单用户最大文件描述符数通常为 1024,每个
cURL句柄占一个 socket,超过会报Too many open files - 目标服务器可能对同一 IP 的并发连接数做限制(如 Nginx 的
limit_conn),导致部分请求卡住或直接拒绝 -
curl_multi_exec()轮询时若不加usleep()或curl_multi_select()等待,会空转 CPU;建议用curl_multi_select($mh, 1)阻塞等待 I/O 就绪 - 单次并发建议控制在 10–50 之间,具体看目标接口承载力和本地资源;需要更高吞吐应考虑队列分批
错误处理常被忽略的三个点
并发场景下,单个请求失败不能让整个批次中断,但错误信息容易被淹没:
- 每次
curl_multi_info_read()拿到完成句柄后,必须立刻调用curl_error($ch)和curl_errno($ch)检查该句柄是否出错,而不是只看 HTTP 状态码 -
CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT必须单独设置,否则默认是 0(无限等待),一个慢请求会拖垮整批 - 记得在循环末尾调用
curl_multi_remove_handle()和curl_close(),否则句柄泄漏,后续请求可能失败
真正难的不是发出去,而是每个请求的上下文隔离、超时控制、错误归因和资源清理——这些细节没处理好,并发反而比串行更不可靠。











