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

时间:2014-08-07 18:19:46

标签: laravel laravel-4 global-variables

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

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

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

16 个答案:

答案 0 :(得分:39)

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

答案 1 :(得分:37)

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

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

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

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

答案 2 :(得分:21)

使用Config类:

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

Config::get('site_settings');

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

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

答案 3 :(得分:6)

在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

希望这有帮助。

答案 4 :(得分:5)

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

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

我的控制器位置:/app/Http/Controllers/Controller.php

namespace App\Models;

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

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

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

function traverseArray($array)
{
    // Loops through each element. If element again is array, function is recalled. If not, result is echoed.
    foreach ($array as $key => $value)
    {
        if (is_array($value))
        {
            Self::traverseArray($value); // Or
            // traverseArray($value);
        }
        else
        {
            echo $key . " = " . $value . "<br />\n";
        }
    }
}

答案 5 :(得分:3)

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

像(简化示例):

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()时它都会返回缓存的值。

答案 6 :(得分:3)

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

答案 7 :(得分:3)

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

  1. 创建了提供商SettingsServiceProvider
  2.     php artisan make:provider SettingsServiceProvider
    
    1. 创建了我需要的模型(GlobalSettings
    2.     php artisan make:model GlobalSettings
      
      1. register中修改了生成的\App\Providers\SettingsServiceProvider方法。如您所见,我使用Setting::all()的简单模型检索我的设置。
      2.  
        
            public function register()
            {
                $this->app->singleton('App\GlobalSettings', function ($app) {
                    return new GlobalSettings(Setting::all());
                });
            }
        
         
        1. Collection
        2. 中定义了一些有用的参数和方法(包括带有所需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
          2. 注册了提供商
             
            
                'providers' => [
                    // [...]
            
                    App\Providers\SettingsServiceProvider::class
                ]
            
             
            1. 使用php artisan config:cache清除配置缓存后,您可以按如下方式使用您的单例。
            2.  
              
                  $foo = app(App\GlobalSettings::class);
                  echo $foo->has("company") ? $foo->get("company") : "Stack Exchange Inc.";
              
               

              您可以在Laravel Docs中了解有关服务容器和服务提供商的更多信息&gt;

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

              我忘了添加boot SettingsServiceProvider方法,以使设置变量在视图中全局可用,所以请转到:

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

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

              在刀片模板中:

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

答案 8 :(得分:2)

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

添加到

app->Providers->AppServiceProvider文件引导方法

它的全局变量。

答案 9 :(得分:1)

在Laravel 5+中,要设置变量一次并全局访问它,我发现将其作为属性添加到请求中最简单:

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

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

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

并使用以下任意一种刀片:

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

答案 10 :(得分:1)

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

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

用法

config('yourconfig.company');

答案 11 :(得分:0)

您还可以使用我正在使用的 Laravel帮助程序。 只需在 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;
    }
}

然后将其添加到您在config> 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。要在视图中使用:

Site::settings()

答案 12 :(得分:0)

我发现了一种更好的方法,可以在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()
    {

    }
}

答案 13 :(得分:0)

使用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
}

答案 14 :(得分:0)

在文件-\ vendor \ autoload.php中,如下定义您的gobals变量,该变量应位于最上方。

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

在任何地方以:-

访问该全局变量
$GLOBALS['global_variable'];

享受:)

答案 15 :(得分:-3)

有两种选择:

  1. 在app / libraries / YourClassFile.php

    中创建一个php类文件

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

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

    ℃。确保你包括&#34; app / libraries&#34;在作曲家文件中的自动加载类图中。

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

    引用它

    配置::得到(&#39;变量名&#39);

  3. 希望这有帮助。

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