【问题标题】:Laravel View Composer duplicating SQL queries for every viewLaravel View Composer 为每个视图复制 SQL 查询
【发布时间】:2018-03-11 17:13:03
【问题描述】:

我需要在大多数视图中访问一些数据(用户详细信息)。我做了什么:

我创建了 ComposerServiceProvider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer(
            ['includes.header','profile'],
            'App\Http\ViewComposers\CustomerComposer'
        );

    }

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

创建 CustomerComposer 类

<?php

namespace App\Http\ViewComposers;

use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Modules\Customers\Entities\CustomerDetail;

class CustomerComposer
{
    public $customer = [];

    /**
     * Bind data to the view.
     *
     * @param  View  $view
     * @return void
     */
    public function compose(View $view)
    {
        $user = Auth::guard('customer');

        $this->customer = CustomerDetail::where('user_id',$user->id())->first();

        $view->with( 'customer', $this->customer );
    }
}

一切正常,但是当我查看调试栏时,它会显示每个视图执行的相同查询,例如,如果我定义 ['includes.header','profile'] 如果 ['includes.header ','profile','something_else'] 3 次等等...

在这种情况下,查询是

select * from `customer_details` where `user_id` = '1' limit 1
select * from `customer_details` where `user_id` = '1' limit 1

如果我提供通配符

view()->composer(
            ['*'],
            'App\Http\ViewComposers\CustomerComposer'
        );

它将生成 23 个查询!我错过了什么?

【问题讨论】:

    标签: php mysql laravel laravel-5 blade


    【解决方案1】:

    好的,我想我找到了解决方案。在 ComposerServiceProvider 类中:

    /**
    * Register the application services.
    *
    * @return void
    */
    public function register()
    {
        $this->app->singleton(\App\Http\ViewComposers\CustomerComposer::class);
    }
    

    那个。

    在 Laravel 文档中

    注册一个单例

    有时,您可能希望将某些内容绑定到容器中 应该只解析一次,并且应该返回相同的实例 在随后调用容器时:

    【讨论】:

      【解决方案2】:

      根据https://laravel.com/docs/5.5/views#view-composers 的手册:

      “视图合成器是在渲染视图时调用的回调或类方法。如果您有想要绑定到视图的数据每次渲染视图时,视图合成器可以帮助您将该逻辑组织到一个位置。”

      (强调我的)

      在这种情况下:

          view()->composer(
              ['includes.header','profile'],
              'App\Http\ViewComposers\CustomerComposer'
          );
      

      您正在附加includes.header 视图和profile 视图,我猜其中包括includes.header 视图。因此,由于 composer 在视图渲染时执行,它会执行两次,一次是在渲染 profile 视图时,另一次是在渲染 includes.header 视图时。

      【讨论】:

      • 我明白这一点,但是将数据从模型传递到所有视图的最有效方法是什么?我虽然这个实现是为此而做的,但我必须在这里遗漏一些明显的东西。
      【解决方案3】:

      您可以在此处使用配置来解决视图组合的多次查询运行问题。比如下面的代码。

      公共函数撰写(查看$view) {

      if(!Config::has('composeVars')) 
      {
          Config::set('composeVars') = [
            'users' => User::all();  
          ];
      }
      
      $view->with('*', Config::get('composeVars'));
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 2018-09-19
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 2014-07-29
        相关资源
        最近更新 更多