首页 文章

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

提问于
浏览
39

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

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

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

11 回答

  • 3

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

  • 3

    好吧,我将完全忽略其他答案充满的过度工程和假设的荒谬数量,并选择简单的选项 .

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

    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 .

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

  • 3

    使用Config类:

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

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

    在运行时设置的配置值仅为当前请求设置,不会转移到后续请求 .

  • 20

    在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() {...
    
  • -3

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

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

    现在在 routescontrollerviews 中,您可以使用它来访问它

    Config::get('siteVars.supportEmail')
    

    在视图中,如果我这样

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

    它将给出email@gmail.com

    希望这可以帮助 .

  • 37

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

    像(简化示例):

    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() 就会返回缓存的值 .

  • 5

    这里使用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/

  • 5

    我知道,5.4仍然需要这个,我只是遇到了同样的问题,但没有一个答案足够干净,所以我尝试用 ServiceProviders 完成可用性 . 这是我做的:

    • 创建了提供者 SettingsServiceProvider
    php artisan make:provider SettingsServiceProvider
    
    • 创建了我需要的模型( GlobalSettings
    php artisan make:model GlobalSettings
    
    • \App\Providers\SettingsServiceProvider 中编辑了生成的 register 方法 . 如您所见,我使用 Setting::all() 使用eloquent模型检索我的设置 .
    public function register()
        {
            $this->app->singleton('App\GlobalSettings', 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' => [
            // [...]
    
            App\Providers\SettingsServiceProvider::class
        ]
    
    • 使用 php artisan config:cache 清除配置缓存后,您可以使用单例作为如下 .
    $foo = app(App\GlobalSettings::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") }}
    
  • 35
    View::share('site_settings', $site_settings);
    

    添加

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

    它是全局变量 .

  • 2

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

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

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

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

    并使用以下任何刀片:

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

    有两种选择:

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

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

    湾如果它是静态函数,您可以通过类名轻松访问它 .

    C . 确保在composer文件中的autoload类映射中包含“app / libraries” .

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

    配置::得到( '变量名称');

    希望这可以帮助 .

    编辑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();
    

相关问题