Make a variable available in all controllers

Viewed 87

I am not sure the title of the question is clear, so I will try to explain it in details.

I want to execute a piece of code in every controller automatically, assign the result to a variable that will be globally accessible everywhere.

So the code that need to be run will be like this:

function getLanguage() {
    session('lang') ? session('lang') : 'en';
}
$LANG = getLanguage();

In any controller I need to access that variable like this:

myModel::all($LANG);

Also in the view, it would be helpful to access that variable as well (if possible)

<div> User language: {{$LANG}}</div>

Is there any place where I can execute that piece of code automatically?

2 Answers
  • Create a middleware
  • Add new middleware to App\Http\Kernels $middleware property, if you want it to run on every request. You may also put into $middlewareGroups property's web key.
  • Your middleware's handle method will be like this
public function handle(Request $request, Closure $next)
{
    Config::set('some-name.some-sub-name', session('lang') ?: 'en');

    return $next($request);
}
  • You will be updating a config in your middleware. This config has to be set only in this middleware to prevent possible problems of shared global state. (it is also important to be unique)
  • Then you can use it with config('some-name.some-sub-name')

In your use-case, you should implement a global middleware which sets the locale as you wish

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Session\SessionManager;
use Illuminate\Contracts\Foundation\Application;

class CheckLocale
{
    /**
     * The application instance.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected $app;

    /**
     * The session manager instance.
     *
     * @var \Illuminate\Session\SessionManager
     */
    protected $sessionManager;


    public function __construct(Application $app, SessionManager $sessionManager)
    {
        $this->app = $app;
        $this->sessionManager = $sessionManager;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        $this->app->setLocale($this->sessionManager->get('lang', 'en'));

        return $next($request);
    }
}

After setting it as a global middleware, you can access it wherever you need it from a controller or view

Controller

public function foo(Application $app)
{
    $lang = $app->getLocale();
}

In a Blade view

@inject('app', Illuminate\Contracts\Foundation\Application::class)

{{ $app->getLocale() }}

For any other variable, you may directly use Laravel container

In a service provider register method:

$this->app->singleton('lang', function ($app) {
    return $app['session']->get('lang', 'en');
});

And wherever else

app('lang');
Related