Swoole 是 PHP 的 C 扩展,非 Composer 包,需编译安装并配置 php.ini;支持常驻内存服务,HTTP 与 WebSocket 服务器协议不同、端口不可混用;协程仅对封装 IO 透明,阻塞操作须替换为协程版或交由 TaskWorker 处理。

Swoole 不是框架,是 PHP 的 C 扩展
它让 PHP 能写常驻内存、高并发的网络服务,比如 HTTP 服务器、WebSocket 服务、TCP 长连接网关。你写的代码不再走 php-fpm + Nginx 那套请求-响应生命周期,而是自己监听端口、接收连接、处理数据——本质上,你是在用 PHP 写“服务端程序”,不是“Web 脚本”。
为什么不能当普通 Composer 包装?
因为 swoole 是 PHP 解释器级别的扩展,必须编译进 PHP 运行时,不是靠 require 加载的类库。装错位置、版本不匹配、PHP 编译参数冲突,都会导致 Class 'Swoole\Http\Server' not found 或直接段错误。
- 必须用
pecl install swoole或源码编译,不能composer require swoole/swoole(那个包只是空壳,没用) - PHP 版本要 ≥ 7.4(2026 年主流已到 8.2+),但注意:Swoole 5.x 不支持 PHP 8.4,装前先查
php -v和pecl info swoole - 装完必须在
php.ini里加extension=swoole.so,且确认是 CLI 模式下的 php.ini(php --ini查路径),不是 FPM 的 - 重启的是
phpCLI 环境,不是 Apache/Nginx;验证用php -m | grep swoole,不是看网页
swoole_http_server 和 swoole_websocket_server 的关键区别
别以为只是换了个类名——底层协议栈、事件回调、数据解析逻辑完全不同。HTTP 是短连接、有状态头、需响应格式;WebSocket 是长连接、二进制/文本帧、需握手升级。混用会直接断连或收不到数据。
-
swoole_http_server只响应onRequest,不认onOpen/onMessage;强行注册会被忽略 -
swoole_websocket_server也能处理 HTTP 请求(比如升级前的 GET),但只触发onRequest,且必须手动调用$response->upgrade()才能转成 WebSocket 连接 - 端口不能复用:同一个端口不能既跑 HTTP 又跑 WebSocket,除非你在
onRequest里做协议判断和路由,但非常容易出错 - 调试时用
curl http://127.0.0.1:9501测 HTTP,用wscat -c ws://127.0.0.1:9502测 WebSocket,别用浏览器开发者工具瞎猜
协程不是“自动异步”,sleep() 和 file_get_contents() 仍会阻塞
很多人以为开了协程就万事大吉,结果写个 sleep(3) 或同步 MySQL 查询,整个 Worker 就卡住。Swoole 的协程只对它封装过的 IO 操作透明(如 Swoole\Coroutine\Http\Client、Swoole\Coroutine\MySQL),原生 PHP 函数照旧阻塞。
- 必须把阻塞操作替换成协程版:用
Swoole\Coroutine\MySQL代替mysqli,用Swoole\Coroutine\Http\Client代替file_get_contents或 cURL 同步调用 -
usleep()可以,sleep()不行;co::sleep()是推荐写法 - 第三方 SDK(比如 Redis 客户端)若没适配协程,必须用
go(function() { ... })包一层并扔给TaskWorker处理,否则污染主协程调度 - 开启协程 Hook(
Swoole\Runtime::enableCoroutine())能自动转换部分函数,但仅限于明确文档支持的(如fread、stream_socket_client),别赌运气
真正难的不是写第一个 echo "Hello Swoole",而是搞清进程模型里 Master/Worker/Task/Reactor 各自干什么、哪些变量跨协程不共享、日志怎么打才不丢、热更新怎么安全切流——这些不在入门示例里,但上线第一天就会撞上。










