Laravel 10.10单例异常:服务端每次创建新实例,Tinker正常
Laravel 10.10单例实例无法跨请求持久化的问题解决
问题重现
已在AppServiceProvider.php中注册单例:
public function register(): void { $this->app->singleton('customService', \App\Services\CustomService::class); }
控制器中的test方法:
public function test() { $state = app('customService')->func('test', 'test'); $items = app('customService')->getRecents(); return ['items' => $items]; }
问题:每次调用控制器方法时,customService都会创建新实例,跨请求无法保留状态;但在Laravel Tinker中运行相同逻辑,单例实例能持久化,符合预期。
核心原因
Laravel的服务容器生命周期绑定于单个HTTP请求:
- 每次HTTP请求到达时,Laravel会重新初始化整个应用,服务容器也会从头构建,所有注册的单例只会在当前请求范围内保持唯一实例。请求结束后,整个应用实例会被销毁,内存释放。
- Tinker是一个长期运行的CLI进程,容器只会初始化一次,所以单例实例会在Tinker的整个会话中保持持久。
你误解了单例的作用范围:Laravel的单例是请求内单例,而非跨请求的全局持久实例。
解决方案
如果需要跨请求保存customService的状态,不能依赖容器单例,需要用持久化存储方案:
- Session:适合保存用户级别的临时状态,比如当前用户的操作记录。
- 缓存系统(Redis/ Memcached):适合保存全局或共享的临时数据,设置合适的过期时间。
- 数据库:适合需要永久存储的状态数据。
如果只是确保当前请求内使用同一个实例,你现有的代码是完全正确的,无需修改——比如在同一个请求的控制器、中间件、服务中多次调用app('customService'),都会拿到同一个实例。
内容的提问来源于stack exchange,提问作者zygsid
相关产品推荐
相关产品推荐

