global variable for all controller and views

后端 未结 16 2072
Happy的楠姐
Happy的楠姐 2020-11-27 15:54

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

public function __construct() 
{
             


        
相关标签:
16条回答
  • 2020-11-27 16:11

    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") }}
    
     
    0 讨论(0)
  • 2020-11-27 16:11
    View::share('site_settings', $site_settings);
    

    Add to

    app->Providers->AppServiceProvider file boot method

    it's global variable.

    0 讨论(0)
  • 2020-11-27 16:11

    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/

    0 讨论(0)
  • 2020-11-27 16:13

    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()
        {
    
        }
    }
    
    0 讨论(0)
  • 2020-11-27 16:13

    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()
    
    0 讨论(0)
  • 2020-11-27 16:16

    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().

    0 讨论(0)
提交回复
热议问题