global variable for all controller and views

In Laravel I have a table settings and i have fetched complete data from the table in the BaseController, as following

public function __construct() 
{
    // Fetch the Site Settings object
    $site_settings = Setting::all();
    View::share('site_settings', $site_settings);
}

Now i want to access $site_settings. in all other controllers and views so that i don't need to write the same code again and again, so anybody please tell me the solution or any other way so i can fetch the data from the table once and use it in all controllers and view.

Answers


At first, a config file is appropriate for this kind of things but you may also use another approach, which is as given below (Laravel - 4):

// You can keep this in your filters.php file
App::before(function($request) {
    App::singleton('site_settings', function(){
        return Setting::all();
    });

    // If you use this line of code then it'll be available in any view
    // as $site_settings but you may also use app('site_settings') as well
    View::share('site_settings', app('site_settings'));
});

To get the same data in any controller you may use:

$site_settings = app('site_settings');

There are many ways, just use one or another, which one you prefer but I'm using the Container.


Okay, I'm going to completely ignore the ridiculous amount of over engineering and assumptions that the other answers are rife with, and go with the simple option.

If you're okay for there to be a single database call during each request, then the method is simple, alarmingly so:

class BaseController extends \Controller
{

    protected $site_settings;

    public function __construct() 
    {
        // Fetch the Site Settings object
        $this->site_settings = Setting::all();
        View::share('site_settings', $this->site_settings);
    }

}

Now providing that all of your controllers extend this BaseController, they can just do $this->site_settings.

If you wish to limit the amount of queries across multiple requests, you could use a caching solution as previously provided, but based on your question, the simple answer is a class property.


Use the Config class:

Config::set('site_settings', $site_settings);

Config::get('site_settings');

http://laravel.com/docs/4.2/configuration

Configuration values that are set at run-time are only set for the current request, and will not be carried over to subsequent requests.


In Laravel, 5+ you can create a file in the config folder and create variables in that and use that across the app. For instance, I want to store some information based on the site. I create a file called siteVars.php, which looks like this

<?php
return [
    'supportEmail' => 'email@gmail.com',
    'adminEmail' => 'admin@sitename.com'
];

Now in the routes, controller, views you can access it using

Config::get('siteVars.supportEmail')

In the views if I this

{{ Config::get('siteVars.supportEmail') }}

It will give email@gmail.com

Hope this helps.


In Laravel 5.1 I needed a global variable populated with model data accessible in all views.

I followed a similar approach to ollieread's answer and was able to use my variable ($notifications) in any view.

My controller location: /app/Http/Controllers/Controller.php

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

use App\Models\Main as MainModel;
use View;

abstract class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function __construct() {
        $oMainM = new MainModel;
        $notifications = $oMainM->get_notifications();
        View::share('notifications', $notifications);
    }
}

My model location: /app/Models/Main.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DB;

class Main extends Model
{
    public function get_notifications() {...

If you are worried about repeated database access, make sure that you have some kind of caching built into your method so that database calls are only made once per page request.

Something like (simplified example):

class Settings {

    static protected $all;

    static public function cachedAll() {
        if (empty(self::$all)) {
           self::$all = self::all();
        }
        return self::$all;
    }
}

Then you would access Settings::cachedAll() instead of all() and this would only make one database call per page request. Subsequent calls will use the already-retrieved contents cached in the class variable.

The above example is super simple, and uses an in-memory cache so it only lasts for the single request. If you wanted to, you could use Laravel's caching (using Redis or Memcached) to persist your settings across multiple requests. You can read more about the very simple caching options here:

http://laravel.com/docs/cache

For example you could add a method to your Settings model that looks like:

static public function getSettings() {
    $settings = Cache::remember('settings', 60, function() {
        return Settings::all();
    });
    return $settings;
}

This would only make a database call every 60 minutes otherwise it would return the cached value whenever you call Settings::getSettings().


Most popular answers here with BaseController didn't worked for me on Laravel 5.4, but they have worked on 5.3. No idea why.

I have found a way which works on Laravel 5.4 and gives variables even for views which are skipping controllers. And, of course, you can get variables from the database.

add in your app/Providers/AppServiceProvider.php

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Using view composer to set following variables globally
        view()->composer('*',function($view) {
            $view->with('user', Auth::user());
            $view->with('social', Social::all()); 
            // if you need to access in controller and views:
            Config::set('something', $something); 
        });
    }
}

credit: http://laraveldaily.com/global-variables-in-base-controller/


I see, that this is still needed for 5.4+ and I just had the same problem, but none of the answers were clean enough, so I tried to accomplish the availability with ServiceProviders. Here is what i did:

  1. Created the Provider SettingsServiceProvider
    php artisan make:provider SettingsServiceProvider
  1. Created the Model i needed (GlobalSettings)
    php artisan make:model GlobalSettings
  1. Edited the generated register method in \App\Providers\SettingsServiceProvider. As you can see, I retrieve my settings using the eloquent model for it with Setting::all().
 

    public function register()
    {
        $this->app->singleton('App\GlobalSettings', function ($app) {
            return new GlobalSettings(Setting::all());
        });
    }

 
  1. Defined some useful parameters and methods (including the constructor with the needed Collection parameter) in GlobalSettings
 

    class GlobalSettings extends Model
    {
        protected $settings;
        protected $keyValuePair;

        public function __construct(Collection $settings)
        {
            $this->settings = $settings;
            foreach ($settings as $setting){
                $this->keyValuePair[$setting->key] = $setting->value;
            }
        }

        public function has(string $key){ /* check key exists */ }
        public function contains(string $key){ /* check value exists */ }
        public function get(string $key){ /* get by key */ }
    }

 
  1. At last I registered the provider in config/app.php
 

    'providers' => [
        // [...]

        App\Providers\SettingsServiceProvider::class
    ]

 
  1. After clearing the config cache with php artisan config:cache you can use your singleton as follows.
 

    $foo = app(App\GlobalSettings::class);
    echo $foo->has("company") ? $foo->get("company") : "Stack Exchange Inc.";

 

You can read more about service containers and service providers in Laravel Docs > Service Container and Laravel Docs > Service Providers.

This is my first answer and I had not much time to write it down, so the formatting ist a bit spacey, but I hope you get everything.


I forgot to include the boot method of SettingsServiceProvider, to make the settings variable global available in views, so here you go:

 

    public function boot(GlobalSettings $settinsInstance)
    {
        View::share('globalsettings', $settinsInstance);
    }

 

Before the boot methods are called all providers have been registered, so we can just use our GlobalSettings instance as parameter, so it can be injected by Laravel.

In blade template:

 

    {{ $globalsettings->get("company") }}

 

View::share('site_settings', $site_settings);

Add to

app->Providers->AppServiceProvider file boot method

it's global variable.


In Laravel 5+, to set a variable just once and access it 'globally', I find it easiest to just add it as an attribute to the Request:

$request->attributes->add(['myVar' => $myVar]);

Then you can access it from any of your controllers using:

$myVar = $request->get('myVar');

and from any of your blades using:

{{ Request::get('myVar') }}

You can also use Laravel helper which I'm using. Just create Helpers folder under App folder then add the following code:

namespace App\Helpers;
Use SettingModel;
class SiteHelper
{
    public static function settings()
    {
        if(null !== session('settings')){
          $settings = session('settings');
        }else{
          $settings = SettingModel::all();
          session(['settings' => $settings]);
        }
        return $settings;
    }
}

then add it on you config > app.php under alliases

'aliases' => [
....
'Site' => App\Helpers\SiteHelper::class,
]

1. To Use in Controller

use Site;
class SettingsController extends Controller
{
    public function index()
    {
        $settings = Site::settings();
        return $settings;
    }
}

2. To Use in View:

Site::settings()

I have found a better way which works on Laravel 5.5 and makes variables accessible by views. And you can retrieve data from the database, do your logic by importing your Model just as you would in your controller.

The "*" means you are referencing all views, if you research more you can choose views to affect.

add in your app/Providers/AppServiceProvider.php

<?php

    namespace App\Providers;

    use Illuminate\Contracts\View\View;

    use Illuminate\Support\ServiceProvider;
    use App\Setting;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
    */
    public function boot()
    {
        // Fetch the Site Settings object
        view()->composer('*', function(View $view) {
            $site_settings = Setting::all();
            $view->with('site_settings', $site_settings);
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {

    }
}

There are two options:

  1. Create a php class file inside app/libraries/YourClassFile.php

    a. Any function you create in it would be easily accessible in all the views and controllers.

    b. If it is a static function you can easily access it by the class name.

    c. Make sure you inclued "app/libraries" in autoload classmap in composer file.

  2. In app/config/app.php create a variable and you can reference the same using

    Config::get('variable_name');

Hope this helps.

Edit 1:

Example for my 1st point:

// app/libraries/DefaultFunctions.php

class DefaultFunctions{

    public static function getSomeValue(){
     // Fetch the Site Settings object
     $site_settings = Setting::all();
     return $site_settings; 
    }
}

//composer.json

"autoload": {
        "classmap": [
..
..
..  
        "app/libraries" // add the libraries to access globaly.
        ]
    }

 //YourController.php

   $default_functions  = new DefaultFunctions();
    $default_functions->getSomeValue();

Need Your Help

Preserving ORDER BY in SELECT INTO

sql-server tsql sql-order-by select-into

I have a T-SQL query that takes data from one table and copies it into a new table but only rows meeting a certain condition: