Laravel 5.2视图编辑器被多次执行

Dev*_*evK 9 php laravel laravel-5

我正在处理的项目中存在一些(主要)性能问题,并且在记录了所有执行的查询后,我意识到其中许多执行多次,我无法找到问题的根源.

多次执行的所有查询都在我的视图编写器提供程序中.

这就是我的视图作曲家的样子:

public function boot()
    {
        view()->composer('partials.sidebar', function ($view) {
            $currentCategory = $this->getCurrentCategory();
            $sidebarCategories = SidebarCategory::category($currentCategory)
                ->order()
                ->get();
            $view
                ->with('sidebarCategories', $sidebarCategories);
        });

        view()->composer('partials.footer', function ($view) {
            $footerLinks = FooterCategory::with('links.translations')->order()->get();
            $footerColumn1 = $footerLinks->filter(function ($value, $key) {
                return $value->column == 1;
            });
            $footerColumn2 = $footerLinks->filter(function ($value, $key) {
                return $value->column == 2;
            });
            $footerColumn3 = $footerLinks->filter(function ($value, $key) {
                return $value->column == 3;
            });
            $footerColumn4 = $footerLinks->filter(function ($value, $key) {
                return $value->column == 4;
            });

            $view
                ->with(compact('footerColumn1', 'footerColumn2', 'footerColumn3', 'footerColumn4'));
        });
}
Run Code Online (Sandbox Code Playgroud)

这两个查询(Sidbar和Footer类别)都会被执行大约6次,即使每个部分只被调用一次.它们都在主视图中使用@include('partialname')调用.

我试过这个:

if($view->offsetExists('sidebarCategory'))
    return;
Run Code Online (Sandbox Code Playgroud)

但是offsetExists总是返回false(即使在它调用了5.时间之后).

知道为什么会这样,我做错了什么?

编辑:

我已经意识到问题所在.在我正在访问的页面上(执行多个查询的位置),有一些404元素(主要是图像).每次找不到文件时,都会抛出新的404异常.每次抛出404异常时,404视图都会被执行=>意味着页脚/侧边栏查询也会被执行(因为它们是404视图的一部分).示例:http://imgur.com/a/RrmOD

因此,后续问题是如何在不需要时防止视图被渲染(例如,404是未找到的图像).

这是我的路线中的一段代码,我假设这是发生这种情况的原因:

Route::get('{slug}', ['as' => 'findBySlug', 'uses' => function($slug) {
    if(\App\DynamicCategory::findBySlug($slug)->count() > 0)
        return App::make('App\Http\Controllers\GeneralController')->getDynamicCategoryIndex($slug);
    else if(\App\DynamicPage::noCategory()->findBySlug($slug)->count() > 0)
        return App::make('App\Http\Controllers\GeneralController')->getDynamicPage($slug);
    else
        abort(404);
}]);
Run Code Online (Sandbox Code Playgroud)

PS:我知道这段代码是非常不优化的(因为它基本上执行相同的查询两次,一次查看项目是否存在,另一次实际在控制器中).这是正在进行的工作,它在todo列表中.

编辑2:

我已经提出了下一个解决方案,我愿意接受改进,因为这是一种有点黑客的方式(如果我添加更多文件夹,我将需要记住更新它).我在公共文件夹中只有3个直接子文件夹:东西,文件和资源.

解决方案是在呈现异常时(在文件app/Exceptions/Handler.php中)检查url的第一个段,如果它与3个文件夹中的一个匹配,则返回404响应而不显示视图:

public function render($request, Exception $e)
{
    $firstSegment = $request->segment(1);
    if(starts_with($firstSegment, 'files') || starts_with($firstSegment, 'something') || starts_with($firstSegment, 'resources')) {
        return response('Stran ne obstaja', 404);
    }

    return parent::render($request, $e);
}
Run Code Online (Sandbox Code Playgroud)

提前致谢

Tsc*_*cka 5

不要通过laravel路由文件请求并在404上提供空白图像

.htaccess样本:

RewriteEngine On
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .*$ /no_picture.png [L]
Run Code Online (Sandbox Code Playgroud)

您可以将此发布在重定向到index.php的规则之上

这假设图片是从网站提供的,而不是通过流式数据库内容提供的.

基本上会发生这样的事情:

  • 后端用户上传图片:
  • laravel将图像存储在/some/path/to/store/data/public/12a/4d8/458/12a4d8458.gif中
  • laravel将图像存储为数据库中的12a4d8458.gif
  • - - - - - - - - - - 时间流逝 - - - - - - - - - - - -
  • 访客请求页面.
  • 请求与文件不匹配.重定向到index.php(根据.htaccess)
  • 请求被发送到index.php
  • laravel建立页面.找到图像
  • laravel组成完整的公共URL路径
  • www.awesome.com/data/public/12a/4d8/458/12a4d8458.gif
  • 组合的html内容被推送给访问者
  • ----------------毫秒传递------------------------
  • 访客请求图片/data/public/12a/4d8/458/12a4d8458.gif
  • 请求匹配文件文件由apache提供
  • laravel仍然幸福地没有意识到请求
  • -----------------没有超过毫秒-------------
  • 访客请求图片/data/public/4e8/d44/98f/4e8d4498f.gif
  • 请求与文件不匹配.重定向到index.php(根据.htaccess)
  • laravel建立页面.找不到路线.
  • laravel调用404例程
  • laravel构建404页面,其中包含所有触发器
  • laravel为用户提供404服务

因此,您希望在最后一步中执行的操作是通过按照.htaccess规则定义提供您自己的图像来防止图像请求达到laravel.这样,您的网络服务器可以更快地对丢失的图像做出响应.