所有控制器和视图的全局变量



在Laravel中,我有一个表设置,我已经从BaseController中的表中获取了完整的数据,如下所示

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

现在我想访问$site_settings。在所有其他控制器和视图中,所以我不需要一次又一次地编写相同的代码,所以有人请告诉我解决方案或任何其他方式,这样我就可以从表中获取数据,并在所有控制器和视图中使用它。

好吧,我将完全忽略其他答案中充斥的荒谬的过度工程和假设,并使用简单的选项。

如果您同意在每个请求期间都有一个数据库调用,那么该方法很简单,非常简单:

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);
    }
}

现在提供你所有的控制器扩展这个BaseController,他们可以只做$this->site_settings

如果您希望限制跨多个请求的查询数量,您可以使用前面提供的缓存解决方案,但是根据您的问题,简单的答案是类属性。

首先,配置文件适合于这种事情,但您也可以使用另一种方法,如下所示(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'));
});

要在任何控制器中获得相同的数据,您可以使用:

$site_settings = app('site_settings');

有很多方法,只是使用一个或另一个,你喜欢哪个,但我使用的是Container

使用配置类:

Config::set('site_settings', $site_settings);
Config::get('site_settings');
http://laravel.com/docs/4.2/configuration

在运行时设置的配置值仅为当前请求设置,不会传递到后续请求。

在Laravel中,你可以在config文件夹中创建一个文件,并在其中创建变量,然后在整个应用程序中使用它。例如,我想存储一些基于网站的信息。我创建了一个名为site_vars.php的文件,它看起来像这样

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

现在在routes, controller, views中,您可以使用

访问它
Config::get('site_vars.supportEmail')

在视图中如果I this

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

它会给出email@gmail.com

希望对你有帮助。

编辑- 您也可以在.env文件中定义变量并在这里使用它们。在我看来,这是最好的方法,因为它使您能够灵活地在本地机器上使用您想要的值。

那么,你可以在数组

中这样做
'supportEmail' => env('SUPPORT_EMAIL', 'defaultmail@gmail.com')

重要—这样做之后,不要忘记在生产环境

上执行此操作。
php artisan config:cache

如果仍然有一些问题,那么你可以这样做(通常它不会发生,但如果它发生了)

php artisan cache:clear
php artisan config:cache

在你的local env中,总是在这个之后添加

php artisan config:clear 

不将配置变量缓存到本地总是一个好习惯。在缓存的情况下,这将删除缓存并加载新的更改。

我明白了,这仍然需要5.4+,我只是有同样的问题,但没有一个答案是足够干净的,所以我试图完成ServiceProviders的可用性。以下是我所做的:

  1. 创建提供程序SettingsServiceProvider
<>之前设置服务提供商之前
  • 创建我需要的模型(GlobalSettings)
  • <>之前模型全局设置之前
  • AppProvidersSettingsServiceProvider中编辑生成的register方法。正如您所看到的,我使用Setting::all()的雄辩模型检索我的设置。
     
        public function register()
        {
            $this->app->singleton('AppGlobalSettings', function ($app) {
                return new GlobalSettings(Setting::all());
            });
        }
     
  • GlobalSettings
  • 中定义了一些有用的参数和方法(包括需要Collection参数的构造函数)
     
        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 */ }
        }
     
  • 最后我在config/app.php
  • 注册了提供商
     
        'providers' => [
            // [...]
            AppProvidersSettingsServiceProvider::class
        ]
     
  • 在使用php artisan config:cache清除配置缓存后,您可以按如下方式使用您的单例。
     
        $foo = app(AppGlobalSettings::class);
        echo $foo->has("company") ? $foo->get("company") : "Stack Exchange Inc.";
     

    你可以在Laravel Docs> service Container和Laravel Docs> service providers中阅读更多关于服务容器和服务提供商的信息。

    这是我的第一个答案,我没有太多的时间写下来,所以格式列表有点空格,但我希望你能得到所有的


    我忘了包含SettingsServiceProviderboot方法,以使设置变量在视图中可用,所以在这里:

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

    在启动方法被调用之前,所有的提供者都已经注册了,所以我们可以只使用我们的GlobalSettings实例作为参数,这样它就可以被Laravel注入。

    叶片模板:

    <>以前 {{ $globalsettings->get("company") }}
  • View::share('site_settings', $site_settings);
    

    添加到

    app->Providers->AppServiceProvider文件启动方法

    全局变量

    这里最流行的关于BaseController的答案在Laravel 5.4上不适合我,但它们在5.3上可以工作。不知道为什么。

    我找到了一种方法,可以在Laravel 5.4上工作,甚至可以为跳过控制器的视图提供变量。当然,您还可以从数据库中获取变量。

    添加你的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/

    在Laravel 5+中,要设置一个变量只一次并"全局"访问它,我发现最简单的是将它作为一个属性添加到Request:

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

    然后你可以从你的任何控制器访问它:

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

    和从任何刀片使用:

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

    在Laravel 5.1中,我需要一个全局变量填充所有视图中可访问的模型数据。

    我采用了与olliread的答案类似的方法,并且能够在任何视图中使用我的变量($notifications)。

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

    <?php
    namespace AppHttpControllers;
    use IlluminateFoundationBusDispatchesJobs;
    use IlluminateRoutingController as BaseController;
    use IlluminateFoundationValidationValidatesRequests;
    use IlluminateFoundationAuthAccessAuthorizesRequests;
    use AppModelsMain 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);
        }
    }
    

    我的模型位置:/app/Models/Main.php

    namespace AppModels;
    use IlluminateDatabaseEloquentModel;
    use DB;
    class Main extends Model
    {
        public function get_notifications() {...
    

    我找到了一种更好的方法,可以在Laravel 5.5上工作,并且可以通过视图访问变量。您可以从数据库中检索数据,通过导入模型来执行逻辑操作,就像在控制器中一样。

    "*"表示你引用了所有视图,如果你研究得更多,你可以选择要影响的视图。

    add in your app/Providers/AppServiceProvider.php

    <?php
        namespace AppProviders;
        use IlluminateContractsViewView;
        use IlluminateSupportServiceProvider;
        use AppSetting;
    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()
        {
        }
    }
    

    如果您担心重复访问数据库,请确保在您的方法中内置了某种缓存,以便每个页面请求只进行一次数据库调用。

    类似于(简化的例子):

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

    那么您将访问Settings::cachedAll()而不是all(),这将只使每个页面请求调用一个数据库。后续调用将使用缓存在类变量中的已经检索到的内容。

    上面的例子非常简单,并且使用了内存缓存,所以它只适用于单个请求。如果你愿意,你可以使用Laravel的缓存(使用Redis或Memcached)在多个请求中持久化你的设置。您可以在这里阅读更多关于非常简单的缓存选项:

    http://laravel.com/docs/cache

    例如,你可以添加一个方法到你的Settings模型,看起来像:

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

    这只会使数据库调用每60分钟,否则它会返回缓存的值,每当你调用Settings::getSettings() .

    你也可以使用Laravel助手我正在使用。只需在App文件夹下创建Helpers文件夹然后添加以下代码:

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

    然后添加到config> app.php中的alliases

    'aliases' => [
    ....
    'Site' => AppHelpersSiteHelper::class,
    ]
    

    1。控制器

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

    2。视图:

    Site::settings()
    

    在控制器中使用的全局变量;你可以在AppServiceProvider中这样设置:

    public function boot()
    {
        $company=DB::table('company')->where('id',1)->first();
        config(['yourconfig.company' => $company]);
    }
    
    使用

    config('yourconfig.company');
    

    使用middlwares

    1-创建任意名称的中间件

    <?php
    namespace AppHttpMiddleware;
    use Closure;
    use IlluminateSupportFacadesView;
    class GlobalData
    {
        public function handle($request, Closure $next)
        {
            // edit this section and share what do you want
            $site_settings = Setting::all();
            View::share('site_settings', $site_settings);
            return $next($request);
        }
    }
    

    2-在Kernal.php

    中注册你的中间件
    protected $routeMiddleware = [
     .
     ...
     'globaldata' => GlobalData::class,
     ]
    

    现在将您的路由与globaldata中间件分组

    Route::group(['middleware' => ['globaldata']], function () {
    //  add routes that need to site_settings
    }
    

    在file - vendor autolload .php中,按如下方式定义变量gobals,应该位于最上面一行。

    $global_variable = "Some value";//the global variable
    

    在任何地方访问全局变量:-

    $GLOBALS['global_variable'];
    

    享受吧

    我知道我迟到了,但这是我找到的最简单的方法。在app/Providers/AppServiceProvider.php中,在引导方法中添加变量。在这里,我从DB检索所有国家:

    public function boot()
    {
        // Global variables
        view()->composer('*',function($view) {
            $view->with('countries', Country::all());
        });
    }
    

    有两个选项:

    1. 在app/libraries/YourClassFile.php中创建一个php类文件

      。您在其中创建的任何函数都可以在所有视图和控制器中轻松访问。

      b。如果它是一个静态函数,您可以通过类名轻松访问它。

      c。确保你在自动加载类映射中包含了"app/libraries"

    2. 在app/config/app.php中创建一个变量,你可以使用

      来引用它

      配置:get (variable_name);

    希望对你有帮助。

    编辑1:

    第一个例子:

    // 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();
    

    相关内容

    • 没有找到相关文章

    最新更新