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

问题描述 投票:57回答:14

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

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

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

laravel laravel-4 global-variables
14个回答
47
投票
首先,配置文件适用于这种情况,但是您也可以使用另一种方法,如下所示(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

4
投票
在Laravel 5+中,只设置一个变量并“全局”访问它,我发现将其作为属性添加到R​​equest中是最简单的:

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


3
投票
我发现了一种更好的方法,可以在Laravel 5.5上运行,并使变量可以通过视图访问。您可以从数据库中检索数据,通过导入模型来执行逻辑,就像在控制器中一样。

“ *表示您正在引用所有视图,如果您进行更多研究,则可以选择要影响的视图。


0
投票
您还可以使用我正在使用的

Laravel helper。只需在App


0
投票
使用middlwares

1-创建具有任何名称的中间件


-3
投票
有两个选项:

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

45
投票
好吧,我将完全忽略荒谬的过度工程设计和其他答案充斥的假设,并采用简单的选择。

如果您可以在每个请求期间进行一次数据库调用,那么该方法很简单,令人震惊的是:

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

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


31
投票
使用配置类:

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

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

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


10
投票
在Laravel中,5岁以上,您可以在config文件夹中创建一个文件,并在其中创建变量,然后在整个应用程序中使用该文件。例如,我想根据站点存储一些信息。我创建了一个名为siteVars.php的文件,看起来像这样

<?php return [ 'supportEmail' => '[email protected]', 'adminEmail' => '[email protected]' ];

现在在routescontrollerviews中,您可以使用]进行访问>

Config::get('siteVars.supportEmail')

如果我这样做,在意见中>

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

它将给[email protected]

希望这会有所帮助。

我看到,对于5.4+来说仍然需要这样做,但是我也遇到了同样的问题,但是没有一个答案很干净,因此我尝试使用ServiceProviders实现可用性。这是我所做的:

    创建提供者SettingsServiceProvider
  • php artisan make:provider SettingsServiceProvider
    1. 创建了我需要的模型(GlobalSettings
  • php artisan make:model GlobalSettings
    1. register中编辑了生成的\App\Providers\SettingsServiceProvider方法。如您所见,我使用雄辩的模型并通过Setting::all()来检索我的设置。
  • public function register() { $this->app->singleton('App\GlobalSettings', function ($app) { return new GlobalSettings(Setting::all()); }); }
    1. Collection中定义了一些有用的参数和方法(包括带有所需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. 最后我在config/app.php中注册了提供商。>
  • 'providers' => [ // [...] App\Providers\SettingsServiceProvider::class ]
      php artisan config:cache清除配置缓存后,您可以按以下方式使用单例。
  • $foo = app(App\GlobalSettings::class); echo $foo->has("company") ? $foo->get("company") : "Stack Exchange Inc.";
    您可以在Laravel文档>服务容器和Laravel文档>服务提供商中阅读有关服务容器和服务提供商的更多信息。
  • 这是我的第一个答案,我没有太多的时间写下来,因此格式化有点麻烦,但是希望您能得到一切。


    我忘了包括bootSettingsServiceProvider方法,以使设置变量在视图中全局可用,因此您可以:

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

    在调用引导方法之前,所有提供程序都已注册,因此我们可以仅将GlobalSettings实例用作参数,以便可以由Laravel注入。

    在刀片模板中:

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

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

    我遵循了类似的方法来解决ollieread的问题,并且能够在任何视图中使用我的变量($ notifications)。

    我的控制器位置:/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); } }

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

    namespace App\Models; use Illuminate\Database\Eloquent\Model; use DB; class Main extends Model { public function get_notifications() {...

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

    类似(简化示例):

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

    然后您将访问Settings::cachedAll()而不是all(),并且每个页面请求只会进行一次数据库调用。后续调用将使用缓存在class变量中的已检索内容。

    上面的示例非常简单,并且使用了内存中的缓存,因此仅在单个请求时才持续。如果需要,可以使用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()时,它将返回缓存的值。

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

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

    在Laravel 5+中,只设置一个变量并“全局”访问它,我发现将其作为属性添加到R​​equest中是最简单的:

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

    然后您可以使用:从任何控制器访问它:

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

    以及使用以下任何刀片式服务器:

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

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

    “ *表示您正在引用所有视图,如果您进行更多研究,则可以选择要影响的视图。

    添加到您的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() { } }

    您还可以使用我正在使用的

    Laravel helper。只需在App

    文件夹下创建Helpers
    文件夹然后添加以下代码: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; } }
    然后将其添加到您的配置中>联盟下的app.php

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

    1。在

    Controller

    中使用use Site; class SettingsController extends Controller { public function index() { $settings = Site::settings(); return $settings; } }
    2。要在

    View中使用:

    Site::settings()
    使用middlwares

    1-创建具有任何名称的中间件

    <?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\View; 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, ]

    3-现在使用globaldata中间件对您的路线进行分组

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

    有两个选项:

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

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

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

    c。确保在composer文件的自动加载类映射中包含“应用程序/库”。

  • 在app / config / app.php中创建一个变量,您可以使用引用它

    Config :: 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();


    7
    投票
    我看到,对于5.4+来说仍然需要这样做,但是我也遇到了同样的问题,但是没有一个答案很干净,因此我尝试使用ServiceProviders实现可用性。这是我所做的:

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

    我遵循了类似的方法来解决ollieread的问题,并且能够在任何视图中使用我的变量($ notifications)。


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

    类似(简化示例):


    5
    投票
    View::share('site_settings', $site_settings);
    添加到

    5
    投票
    此处使用BaseController的大多数流行答案在Laravel 5.4上不适用于我,但在5.3上适用。不知道为什么。

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

    © www.soinside.com 2019 - 2024. All rights reserved.