CLI和FPM使用不同php.ini,Swoole仅在CLI下完整可用;需分别配置extension=swoole.so并重启服务;编译缺pcre.h需装libpcre3-dev或pcre-devel;WebSocket需服务端用swoole_websocket_server且Nginx反代配upgrade头。

为什么 php --ri swoole 有输出,但 php -m 或网页 phpinfo() 看不到?
这不是安装失败,而是 CLI 和 FPM/Apache 使用了不同的 php.ini 文件。Swoole 只在 CLI 模式下完整可用,FPM 模式下协程、异步 IO、定时器等核心功能全部失效——它压根就不是为 FPM 设计的。
- 运行
php --ini查 CLI 的配置路径,php-fpm -i | grep "Loaded Configuration File"查 FPM 的路径 - 确认两个
php.ini都写了extension=swoole.so(注意路径是否真实存在) - 别纠结网页版
phpinfo()是否显示 Swoole:只要php --ri swoole能打印出版本和coroutine => enabled,就代表可用了 - 常见坑:编译安装后忘了加
swoole.use_namespace=1,导致类名找不到;或没重启php-fpm进程,改了配置也不生效
make 报错 pcre.h: No such file or directory 怎么办?
这是系统缺 PCRE 开发头文件,不是 Swoole 代码问题,也不是 PHP 版本不对。PCRE 是正则底层依赖,Swoole 编译时必须能 #include <pcre.h>。
- Ubuntu/Debian:
sudo apt-get install libpcre3-dev(注意是-dev包,不是libpcre3) - CentOS/RHEL:
sudo yum install pcre-devel或dnf install pcre-devel - 装完必须重新执行
phpize && ./configure && make clean && make install,不能跳过 - 验证是否生效:
php --ri swoole | grep pcre应输出pcre => enabled
WebSocket 客户端连不上 swoole_websocket_server,但 telnet 能通端口
协议不匹配是最常见原因。浏览器用 ws:// 或 wss://,服务端就必须是 swoole_websocket_server;如果服务端是 swoole_server(TCP),客户端却用 WebSocket 库连接,必然失败——就像拿英语词典跟日本人对话。
- 检查服务端实例化方式:
new Swoole\WebSocket\Server才支持 WebSocket 握手,new Swoole\Server不行 - 客户端不要在浏览器地址栏直接输
ws://127.0.0.1:9501测试,要用 JS 写new WebSocket(...),否则握手请求不完整 - 上线用 Nginx 反代时,必须加这三行:
proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade",缺一不可 - 防火墙或云服务器安全组放行的是端口,不是协议——端口通 ≠ 协议通
Worker 进程里创建的定时器、Redis 连接、MySQL 连接,重启后丢失?
因为 Swoole 默认 reload 是“杀旧启新”,旧进程退出前不会自动清理资源。你没显式关闭,连接就挂在那儿直到超时断开,定时器回调也永远不执行。
- 必须监听
onWorkerExit事件,在里面主动close()所有长连接(Redis、MySQL、TCP Socket) - 定时器若跨请求生命周期,得用
onWorkerStart初始化,或改用Task进程承载长期任务 - 别依赖
__destruct:PHP 对象析构在进程退出时不保证触发,尤其协程环境下 - 更稳妥的做法是设
max_request(如 3000),让 Worker 处理一定请求数后自动退出,强制释放所有上下文










