Laravel View Composer 为每个视图复制 SQL 查询
Laravel View Composer duplicating SQL queries for every view
我需要在大多数视图中访问一些数据(用户详细信息)。我做了什么:
我创建了 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 class
<?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'] 相同的 SQL 将是如果 ['includes.header','profile','something_else'] 执行了两次,依此类推...
在这种情况下查询是
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 个查询!我在这里错过了什么?
根据 https://laravel.com/docs/5.5/views#view-composers 处的手册:
"View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location."
(强调我的)
在这种情况下:
view()->composer(
['includes.header','profile'],
'App\Http\ViewComposers\CustomerComposer'
);
您正在附加 includes.header
视图和 profile
视图,我猜其中包括 includes.header
视图。因此,由于 composer 在渲染视图时执行,因此它将执行两次,一次在渲染 profile
视图时执行,另一次在渲染 includes.header
视图时执行。
好的,我想我找到了解决方案。在 ComposerServiceProvider class:
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(\App\Http\ViewComposers\CustomerComposer::class);
}
那个吧。
在 Laravel 文档中
Registering A Singleton
Sometimes, you may wish to bind something into the container that
should only be resolved once, and the same instance should be returned
on subsequent calls into the container:
您可以在此处使用配置来解决视图撰写的多次查询运行问题。例如显示下面的代码。
public 函数撰写(查看 $view)
{
if(!Config::has('composeVars'))
{
Config::set('composeVars') = [
'users' => User::all();
];
}
$view->with('*', Config::get('composeVars'));
}
我需要在大多数视图中访问一些数据(用户详细信息)。我做了什么:
我创建了 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 class
<?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'] 相同的 SQL 将是如果 ['includes.header','profile','something_else'] 执行了两次,依此类推...
在这种情况下查询是
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 个查询!我在这里错过了什么?
根据 https://laravel.com/docs/5.5/views#view-composers 处的手册:
"View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location."
(强调我的)
在这种情况下:
view()->composer(
['includes.header','profile'],
'App\Http\ViewComposers\CustomerComposer'
);
您正在附加 includes.header
视图和 profile
视图,我猜其中包括 includes.header
视图。因此,由于 composer 在渲染视图时执行,因此它将执行两次,一次在渲染 profile
视图时执行,另一次在渲染 includes.header
视图时执行。
好的,我想我找到了解决方案。在 ComposerServiceProvider class:
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(\App\Http\ViewComposers\CustomerComposer::class);
}
那个吧。
在 Laravel 文档中
Registering A Singleton
Sometimes, you may wish to bind something into the container that should only be resolved once, and the same instance should be returned on subsequent calls into the container:
您可以在此处使用配置来解决视图撰写的多次查询运行问题。例如显示下面的代码。
public 函数撰写(查看 $view) {
if(!Config::has('composeVars'))
{
Config::set('composeVars') = [
'users' => User::all();
];
}
$view->with('*', Config::get('composeVars'));
}