Кэширование вывода вида в Laravel 4
Я знаю, что Blade уже кэширует скомпилированный PHP для всех представлений blade, но я хотел бы сделать этот шаг дальше. Веб-сайт, над которым я работаю, модулируется в компонентные представления, а затем объединяется в контроллере по умолчанию. Каждый из" виджетов " имеет свой собственный вид, который редко изменяет содержимое (за исключением нескольких часто обновляющихся). Поэтому я хотел бы кэшировать HTML-вывод этих редко меняющихся представлений, чтобы предотвратить их оценку на каждой странице загружать.
В Laravel 3 мы могли бы сделать что-то вроде этого (кредитные форумы Laravel):
Event::listen(View::loader, function($bundle, $view)
{
return Cache::get($bundle.'::'.$view, View::file($bundle, $view,
Bundle::path($bundle).'view'));
});
К сожалению, View::loader полностью исчез в Laravel 4. Копаясь в IlluminateViewView и IlluminateViewEnvironment, я обнаружил, что каждое представление отправляет событие с именем "composing: {view_name}". Прослушивание этого события предоставляет имя представления и данные, передаваемые ему при каждом отображении представления, однако возврат из обратного вызова не имеет такого же эффекта, как в Laravel 3:
Event::listen('composing: *', function($view) {
if(!in_array($view->getName(), Config::get('view.alwaysFresh'))) {
// Hacky way of removing data that we didn't pass in
// that have nasty cyclic references (like __env, app, and errors)
$passedData = array_diff_key($view->getData(), $view->getEnvironment()
->getShared());
return Cache::forever($view->getName() . json_encode($passedData), function() {
return 'test view data -- this should appear in the browser';
});
}, 99);
Вышесказанное не имеет значения. обходите обычный вид, включая и процесс рендеринга.
Итак, как можно обойти нормальную визуализацию представления и вернуть кэшированное содержимое из этого события составления? Возможно ли в настоящее время в Ларавеле без какой-то уродливой халтуры?
2 ответов:
Быстрый и грязный
Ну, один из вариантов, как я уверен, вы знаете, заключается в том, чтобы кэшировать элементы внутри контроллеров по мере отображения представления. Я подозреваю, что вы не хотите этого делать, так как в долгосрочной перспективе это менее ремонтопригодно.
Более ремонтопригодный(?) метод
Однако, если загрузчик/визуализатор вида не запускает событие там, где вы хотите, вы можете создать его. Поскольку каждый пакет / библиотека в Laravel 4 устанавливается в контейнере приложения, вы можете на самом деле замените библиотеку представлений своей собственной.
Шаги, которые я бы предпринял:
- создайте библиотеку / пакет. Цель состоит в том, чтобы создать класс, который расширяет логику представления Laravel. После того, как вы посмотрите, вы можете расширить этот - это
Viewфасад- Если вы расширили фасад вида своим собственным (иначе говоря, если мое предположение о файле в шаге 1 верно), вам просто нужно будет заменить псевдоним вида в
app/config/app.phpвашим собственный.Edit-я немного поиграл с этим. Хотя я не обязательно согласен с кэшированием результата просмотра, против кэширования sql-запросов или "более тяжелых лифтов", вот как я буду делать это в Laravel 4:
Рендеринг вида в Laravel 4 не запускает событие, которое позволяет нам кэшировать результат просмотра. Вот как я добавил в эту функциональность кэшировать результат представления.
Возможно, вы захотите рассмотреть последствия кэширования представлений. результат. Например, это не обходится без тяжелой работы по общению с базой данных, чтобы получить данные, необходимые для представления. В любом случае, это дает хороший обзор по расширению или замене основных элементов.
Сначала создайте пакет и настройте его автоматическую загрузку. Я буду использовать пространство имен
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. В нашем случае это означает, что мы будем расширять Осветить\Посмотреть\Окружение .В этом классе мы возьмем результат визуализации представления и добавим некоторую логику в кэш (или не кэш) его. Вот
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, чтобы он работал как фасад. У меня есть запись в блоге о создании фасадов Laravel. Вот как это сделать в этом случае дело: Создайте фасад для нашей новой среды. Мы назовем егоfideloper.viewв коде.Затем создайте поставщика услуг, который скажет Laravel, что создавать, когда<?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'; } }fideloper.viewбудет вызван. Обратите внимание, что это должно имитировать функциональностьIlluminate\View\ViewServiceProviderдля создания расширенного классаEnvironment.Наконец, мы должны соединить все это вместе и сказать Laravel, чтобы загрузить нашего поставщика услуг и заменить фасад иллюмината на наш собственный. Edit<?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; }); } }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()!Наконец
Стоит отметить, что есть некоторые шаблоны для загрузки в несколько "запросов" на веб-запрос. Symfony, например, давайте вы определяете контроллеры как серверы . Зенд имеет (имел?) концепция стеков действий, которая позволяет вам
... эффективно помочь вам создать очередь действий [контроллера] для выполнения во время запроса.
Возможно, вы хотели бы изучить эту возможность в Laravel и кэшировать результаты этих "действий" (против кэширования представления напрямую).
Просто мысль, а не рекомендация.
В Laravel(и не только) есть библиотека для кэширования видов/деталей-Flatten.
Это мощная система кэширования для кэширования страниц во время выполнения. То, что он делает, довольно просто : вы говорите ему, какая страница должна быть кэширована, когда кэш должен быть сброшен, и оттуда сглаживает все это. Он спокойно сгладит ваши страницы до простого HTML и сохранит их. Вот почему, если пользователь посещает страницу, которая уже была расплющена, весь PHP highjacked вместо отображения простой HTML-страницы. Это существенно повысит скорость работы приложения, так как кэш страницы обновляется только после внесения изменений в отображаемые данные.
Кэшировать все авторизованные страницы в приложении с помощью команды
artisan flatten:build. Он будет сканировать ваше приложение и переходить со страницы на страницу, кэшируя все страницы, которые вы ему разрешили.Промывка
Иногда может потребоваться смыть определенную страницу или шаблон. Если, например, вы кэшируете профили пользователей, вы можете захотеть смыть их те, когда пользователь редактирует свою информацию. Это можно сделать следующими способами:
// Manual flushing Flatten::flushAll(); Flatten::flushPattern('users/.+'); Flatten::flushUrl('http://localhost/users/taylorotwell'); // Flushing via an UrlGenerator Flatten::flushRoute('user', 'taylorotwell'); Flatten::flushAction('UsersController@user', 'taylorotwell'); // Flushing template sections (see below) Flatten::flushSection('articles');Ссылка на - https://github.com/Anahkiasen/flatten
Comments