执行php artisan optimize报Closure::__set_state()未定义如何解决
问题成因
运行php artisan optimize时触发该报错的核心原因是:Laravel执行优化命令时,会将项目的配置、路由等核心数据序列化后写入bootstrap/cache目录生成缓存文件,而PHP的闭包(匿名函数)本身不支持序列化所需的__set_state()魔术方法,当待缓存的内容中包含闭包时,序列化过程就会抛出该错误。手动删除缓存只是临时清除了错误生成的缓存文件,下次执行优化命令时问题会复现。
常见的闭包引入场景包括:
config/目录下的配置文件中直接定义了匿名函数作为配置值routes/目录下的路由文件中直接使用闭包定义路由逻辑,且优化命令会触发路由缓存- 新引入的第三方扩展包的默认配置中包含闭包
- 服务提供者中给容器绑定的逻辑使用了不符合缓存规则的闭包写法
永久解决方法
- 排查配置文件:遍历
config目录下的所有PHP文件,将所有作为配置值的匿名函数替换为可调用类方法、常量或者具体返回值。比如原配置'custom_callback' => function() { return date('Y-m-d'); }可以改为'custom_callback' => [\App\Helpers\Common::class, 'getDate'],使用时通过call_user_func(config('app.custom_callback'))调用即可。 - 调整路由定义:如果项目需要启用路由缓存,所有路由不能直接使用闭包定义,需全部映射到对应的控制器方法处理。比如将
Route::get('/demo', function () { return view('demo'); })改为Route::get('/demo', [\App\Http\Controllers\DemoController::class, 'index'])。 - 排查第三方扩展:如果自有代码排查完仍存在问题,逐个检查近期新增的Laravel第三方扩展,将带闭包的扩展配置发布到项目
config目录后,替换掉其中的闭包逻辑即可。 - 拆分优化命令:如果业务场景必须保留部分闭包逻辑,可以放弃执行全量
php artisan optimize命令,按需执行单独的优化指令,比如仅执行配置缓存php artisan config:cache、视图缓存php artisan view:cache,跳过会触发闭包序列化的路由缓存环节。
内容的提问来源于stack exchange,提问作者Swift Solutions
相关产品推荐
相关产品推荐

