必须重新编译已安装的swoole.so才能启用curl支持,因其功能集在编译时固化;configure需加--enable-swoole-curl且系统须预装libcurl开发包,运行时还需调用Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL)显式启用协程hook。

必须重新编译,已安装的 swoole.so 无法追加 curl 支持
PHP 扩展一旦编译完成,其功能集(比如是否支持 --enable-swoole-curl)就固化在二进制里了。你不能通过改 php.ini 或调用某个函数来“开启”原生 cURL hook —— 它根本不在那块代码里。所以,哪怕 swoole.so 已加载、php -m | grep swoole 显示正常,只要没在 configure 阶段加 --enable-swoole-curl,后续所有协程 cURL 调用都会 fallback 到同步阻塞行为,甚至卡死。
configure 时必须带 --enable-swoole-curl,且依赖系统 cURL 开发头文件
核心命令是:./configure --with-php-config=/path/to/php-config --enable-swoole-curl。但这个选项生效的前提是:编译机上得有 curl/curl.h。macOS M2 上默认没有,必须先跑:brew install curl;Linux(如 Ubuntu)则需:sudo apt install libcurl4-openssl-dev;CentOS/RHEL 是:sudo yum install libcurl-devel。漏掉这步,configure 会静默跳过 cURL 支持,也不报错,只在 make 后期或运行时暴露问题。
macOS 编译常见链接警告:用 LDFLAGS 规避 -undefined suppress
在 macOS(尤其是 M2)上执行 make 时,容易看到:ld: warning: -undefined suppress is deprecated。这不是错误,但可能掩盖真实问题。解决方法是在 configure 前加环境变量:LDFLAGS="-Wl,-undefined,dynamic_lookup"。完整流程示例:
LDFLAGS="-Wl,-undefined,dynamic_lookup" ./configure \ --with-php-config=/opt/homebrew/bin/php-config \ --enable-swoole-curl \ --enable-openssl \ --with-openssl-dir=/opt/homebrew/opt/openssl@3
注意:--enable-openssl 和 --with-openssl-dir 虽非 curl 强依赖,但 HTTPS 请求必用,漏掉会导致 CURLOPT_SSL_VERIFYPEER=1 失败。
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
启用后还要 Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL)
编译只是第一步。运行时必须显式启用 hook,否则 curl_init() 还是走 PHP 原生同步逻辑。正确写法是:
use Swoole\Runtime;
Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);
go(function () {
$ch = curl_init('https://httpbin.org/get');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
echo curl_exec($ch); // 这行才是协程化的
curl_close($ch);
});
别用 SWOOLE_HOOK_ALL 代替 —— 它会无差别 hook 所有 IO,可能干扰已有 MySQLi 或 Redis 扩展的行为;只钩 cURL 最安全。另外,curl_multi 在 v4.6.5+ 才支持,老版本即使编译了 --enable-swoole-curl 也无效。
真正容易被忽略的是:编译路径和运行时 PHP 版本必须完全一致。比如你用 /opt/homebrew/bin/php-config 编译,但项目实际跑在 MAMP 的 PHP 8.2 上,那装进去的 swoole.so 就会 ABI 不匹配,扩展加载失败且无明确提示。

















