如何将数据传递给 Laravel 5 中的所有视图?

How to pass data to all views in Laravel 5?

我想在我的 Laravel 5 应用程序的所有视图中访问一些默认数据。

我试图搜索它,但只找到 Laravel 4 的结果。我已阅读文档 'Sharing Data With All Views' here 但我不明白该怎么做。下面的代码应该放在哪里?

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

感谢您的帮助。

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

1。使用 BaseController

我喜欢设置东西的方式,我做了一个 BaseController class 扩展 Laravel 自己的 Controller,并在那里设置各种全局东西.然后所有其他控制器都从 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.

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 还有助于将特定数据绑定到以不同方式查看。您可以直接将变量绑定到特定视图或所有视图。例如,您可以根据需要创建自己的目录来存储您的视图编辑器文件。这些视图编辑器文件通过服务提供与视图的交互。

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 下的 "providers" 部分。

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

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

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

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

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

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

如果你更愿意使用 facade 而不是 helper,请将 view()-> 更改为 View:: 但不要忘记在顶部添加 use View;你的文件。

在文档中:

Typically, you would place calls to the share method within a service provider's boot method. You are free to add them to the AppServiceProvider or generate a separate service provider to house them.

我同意 Marwelln 的观点,只需将它放在 AppServiceProvider 的启动函数中即可:

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

我建议为变量使用一个特定的名称,以避免与其他 'global' 变量混淆或错误。

我认为最好的方法是 View Composers。如果有人来到这里并想了解如何使用 View Composers 的方式做到这一点,请阅读我的回答 =>

我发现这是最简单的一个。创建一个新的提供者并使用 '*' 通配符将其附加到所有视图。也适用于 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()
    {
        //
    }
}

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

共享变量

使用"*"作曲时遇到的问题:

考虑以下方法:

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

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

从示例blade来看:

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

会发生什么?

  • GlobalComposer class 实例化 1000 次使用 App::make
  • 事件composing:some_partial_view_to_display_i已处理 1000 次。
  • GlobalComposer class 中的 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());
  }
}

更新

如果您使用的是通过中间件管道计算的东西,您可以简单地监听到适当的事件或将视图共享管道最后底部的中间件。

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

文档是听到的 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 Service Provider。当您 运行 您的应用程序具有像 http://yourdomain/something/profile 这样的视图配置文件时,服务提供商 ComposerServiceProvider 被调用并且 class App\Http\ViewComposers\ProfileComposer 由于启动方法或函数中的以下代码,调用方法 Composer 被实例化。

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. 如果您刷新应用程序,您将收到错误消息,因为 class 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'
);

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

<?php

  return [
    'versionNumber' => '122231',
  ];

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

config('variable.versionNumber')

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

}

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

您有两个选择:

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

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

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

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

2。使用助手 class:

在您的应用程序的任何位置创建一个助手 class 并将其注册到 config 文件夹中 app.php 文件的 Alias 数组中。

 '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 或任何其他 classes。

例如你可以return数据库中所有表的列表到控制器的所有视图 像这样:

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

In Laravel 5 and above versions , you can edit boot function in AppServiceProvider.php to access variable in all views

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

如果你正在使用 Laravel 8 你可以这样做,

class Controller extends BaseController{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

public function __construct(){
    $categories = Category::where('show_menu', '=', 1)->where('status', '=', 'approved')->get();
    view()->share('categories', $categories);
}}