不能靠 curl_multi 自动隔离 cookie——所有句柄共享同一 cookie 上下文,必须显式禁用自动管理:设 CURLOPT_COOKIEFILE、CURLOPT_COOKIEJAR、CURLOPT_COOKIE 为空,并手动通过 CURLOPT_HTTPHEADER 设置 Cookie;禁止使用 curl_share_init_persistent 共享 cookie 资源;每个请求应独占独立句柄并重置 cookie 相关选项。

不能靠 curl_multi 自动隔离 cookie —— 它根本不处理 cookie 隔离,所有句柄共享同一份 cookie 上下文,除非你主动切断。
为什么 curl_multi 会污染 cookie
多个 CurlHandle 加入同一个 CurlMultiHandle 后,如果都启用了 CURLOPT_COOKIEFILE 或 CURLOPT_COOKIEJAR,libcurl 默认会把所有请求的 cookie 存进同一个内存池(或文件)。哪怕你为每个句柄单独设置了不同 CURLOPT_COOKIEFILE 路径,只要没显式禁用 cookie 共享机制,它们仍可能在 DNS/连接复用层被意外混用。更隐蔽的是:若某个句柄设置了 CURLOPT_COOKIE(字符串形式发送),而另一个没清空,后续请求可能带上不该带的头。
必须禁用自动 cookie 管理
对每个加入 curl_multi 的句柄,显式关闭 libcurl 的 cookie 引擎:
-
curl_setopt($ch, CURLOPT_COOKIEFILE, '')—— 清空读取源,避免加载旧 cookie -
curl_setopt($ch, CURLOPT_COOKIEJAR, '')—— 清空写入目标,防止写入共享文件 -
curl_setopt($ch, CURLOPT_COOKIE, '')—— 清空手动设置的 cookie 字符串 - 如果需要发特定 cookie,改用
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Cookie: key=value'])显式传,且每次请求前重设
不要用 curl_share_init_persistent 共享 cookie 相关资源
虽然 curl_share_init_persistent 支持 CURL_LOCK_DATA_DNS 和 CURL_LOCK_DATA_CONNECT,但它明确禁止传入 CURL_LOCK_DATA_COOKIE —— PHP 会直接抛出 ValueError。这不是限制,而是强制提醒:持久化 cookie 共享在多用户/多请求场景下是危险操作。即使你绕过 PHP 层强行用 C 扩展做,也会导致跨请求 session 混淆,尤其在 FPM 模式下 worker 复用时极易暴露。
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
立即学习“PHP免费学习笔记(深入)”;
真正安全的隔离方式:每个逻辑请求独占句柄 + 显式控制 cookie
并发不等于共享 cookie。正确做法是:
- 为每个需独立 cookie 上下文的请求,初始化独立
CurlHandle - 所有 cookie 相关选项设为空,不依赖 libcurl 自动管理
- 如需登录态,先用单个句柄完成登录,提取
Set-Cookie响应头,解析后手动注入到后续请求的Cookieheader 中 - 避免在
curl_multi循环中复用同一$ch变量;句柄应在curl_multi_add_handle前就配置完毕,且不跨请求复用
最易被忽略的一点:即使你没设任何 cookie 选项,某些服务端返回的 Set-Cookie 仍可能被 libcurl 缓存进内部结构 —— 所以务必在每次 curl_exec 后检查响应头,并在下次请求前重置所有 cookie 相关选项。这不是过度防御,而是 curl_multi 在 PHP7.1 下已知的行为边界。


















