【问题标题】:How to pass data to all views in Laravel 5?如何将数据传递给 Laravel 5 中的所有视图?
【发布时间】:2015-04-20 22:11:36
【问题描述】:

我希望在我的 Laravel 5 应用程序的所有视图中都可以访问一些默认数据。

我试图搜索它,但只找到 Laravel 4 的结果。我已阅读文档“与所有视图共享数据”here 但我不明白该怎么做。下面的代码应该放在哪里?

View::share('data', [1, 2, 3]);

感谢您的帮助。

【问题讨论】:

  • 嗯,你需要启动代码来管理这个需求吗?
  • 在服务提供者中使用 View::share 与数据库调用的结果在运行刷新数据库迁移或尝试使用无法访问的数据库连接运行黄昏时将错误输出应用程序(长故事, .env.dusk.local 仅在服务提供者运行后使用)。如下所述,基本控制器或中间件是最好的。
  • 在视图作曲家上使用* 时也要小心,特别是在使用数据库查询时,因为它针对每个包含的子视图、组件等运行,因此您最终可能会运行数百个不必要的查询,最好的办法是使用基本视图,例如layouts.app 然后根据需要向下传递数据。

标签: php laravel laravel-5


【解决方案1】:

这个目标可以通过不同的方法实现,

1.使用 BaseController

我喜欢设置的方式,我创建了一个扩展 Laravel 自己的 ControllerBaseController 类,并在那里设置了各种全局的东西。然后所有其他控制器都从 BaseController 扩展而来,而不是 Laravel 的控制器。

class BaseController extends Controller
{
  public function __construct()
  {
    //its just a dummy data object.
    $user = User::all();

    // Sharing is caring
    View::share('user', $user);
  }
}

2。使用过滤器

如果你知道你想要为整个应用程序中的每个请求的视图设置一些东西,你也可以通过在请求之前运行的过滤器来实现——这就是我在 Laravel 中处理 User 对象的方式.

App::before(function($request)
{
  // Set up global user object for views
  View::share('user', User::all());
});

您可以定义自己的过滤器

Route::filter('user-filter', function() {
    View::share('user', User::all());
});

并通过简单的过滤器调用来调用它。

根据版本 5 更新。*

3.使用中间件

View::sharemiddleware 一起使用

Route::group(['middleware' => 'SomeMiddleware'], function(){
  // routes
});



class SomeMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

4.使用 View Composer

View Composer 还有助于以不同的方式将特定数据绑定到视图。您可以直接将变量绑定到特定视图或所有视图。例如,您可以根据需要创建自己的目录来存储视图编写器文件。并且这些视图编写器文件通过 Service 提供与视图的交互。

View Composer 方法可以使用不同的方式,第一个例子看起来很相似:

您可以创建一个App\Http\ViewComposers 目录。

服务提供商

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
    }
}

之后,将此提供程序添加到“提供程序”部分下的 config/app.php 中。

TestViewComposer

namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;

class TestViewComposer {

    public function compose(View $view) {
        $view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
    }
}

ViewName.blade.php

Here you are... {{$ViewComposerTestVariable}}

此方法仅对特定视图有帮助。但是,如果您想为所有视图触发 ViewComposer,我们必须将这个更改应用到 ServiceProvider。

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
    }
}

参考

Laravel Documentation

进一步澄清Laracast Episode

如果我还有什么不清楚的地方,请告诉我。

【讨论】:

  • 您的示例缺少 register() 方法 - 这不是可选的
  • @jonathan 感谢您指出,但示例仅包含需要注意的部分。与视图共享数据的视角。
  • 你把过滤器放在哪里?现在可能最正确的答案是使用中间件组laravel.com/docs/5.3/middleware#middleware-groups 或全局中间件
  • 这不是一个好主意,视图作曲家为每个单独的视图创建作曲家实例,这意味着如果您运行 1000 次循环,将创建 1000 个作曲家实例,并处理 1000 次触发事件这不是你想要的。
  • @RezaShadman 是正确的!我很难学到这一点。在我安装 laravel-debugbar 工具进行调查之前,我的应用程序运行得很慢。然后我意识到对于单个页面加载,所有 8 个查询都执行了大约 15 次。这是因为将为包含的每个刀片文件调用视图编辑器。也就是说,如果您使用星号 *。如果您不使用*,那么您应该没问题。
【解决方案2】:

您可以创建自己的service providerViewServiceProvider 名称很常见),也可以使用现有的AppServiceProvider

在您选择的提供程序中,将您的代码放入引导方法中。

public function boot() {
    view()->share('data', [1, 2, 3]);
}

这将使$data 变量在您的所有视图中都可以访问。

如果您更愿意使用外观而不是助手,请将view()-> 更改为View::,但不要忘记在文件顶部添加use View; p>

【讨论】:

  • 谢谢,工作得很好。引导功能是针对这种事情的还是您建议创建我自己的服务提供商?
  • 如果你只有一两件事要分享,把它放在AppServiceProvider 很好,但如果你有更多的东西,你应该考虑创建一个新的提供者。
  • 它工作正常,但我发现它今天不工作!使用composer update 也不起作用。实际上它根本没有触发boot()。我需要共享两个变量。
  • 请注意,如果您正在获取数据库记录,这将不起作用,因为它将在执行迁移之前被调用。因此,您基本上是在尝试在数据库记录存在之前获取它们。至少对我来说似乎是这样。
  • 不幸的是,这似乎不适用于共享已登录的用户 Auth::user(),Safoor 的 #1 答案,在此下方:)
【解决方案3】:

我发现这是最简单的。创建一个新的提供者并使用'*' 通配符将其附加到所有视图。也适用于 5.3 :-)

<?php

namespace App\Providers;

use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     * @return void
     */
    public function boot()
    {
        view()->composer('*', function ($view)
        {
            $user = request()->user();

            $view->with('user', $user);
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

【讨论】:

  • 将此提供程序添加到您的配置/应用程序“App\Providers\ViewServiceProvider::class”中的提供程序数组中,
【解决方案4】:

最好的方法是使用View::share('var', $value);共享变量

使用"*"作曲的问题:

考虑以下方法:

<?php
// from AppServiceProvider::boot()
$viewFactory = $this->app->make(Factory::class);

$viewFacrory->compose('*', GlobalComposer::class);

从示例刀片视图:

  @for($i = 0; $i<1000; $i++)
    @include('some_partial_view_to_display_i', ['toDisplay' => $i])
  @endfor

会发生什么?

  • GlobalComposer 类被实例化 1000 次使用 App::make
  • 事件composing:some_partial_view_to_display_i被处理 1000 次。
  • GlobalComposer 类中的 compose 函数被调用了 1000 次。

但局部视图some_partial_view_to_display_iGlobalComposer组成的变量无关,但会大大增加渲染时间。

最佳方法?

在分组中间件中使用View::share

Route::group(['middleware' => 'WebMiddleware'], function(){
  // Web routes
});

Route::group(['prefix' => 'api'], function (){

});

class WebMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

更新

如果您使用的是通过中间件管道计算的东西,您可以简单地侦听到正确的 事件 或将视图共享中间件放在管道的最后一个底部.

【讨论】:

    【解决方案5】:

    在文档中:

    通常,您会在服务中调用 share 方法 提供者的引导方法。您可以随意将它们添加到 AppServiceProvider 或生成一个单独的服务提供者来容纳 他们。

    我同意 Marwelln 的观点,只需将其放在引导功能中的AppServiceProvider 中即可:

    public function boot() {
        View::share('youVarName', [1, 2, 3]);
    }
    

    我建议为变量使用特定名称,以避免与其他非“全局”变量混淆或出错。

    【讨论】:

      【解决方案6】:

      文档是听到https://laravel.com/docs/5.4/views#view-composers,但我会分解它

      1. 在应用程序的根目录中查找目录 app\Providers 并创建文件 ComposerServiceProvider.php 并将下面的文本复制并粘贴到其中并保存.

        <?php
            namespace App\Providers;
            use Illuminate\Support\Facades\View;
            use Illuminate\Support\ServiceProvider;
        
            class ComposerServiceProvider extends ServiceProvider
            {
                /**
                * Register bindings in the container.
                *
                * @return void
                */
            public function boot()
            {
                // Using class based composers...
                View::composer(
                    'profile', 'App\Http\ViewComposers\ProfileComposer'
                );
        
                // Using Closure based composers...
                View::composer('dashboard', function ($view) {
                    //
                });
            }
        
            /**
            * Register the service provider.
            *
            * @return void
            */
            public function register()
            {
                //
            }
        }
        
      2. 从应用程序的根目录打开 Config/app.php 并在文件中查找 Providers 部分,然后复制并粘贴此 'App\Providers\ComposerServiceProvider', 到数组。

      通过这样做,我们创建了 Composer 服务提供者。当您像 http://yourdomain/something/profile 那样使用视图配置文件运行应用程序时,将调用服务提供者 ComposerServiceProvider 并实例化 App\Http\ViewComposers\ProfileComposer 类并调用该方法Composer 由于下面的代码在 boot 方法或函数中。

       // Using class based composers...
       View::composer(
         'profile', 'App\Http\ViewComposers\ProfileComposer'
       );
      
      1. 如果您刷新应用程序,您将收到错误,因为类 App\Http\ViewComposers\ProfileComposer 尚不存在。现在让我们创建它。

      进入目录路径app/Http

      • 创建名为 ViewComposers

      • 的目录
      • 创建文件ProfileComposer.php

        class ProfileComposer
        {
            /**
            * The user repository implementation.
            *
            * @var UserRepository
            */
            protected $users;
        
            /**
            * Create a new profile composer.
            *
            * @param  UserRepository  $users
            * @return void
            */
            public function __construct(UserRepository $users)
            {
                // Dependencies automatically resolved by service container...
                $this->users = $users;
            }
        
            /**
            * Bind data to the view.
            *
            * @param  View  $view
            * @return void
            */
            public function compose(View $view)
            {
                $view->with('count', $this->users->count());
            }
        }
        

      现在转到您的视图或在本例中为 Profile.blade.php 并添加

      {{ $count }}
      

      这将显示个人资料页面上的用户数。

      显示所有页面上的计数变化

      // Using class based composers...
      View::composer(
          'profile', 'App\Http\ViewComposers\ProfileComposer'
      );
      

      // Using class based composers...
      View::composer(
          '*', 'App\Http\ViewComposers\ProfileComposer'
      );
      

      【讨论】:

      【解决方案7】:

      你有两个选择:

      1.通过App\Providers\AppServiceProvider中的‍Boot功能分享:

      public function boot()
      {
        view()->share('key', 'value');
      }
      

      并在任何视图文件中访问$key 变量。

      Note:请记住,您无法在此处访问当前的SessionAuthRoute 数据。仅当您要共享静态数据时,此选项才适用。假设您想根据当前用户、路由或任何您无法使用的自定义会话变量共享一些数据。

      2。使用辅助类:

      在应用程序的任何位置创建一个帮助类,并将其注册到 app.php 文件夹中的别名数组中的 config 文件中。

       'aliases' => [ 
         ...,
        'Helper' => App\HelperClass\Helper::class,
       ],
      

      并在 App 文件夹内的 HelperClass 文件夹中创建 Helper.php

      namespace App\HelperClass;
          
      class Helper
      {
          public static function Sample()
          {
              //Your Code Here
          }
      }
      

      并在任何地方访问它,例如Helper::Sample()

      你不会是 restricted 在这里使用 AuthRouteSession 或任何其他类。

      【讨论】:

      • 两者都不错,但是 .. 它们在 laravel 会话之前运行。
      【解决方案8】:

      我认为最好的方法是使用View Composers。如果有人来到这里并想找到如何使用 View Composers 的方式,请阅读我的答案 => How to share a variable across all views?

      【讨论】:

        【解决方案9】:

        文档在这里https://laravel.com/docs/5.4/views#view-composers 但我会分解它 1.在你的根目录中查找目录Providers,并为ComposerServiceProvider.php创建内容

        【讨论】:

          【解决方案10】:

          在您的配置文件夹中,您可以创建一个 php 文件名,例如“variable.php”,内容如下:

          <?php
          
            return [
              'versionNumber' => '122231',
            ];
          

          现在在所有视图中,您可以像这样使用它

          config('variable.versionNumber')
          

          【讨论】:

          • 在某些情况下我会这样做,因为信息是真正的全球性信息,您可以从任何地方访问它。出于这个原因,我将配置文件称为“global.php”,并在其中放置了我希望在代码的所有其他部分中可以访问的任何内容。唯一的限制是这是针对静态数据的,并且会被缓存。如果您有不断变化的数据,则不应以这种方式使用它。
          【解决方案11】:

          1) 在 (app\Providers\AppServiceProvider.php)

          // in boot function
                 view()->composer('*', function ($view) {
                      $data = User::messages();
                      $view->with('var_messages',$data);
                  });
          

          2) 在您的用户模型中

            public static function messages(){ // this is just example
                  $my_id = auth()->user()->id;
                  $data= Message::whereTo($my_id)->whereIs_read('0')->get(); 
                  return $data; // return is required
              }
          

          3) 在您的视野中

           {{ $var_messages }}
          

          【讨论】:

            【解决方案12】:

            Laravel 5.6 方法:https://laravel.com/docs/5.6/views#passing-data-to-views

            示例,将模型集合共享给所有视图 (AppServiceProvider.php):

            use Illuminate\Support\Facades\View;
            use App\Product;
            
            public function boot()
            {
                $products = Product::all();
                View::share('products', $products);
            
            }
            

            【讨论】:

            • 如果您尝试使用空数据库创建新应用程序,这将导致问题。
            【解决方案13】:

            例如,您可以将数据库中所有表的列表返回给 Controller 的所有视图 像这样:

            public function __construct()
            {
                $tables = DB::select('SHOW TABLES'); // returns an array of stdObjects
                view()->share('tables', $tables);
            }
            

            【讨论】:

              【解决方案14】:

              在 Laravel 5 及以上版本中,您可以在 AppServiceProvider.php 访问所有视图中的变量

              public function boot()
              {
                  \View::composer('*', function($view){
                      $view->with('key', 'value');
                  });
              }
              

              "Key" 代表你要设置的变量的名字,这样你以后可以在任何.blade.php 文件中使用它,"value" 代表变量所代表的值... 例如:

              //设置所有blade.php文件访问的用户角色

              public function boot(){
              //
              View::composer('*', function($view){
              view->with('role', Auth::user()->infouser->role);
               });
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-06-18
                • 1970-01-01
                • 2016-04-14
                • 1970-01-01
                • 2015-06-24
                • 2018-04-09
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多