快速和肮脏的
好了,一个选择,因为我敢肯定你知道,就是缓存控制器内的项目,如查看正在呈现。我怀疑你不想这样做,因为从长远来看它不太可维护。
更好的可维护性(?)方法
但是,如果查看加载/渲染器不火,你想一个事件,你可以创建一个。因为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