Composer 无法直接安装 Swoole 扩展,必须通过 pecl 或源码编译安装 C 扩展并启用,再配合 swooletw/laravel-swoole 等封装库使用;Laravel 中需正确配置 APP_URL、SWOOLE_HTTP_HOST/PORT、server mode 及 Redis scheme,并排查端口占用、协程兼容性与自动加载冲突等问题。

Composer 安装 Swoole 扩展不是靠 composer require
很多人误以为 composer require swoole 就能装好 Swoole,其实不能。Swoole 是 PHP 的 C 扩展,必须先用 pecl 或源码编译安装到 PHP 运行环境中,再让 Composer 加载相关封装库。直接 composer require swoole 只会装一个空壳包(如 swoole/ide-helper),对运行毫无作用。
正确路径是:
- 确认 PHP 版本(Swoole 5.x 要求 PHP 8.0+,4.x 支持 PHP 7.4–8.2)
- 执行
pecl install swoole(推荐)或从 GitHub 源码编译 - 检查
php.ini是否已自动加入extension=swoole;没加就手动添加并重启 PHP-FPM 或 CLI - 运行
php -m | grep swoole确认扩展已启用
Laravel 中使用 swooletw/laravel-swoole 的关键配置点
这个包是 Laravel 社区最成熟的 Swoole 封装,但它不是“开箱即用”,几个地方不配好就会启动失败或路由不生效。
常见卡点:
-
APP_URL必须设为真实域名或http://127.0.0.1:1215(Swoole 默认端口),不能是http://localhost,否则中间件生成的 URL 会错 -
SWOOLE_HTTP_HOST和SWOOLE_HTTP_PORT需在.env中显式定义,否则走默认值但可能被防火墙拦截 -
config/swoole_http.php中的server→mode建议设为SWOOLE_PROCESS(非SWOOLE_BASE),避免协程调度异常影响 Laravel 生命周期 - 若用 Redis 缓存,确保
config/database.php中redis的scheme设为tcp,不要用unixsocket(Swoole 子进程可能无法访问)
php artisan swoole:http start 启动失败的典型错误和对策
启动报错最多的是端口占用、协程不兼容、以及 Laravel 自动加载机制冲突。
高频现象与应对:
- 错误信息:
Address already in use→ 检查netstat -tuln | grep :1215,杀掉残留进程或换端口(改SWOOLE_HTTP_PORT=1216) - 错误信息:
Call to undefined function Swoole\Coroutine\run()→ 表明 Swoole 扩展版本太低( - 请求返回空白页或 500,
storage/logs/swoole_http.log显示Class not found→ 清理bootstrap/cache/下的packages.php和services.php,再执行composer dump-autoload - Session 不生效或跨请求丢失 → 在
config/swoole_http.php中关闭session配置项,改用 Redis 驱动,并确保SESSION_DRIVER=redis
别忽略 Swoole 模式下 Laravel 生命周期的差异
Swoole 是常驻内存的,Laravel 应用只初始化一次,后续请求复用同一个应用实例。这意味着:
-
AppServiceProvider@register()和boot()只运行一次,不能在里面写依赖单次请求的逻辑(比如基于request()判断环境) - 全局变量、静态属性不会自动重置,例如
Cache::rememberForever()缓存会一直存在,除非手动Cache::forget() - 数据库连接默认长连接,需在
config/database.php的mysql配置里加'options' => [PDO::ATTR_PERSISTENT => false],否则高并发下连接数暴涨 - 日志写入要避开
storage/logs/laravel.log的文件锁竞争,建议用monolog+syslog或异步写入队列
php artisan swoole:http start --daemon
这条命令看着简单,背后涉及 PHP 扩展、Laravel 初始化、Swoole 事件循环三者耦合。最容易被跳过的其实是「扩展是否真加载成功」和「.env 配置是否被重新读取」——这两个点一错,后面全白调。











