Laravel 5 - 所有模板中都可用的全局 Blade 视图变量

Posted

技术标签:

【中文标题】Laravel 5 - 所有模板中都可用的全局 Blade 视图变量【英文标题】:Laravel 5 - global Blade view variable available in all templates 【发布时间】:2015-06-25 06:50:54 【问题描述】:

我如何在 Laravel 5 中创建全局变量,该变量将在所有 Blade 模板中可用?

【问题讨论】:

laravel.com/docs/5.0/views#view-composers 【参考方案1】:

选项 1:

你可以像这样使用view::share()

<?php namespace App\Http\Controllers;

use View;

//You can create a BaseController:

class BaseController extends Controller 

    public $variable1 = "I am Data";

    public function __construct() 

       $variable2 = "I am Data 2";


       View::share ( 'variable1', $this->variable1 );
       View::share ( 'variable2', $variable2 );
       View::share ( 'variable3', 'I am Data 3' );
       View::share ( 'variable4', ['name'=>'Franky','address'=>'Mars'] );
      



class HomeController extends BaseController 

    //if you have a constructor in other controllers you need call constructor of parent controller (i.e. BaseController) like so:

    public function __construct()
       parent::__construct();
    

    public function Index()
      //All variable will be available in views
      return view('home');
    


选项 2: 使用作曲家:

    app\Composers\HomeComposer.php 创建一个作曲家文件

注意:如果 app\Composers 不存在,则创建它

<?php namespace App\Composers;

class HomeComposer


    public function compose($view)
    
        //Add your variables
        $view->with('variable1',      'I am Data')
             ->with('variable2',      'I am Data 2');
    

然后您可以通过这样做将作曲家附加到任何视图

<?php namespace App\Http\Controllers;

use View;

class HomeController extends Controller


    public function __construct()

        View::composers([
            'App\Composers\HomeComposer'  => ['home'] //attaches HomeComposer to home.blade.php
        ]);

    

    public function Index()
        return view('home');
    


选项 3: 将 Composer 添加到服务提供者,在 Laravel 5 中,我更喜欢将 Composer 放在 App\Providers\ViewServiceProvider 中

    app\Composers\HomeComposer.php创建一个作曲家文件

    将 HomeComposer 添加到 App\Providers\ViewServiceProvider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use View;
use App\Composers\HomeComposer;
use Illuminate\Support\Facades\Blade;

class ViewServiceProvider extends ServiceProvider

    /**
     * Register any application services.
 *
     * @return void
     */
    public function register()
    
        //
    

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    
        //add to all views
        view()->composer('*', HomeComposer::class);
        //add to only home view 
        //view()->composer('home', HomeComposer::class);
    

【讨论】:

您的回复确实帮助了我选择选项 1,但如果您尝试访问 $user = Auth::user(); 并将 $user 变量传递给所有刀片模板,包括标题和内容部分,该怎么办?我通过将 $user 变量放在 BaseController 中然后共享它来尝试这个,但是如果我 var_dump $user 我会在数组中得到一堆受保护的值。基本上我希望能够在所有模板和视图中访问整个应用程序中的所有 auth 用户变量。看起来很简单,但花了好几个小时才弄明白。 实际上这行得通:&lt;?= $user['name']; ?&gt; 但这行不通: $user-&gt;name @Chad Priddle 这应该适用于数组 $user['name'] ,而这适用于对象 $user-&gt;name 对于选项 1,我得到:Class 'App\Http\Controllers\View' not found 推荐的方式应该是:有View::share的服务商。请注意,每个加载的模板都会调用 composer "*" 选项:如果您进行数据库调用,它将为每个视图和子视图完成!【参考方案2】:

Create a new Service Provider as suggested in here

将您的新服务提供者添加到配置文件 (config/app.php)。

在新服务提供者的启动方法中使用:

View::share( 'something_cool', 'this is a cool shared variable' );

现在您可以在所有视图中使用 $something_cool。

希望这会有所帮助。

【讨论】:

另外,它是 artisan down 之后的 503 页面中多次使用的变量的终极解决方案。 将应用的版本字符串作为缓存破坏参数注入或将其显示在更新时的页脚是其他解决方案的苦差事。 (不过,为此使用 env 变量可能是最干净的解决方案) 这是一个比批准的答案更好的解决方案 我认为主要区别在于用户询问如何在所有模板中使用 global 变量。使用公认的解决方案,用户需要记住扩展 BaseController 并调用 parent::construct,使用 ViewComposer 解决方案他需要在每个控制器构造方法中调用 View::composers 以使变量可用。 这应该被选作答案! 这是我最好的回答并且易于使用。【参考方案3】:

寻找相同问题的解决方案,并在 Laravel 文档中找到最佳解决方案。只需像这样在AppServiceProvider 中使用View::share

View::share('key', 'value');

详情here.

【讨论】:

不适用于 Auth::user() - 在那个状态下它是 null - 但是这个地方是正确的,我只需要通过 composer View::composer('*', function($view) $view-&gt;with('current_user', Auth::user()); 而不是共享来添加它。跨度> 【参考方案4】:

您可以使用view composers 执行此操作。加载模板时执行视图编辑器。您可以为该视图传入具有附加功能的闭包。使用视图作曲家,您可以使用通配符。要为每个视图创建视图编辑器,只需使用 *

View::composer('*', function($view)

    $view->with('variable','Test value');
);

您也可以在没有闭包的情况下执行此操作,如您在文档中看到的那样。

View::composer('*', 'App\Http\ViewComposers\ProfileComposer');

配置文件编写器类必须有一个 compose 方法。

视图合成器在视图被渲染时被执行。 Laravel 也有视图创建者。这些是在实例化视图时执行的。

您还可以选择将BaseController 与 setupLayout 方法一起使用。然后,您将加载的每个视图都通过 setupLayout 方法加载,该方法添加了一些额外的数据。但是,通过使用视图作曲家,您可以确定代码已被执行。但是使用 BaseController 方法,您可以拥有更大的灵活性,因为您可以跳过额外数据的加载。

编辑:正如 Nic Gutierrez 所述,您还可以使用视图共享。

【讨论】:

this 和 view()-&gt;share 之间的区别在于,这仅在使用视图时运行 - 但使用 view()-&gt;share 无论如何都会运行 - 您可能会在 API 调用中返回一些 JSON示例 - 不使用视图。【参考方案5】:

另外,您可以在Route.php 文件中执行此操作:

view()->share('variableName', $variable);

【讨论】:

【参考方案6】:

我宁愿使用带有view() 外观助手的中间件。 (Laravel 5.x)

中间件更易于维护,不会在控制器类树中造成混乱。

步骤

创建中间件

/app/Http/Middleware/TimezoneReset.php

要创建中间件,您可以运行 php artisan make:middleware GlobalTimeConfig

share()你需要分享的数据

 <?php

    namespace App\Http\Middleware;

    use Closure;

    class GlobalTimeConfig
    
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        
            $time_settings = [
                'company_timezone' => 'UTC',
                'company_date_format' => 'Y-m-d H:i:s',
                'display_time' => true,
            ];

            view()->share('time_settings', $time_settings);

            return $next($request);
        
    

注册新创建的中间件

按照下面的示例将中间件添加到中间件路由组中

/app/Http/Kernel.php

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\GlobalTimeConfig::class,
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

从模板访问数据

在 View::share() 方法调用中使用给定键从任何模板访问数据

例如:

    Company timezone:  $time_settings['company_timezone'] 

编辑: Nic Gutierrez 的服务提供商答案可能是更好(或最佳)的解决方案。

【讨论】:

【参考方案7】:

你可以给数组不只是View::share('key', 'value'); 可以把数组像View::share(['key'=&gt;'value','key'=&gt;'value'])

【讨论】:

【参考方案8】:

您可以在Controller.php文件中添加:

use App\Category;

然后:

class Controller extends BaseController 
     public function __construct() 
        $categories = Category::All();
        \View::share('categories', $categories);
     

【讨论】:

【参考方案9】:

您可以将其刷入会话中,您可以在 .env 文件中定义它(静态变量)

【讨论】:

以上是关于Laravel 5 - 所有模板中都可用的全局 Blade 视图变量的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL - 全局变量并非在所有会话中都可用

Laravel 5:在视图模板中获取所有传递的数据

页面中所有表单的 Laravel 5 CSRF 全局令牌隐藏字段

Laravel 本地 vue 组件注册

PHP 超全局变量之$GLOBALS

Laravel 5.5 模型上的自定义软删除