直接用laravel-swoole包最稳妥,但须关闭enable_static_handler、禁用session共享、手动重置auth实例,否则请求间状态串扰致500或登录态丢失;验证swoole可用需执行php --ri swoole确认http=>enabled,并运行php -r "echo swoole_version();"返回版本号才算通过。

直接用 laravel-swoole 包是最稳妥的路径,但必须关掉 enable_static_handler、禁用 Session 共享、手动重置 Auth 实例——否则请求间状态会串,500 错误或登录态丢失是常态。
怎么确认 Swoole 扩展已装好且可用
别只信 php -m | grep swoole,它只说明扩展加载了,不等于能跑 HTTP 服务。真正要验证的是:
-
php --ri swoole看输出里有没有http => enabled - 执行
php -r "echo swoole_version();",返回版本号(如5.1.3)才算通过 - 如果报错
Call to undefined function swoole_version(),大概率是 PHP CLI 和 Web SAPI 用的不是同一个php.ini,得检查php --ini输出的配置路径
为什么 php artisan swoole:http start 启动后访问 127.0.0.1:1215 返回 404
这不是路由没注册,而是 Laravel 的入口逻辑没被正确桥接到 Swoole 的 onRequest 回调里。常见原因有三个:
- 没运行
php artisan vendor:publish --tag=laravel-swoole,导致config/swoole_http.php缺失,Swoole 启动时用的是空配置,静态资源和路由处理全挂了 - 配置里
'enable_static_handler' => true开着,但public/下没有真实文件(比如你用的是 Vue SPA,所有前端路由都靠index.htmlfallback),结果 Swoole 直接 404,连 Laravel 内核都没进 -
APP_URL配置错误(比如写成https://example.com),而 Swoole 是 HTTP 协议监听,Laravel 中间件会因协议不匹配拒绝请求
协程模式下 DB/Redis 连接为啥偶尔卡死或报 Connection refused
因为默认的 pdo_mysql 和 phpredis 不支持协程,Swoole 在协程上下文里调用它们会阻塞整个 worker 进程。必须换:
- 数据库:用
swoole/ide-helper不行,得切到co\MySQL或更推荐的hyperf/database+co-mysql驱动(Laravel 原生不支持,需封装) - Redis:停用
predis或phpredis,改用co\Redis,并在连接前显式调用go(function () { ... })包裹 - 关键点:
DB::connection()返回的实例不能跨协程复用,每次查询前应新建连接或从连接池取——否则连接会被上一个协程 hold 住
热更新代码后 php artisan swoole:http reload 没生效
reload 命令只是向主进程发信号,触发 worker 进程重启,但以下情况会让它“假装重启”:
- 修改了
config/下的文件,但没执行php artisan config:clear,Swoole worker 加载的还是旧配置缓存 - 用了
opcache.enable_cli=1,PHP CLI 模式也开了 OPcache,导致reload后仍跑旧字节码 - 在
AppServiceProvider的boot()里做了单例绑定(比如$this->app->singleton(...)),这些对象不会随 reload 销毁,下次请求还用老实例
真正安全的做法是 stop → config:clear → start,尤其上线前。











