快速和骯髒的
好了,一個選擇,因爲我敢肯定你知道,就是緩存控制器內的項目,如查看正在呈現。我懷疑你不想這樣做,因爲從長遠來看它不太可維護。
更好的可維護性(?)方法
但是,如果查看加載/渲染器不火,你想一個事件,你可以創建一個。因爲Laravel 4中的每個包/庫都在App容器中設置,所以實際上可以用您自己的替換View庫。
我會採取的步驟是:
- 創建庫/包。目標是創建一個擴展Laravel的視圖邏輯的類。看完後,你可能需要擴展this one - 這是
View
外觀
- 如果你用自己的擴展視圖外觀(也就是說,如果我在步驟1中對文件的假設是正確的),那麼你只需要用您自己的
app/config/app.php
替換alias for View。
編輯 - 我玩了這一點。雖然我不一定同意緩存視圖結果,緩存sql查詢或「較重的升降機」,但這裏是我如何去做這件事Laravel 4:
Laravel 4中的視圖渲染doesn不會發佈讓我們緩存視圖結果的事件。以下是我在該功能中添加的緩存視圖結果的方式。
您可能想考慮高速緩存視圖結果的後果。例如,這並沒有解決與數據庫交談以獲取視圖所需數據的艱苦工作。無論如何,這對擴大或替代核心項目提供了一個很好的概述。
首先,創建一個包並設置其自動加載。我將使用命名空間Fideloper\View
。它自動加載在composer.json
會是這樣的:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-0": {
"Fideloper": "app/"
}
},
接下來,創建一個類來代替View
門面。在我們的情況下,這意味着我們將延長Illuminate\View\Environment。
在這個類中,我們將看到渲染的結果並添加一些邏輯來緩存(或不緩存)它。這裏是Fideloper/View/Environment.php
:
<?php namespace Fideloper\View;
use Illuminate\View\Environment as BaseEnvironment;
use Illuminate\View\View;
class Environment extends BaseEnvironment {
/**
* Get a evaluated view contents for the given view.
*
* @param string $view
* @param array $data
* @param array $mergeData
* @return \Illuminate\View\View
*/
public function make($view, $data = array(), $mergeData = array())
{
$path = $this->finder->find($view);
$data = array_merge($mergeData, $this->parseData($data));
$newView = new View($this, $this->getEngineFromPath($path), $view, $path, $data);
// Cache Logic Here
return $newView;
}
}
所以,這就是你的工作的大部分將是 - 填寫該// Cache Logic Here
。但是,我們還有一些工作要做。
接下來,我們需要設置新的Environment
類作爲Facade。我有一篇關於creating Laravel facades的博客文章。以下是在這種情況下如何完成此項任務:
爲我們的新環境創建外觀。我們將用代碼將其命名爲fideloper.view
。
<?php namespace Fideloper\View;
use Illuminate\Support\Facades\Facade;
class ViewFacade extends Facade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'fideloper.view'; }
}
然後,創建服務提供商,這將告訴Laravel創造什麼時候fideloper.view
被調用。請注意,這需要模擬用於創建擴展Environment
類的Illuminate\View\ViewServiceProvider
的功能。
<?php namespace Fideloper\View;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider {
public function register()
{
$this->app['fideloper.view'] = $this->app->share(function($app)
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
$env = new Environment($resolver, $finder, $app['events']);
// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env->setContainer($app);
$env->share('app', $app);
return $env;
});
}
}
最後,我們需要一起掛鉤這一點,並告訴Laravel載入我們的服務供應商和我們自己的替代照亮的觀點門面。編輯app/config/app.php
:
添加服務提供商:
'providers' => array(
// Other providers
'Fideloper\View\ViewServiceProvider',
),
與我們自己替換的視圖門面:
'aliases' => array(
// Other Aliases
//'View' => 'Illuminate\Support\Facades\View',
'View' => 'Fideloper\View\ViewFacade',
),
然後您就可以使用您所希望的任何邏輯在View::make()
方法!
最後
,有一些模式在每個Web請求多次「請求」加載值得注意。舉例來說,Symfony就是讓你define controllers as servers。 Zend擁有(已有?)動作堆棧的概念,它允許您在請求期間創建[控制器]動作的隊列,以便在執行時有效地執行隊列。也許你想在Laravel中探索這種可能性,並緩存這些「動作」(vs直接緩存視圖)的結果。
只是一個想法,而不是一個建議。
也許我問如果你是在一種方式,以避免重新創建的視圖數據這樣做呢?你是否還需要點擊數據庫來創建視圖,即使視圖結果本身保存在緩存中?你可能有更好的運氣來緩存數據庫命中的結果等。 – fideloper