php - tutorial - laravel教學




Laravel 5.2視圖作曲家被執行了多次 (2)

檢查文件擴展名

而不是檢查特定路徑的網址,如果你說它只會是圖像。 所以如果只是需要特定擴展名的東西,你可以檢查一下,並返回一個更簡單的404響應:)

/* \app\Exceptions\Handler.php */

public function render($request, Exception $exception)
{
    if ($exception instanceof NotFoundHttpException) {
        $ext = pathinfo($request->url(), PATHINFO_EXTENSION);
        if (in_array($ext, ['jpg', 'png'])) {
            return response('Nope');
        }
    }

    return parent::render($request, $exception);
}

高速緩存

剛剛意識到它提出了很多要求。 也許這樣的事情,緩存1分鐘的結果,應該足夠長的時間,以便頁面上的下一個404請求,拿起緩存,而不是運行查詢:)

public function boot()
{
    // Sidebar
    $sidebarCategories = Cache::store('file')->remember('sidebarCategories', 1, function () {
        $currentCategory = $this->getCurrentCategory();
        return SidebarCategory::category($currentCategory)->order()->get();
    });

    view()->composer('partials.sidebar', function ($view) use ($sidebarCategories) {
        $view->with('sidebarCategories', $sidebarCategories);
    });


    // Footer
    $footerColumns = Cache::store('file')->remember('footerColumns', 1, function () {
        $footerLinks = FooterCategory::with('links.translations')->order()->get();
        return [
            1 => $footerLinks->filter(function ($value, $key) { return $value->column == 1; }),
            2 => $footerLinks->filter(function ($value, $key) { return $value->column == 2; }),
            3 => $footerLinks->filter(function ($value, $key) { return $value->column == 3; }),
            4 => $footerLinks->filter(function ($value, $key) { return $value->column == 4; }),
        ];
    });

    view()->composer('partials.footer', function ($view) use ($footerColumns) {
        $view->with([
            'footerColumn1' => $footerColumns[1],
            'footerColumn2' => $footerColumns[2],
            'footerColumn3' => $footerColumns[3],
            'footerColumn4' => $footerColumns[4],
        ]);
    });
}

我正在處理的一個項目中遇到了一些(主要的)性能問題,並且在記錄了所有執行的查詢之後,我意識到其中的許多執行了多次,而且我無法找到問題的根源。

所有執行多次的查詢都在我的視圖作曲家提供者。

這是我的觀點作曲家的樣子:

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

這兩個查詢(Sidbar和Footer類別)都會執行大約6次,即使每個部分只被調用一次。 它們都是用@include('partialname')在主視圖中調用的。

我試過這個:

if($view->offsetExists('sidebarCategory'))
    return;

但是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);
}]);

PS:我知道這段代碼是非常不優化的(因為它基本上執行兩次相同的查詢,一次查看該項是否存在,而另一次實際上是在控制器中)。 這是正在進行的工作,它在待辦事項列表上。

編輯2:

我已經提出了下一個解決方案,我願意改進,因為這是一個有點黑客的方式(如果我添加更多的文件夾,我需要記住更新這個)。 我只有3個公共文件夾中的直接子文件夾:東西,文件和資源。

解決方案是在呈現異常時(在文件app / Exceptions / Handler.php中)檢查url的第一個段,並返回404響應而不是視圖,如果它匹配3個文件夾之一:

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

提前致謝


不要通過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]

你會發布這個重定向到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服務

所以你要做的最後一步是防止圖像請求甚至達到laravel,通過服務你自己的圖像按照.htaccess規則定義。 這樣,您的網絡服務器可以更快地處理丟失的圖像。







laravel-5