应优先用 view()->composer() 处理动态数据,view()->share() 仅适用于静态配置;因后者在 AppServiceProvider::boot() 中单次执行,无法获取请求上下文如 Auth::user() 或路由信息。

全局变量该用 view()->share() 还是 view()->composer()?看数据是否依赖请求上下文——静态值用前者,动态值必须用后者。
什么时候必须用 view()->composer()
当你需要的数据每次渲染都可能不同,比如未读消息数、当前用户权限、多租户站点配置,view()->share() 就会出错:它只在 AppServiceProvider::boot() 执行一次,之后所有请求都复用同一个结果。
- Auth::user() 在
view()->share()里大概率是null,因为认证中间件还没跑 - request()->getHost() 或 Route::current()->getName() 在
share()里根本拿不到,对象还没初始化 - 缓存键如果带用户 ID,但
share()里没做区分,所有用户看到的都是第一个用户的缓存 - 错误现象:
Call to a member function unreadMessages() on null或菜单始终显示默认项
view()->composer() 的参数写法陷阱
第一个参数控制作用范围,写错会导致数据漏传或误传;第二个参数决定执行时机和可访问性。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 匹配单个视图:
view()->composer('layouts.app', ...) - 匹配目录下全部视图:
view()->composer('admin.*', ...)(注意是点号,不是斜杠) - 匹配多个不相关视图:
view()->composer(['home', 'profile', 'settings'], ...) - 闭包方式最灵活,但别在里面调
app()或request()实例——它们不是 request-scoped,可能被提前释放 - 类方式更易测试,但类必须实现
compose(View $view)方法,且不能依赖构造器注入 request 或 auth
view()->share() 只能在 AppServiceProvider::boot() 里安全调用
它看着简单,但位置错一步就报 Call to a member function share() on null。
- 绝对不要写在
register()里:视图引擎尚未注册 - 不要写在中间件里:多次响应(如重定向+渲染)会导致重复 share,后一次覆盖前一次
- 不要写在控制器里:只对当前视图生效,违背“全局”本意
- 只放轻量数据:比如
config('app.name')、env('APP_ENV');别放Auth::user()或 Eloquent 模型集合 - 传数组比传对象稳妥:
view()->share('site_config', config('site'))安全,view()->share('config', config())会传入 Application 实例,有副作用风险
调试时怎么确认变量到底有没有进视图
别猜,直接在 Blade 里加一行:{{ dump(get_defined_vars()) }},然后搜索你的 key 名。线上环境务必删掉——它会暴露整个变量作用域。
- 如果变量名存在但值是
null,检查是不是在share()里调了未初始化的Auth::user() - 如果变量名根本没出现,说明
composer()的视图匹配模式写错了,比如写了'layouts/app'(路径写法)而不是'layouts.app'(命名空间写法) - 如果变量值正确但页面没更新,清 Laravel 缓存:
php artisan view:clear,Blade 编译缓存会卡住旧逻辑
真正容易被忽略的是:视图共享不是变量赋值,而是视图实例的上下文注入。你不能指望 isset($foo) 总是返回 true,也不能靠执行顺序假设某个 share() 一定早于另一个——Laravel 允许多次同名覆盖,谁最后执行谁生效。

















