The new (since Laravel 11) Context capabilities should work for you; it is storing the shared state in memory rather than database or cache, so it is quick and allows storing a wider variety of data types (if that is relevant for your use case).
Share data with views and controller without using the cache
Hello,
I'm looking for a way to share data with all views and all controllers without using the cache.
Something like using a view composer, but also available for all classes (controllers, services, ...).
How can I do that properly ?
Thanks for your help.
V
@tykus Thank you.
@tykus I have tried to use Context from the AppServiceProvider, but it doesn't work.
When I get the context keys, it always returns null.
Are there restrictions where I can use the context ?
Laravel's "context" capabilities enable you to capture, retrieve, and share information throughout requests, jobs, and commands executing within your application.
@vincent15000 If you tried to set data in the AppServiceProvider's boot() method before a request is available, or outside a middleware, the auth() helper or any request-specific data may be null.
@vincent15000 how were you trying to add to the Context in the AppServiceProvider?
not sure why you can't do this via cache, but if storage is a concern have you considered the array driver?
@krisi_gjika What's an array driver ?
@vincent15000 the array driver of the cache I mean, basically in-memory cache that lives only for current request
@krisi_gjika I need the data to be accessible all the time during the authenticated session.
@vincent15000 so push it on the session? or prefix the cache key by the session ID
@vincent15000 that wasn't clear from the OP, it seemed that you only needed the data shared in the context of a single Request; consequently, the Context is not a viable solution.
Usually session would be used.
@jlrdw I will probably use session, it seems to difficult to do another way and perhaps no real reason to not use session.
The only problem is that I will need to refresh the session from different places in my code, I wanted to avoid this.
I need to share settings from the authenticated user company.
What kind of data are you sharing?
One option is to use the service container, if it makes sense in your case. For example, I use it to share dynamically resolved settings:
// Service provider:
$this->app->singleton('settings', fn() => $this->getSettings());
// Elsewhere in the app:
$something = app('settings')['something'];
@JussiMannisto This could be interesting, I need to share settings data, but I need to load them from the authenticated user company and this is impossible from the service provider (no access to the authenticated user).
@vincent15000 The dependency is bound via a callback, which only executes when the dependency is resolved — not during the register method of the service provider. That means you can get the user using the request() helper in the callback:
$this->app->bind('me', fn() => request()?->user());
Now, calling app('me') would return the authenticated user. If you called it in an Artisan command, or before the auth middleware is run, you'd get null.
You might want to use bind() instead of singleton() if you do this. Singleton creates the dependency once, on the first resolve call, then returns the same instance on all subsequent calls. bind() will run the closure every time and return a new instance. That way you don't get stuck with null if you try to resolve it before the user object is available. Not that you should be doing that, but still.
I'd strongly suggest caching the settings per-company instead of hitting the DB every time they're needed. And you probably don't want to be resolving it all the time, but instead use something like View::share() in a middleware to share it with all views.
I'm not saying that using the app container is necessarily the best in your case, but it's an option.
Please or to participate in this conversation.