Просмотр кэширования в Laravel 4

Я знаю, что Blade уже кэширует скомпилированный PHP для всех видов блейдов, но я хотел бы сделать это еще дальше. Веб-сайт, над которым я работаю, является модульным в виде компонентов, а затем скомпонован в контроллере по умолчанию. Каждый из «виджетов» имеет свой собственный вид, который редко меняет контент (за исключением нескольких часто обновляемых). Итак, я хотел бы кэшировать вывод 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. При переходе через \Illuminate\View\View и \Illuminate\View\Environment я обнаружил, что каждый просмотр отправляет событие с именем "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); 

Вышеизложенное не обходит нормальный просмотр, включая и визуализацию.

Итак, как вы можете обходить нормальный просмотр изображений и возвращать кешированный контент из этого составного события? Возможно ли это в настоящее время в Ларавеле без какого-то уродливого хакера?

Быстро и грязно

Ну, один из вариантов, как я уверен, вы знаете, состоит в том, чтобы кэшировать элементы внутри контроллеров по мере рендеринга представления. Я подозреваю, что вы не хотите этого делать, поскольку в долгосрочной перспективе он менее ремонтируется.

Более поддерживаемый (?) Метод

Однако, если средство просмотра / рендеринга View не запускает событие, в котором вы хотите, вы можете его создать. Поскольку каждый пакет / библиотека в Laravel 4 установлен в контейнере App, вы можете фактически заменить библиотеку View своей собственной.

Я бы сделал следующие шаги:

  1. Создайте библиотеку / пакет. Цель состоит в том, чтобы создать класс, который расширяет логику представления Laravel. После того, как вы посмотрите, вы можете расширить этот вариант – это View фасада
  2. Если вы расширили внешний вид View своим собственным (иначе, если мое предположение в файле на шаге 1 верное), вам просто нужно будет заменить псевдоним для View в app/config/app.php своим.

Редактировать. Я немного поиграл с этим. Хотя я не всегда согласен с кэшированием результата View, vs caching sql query или «более тяжелых лифтов», вот как я собирался сделать это в Laravel 4 :

Просмотр рендеринга в Laravel 4 не запускает событие, которое позволяет нам кэшировать результат представления. Вот как я добавил в эту функцию кеширование результата представления.

Вы можете рассмотреть последствия кэширования результата представления. Например, это не обойти сложную работу по разговору с datbase, чтобы получить данные, необходимые для представления. В любом случае, это дает хороший обзор по расширению или замене основных элементов.

Сначала создайте пакет и настройте его автозагрузку. Я буду использовать пространство имен 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 .

В этом классе мы возьмем результат визуализации 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 его 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 о загрузке нашего Сервисного провайдера и заменить фасад View Illuminate на наш собственный. Изменить app/config/app.php :

Добавьте поставщика услуг:

 'providers' => array( // Other providers 'Fideloper\View\ViewServiceProvider', ), 

Замените внешний вид View на свой собственный:

 'aliases' => array( // Other Aliases //'View' => 'Illuminate\Support\Facades\View', 'View' => 'Fideloper\View\ViewFacade', ), 

Затем вы сможете использовать любую логику в методе View::make() !

в заключение

Стоит отметить, что есть несколько шаблонов для загрузки в нескольких «запросах» для каждого веб-запроса. Symfony, например, давайте определим контроллеры как серверы . У Zend есть (есть?) Концепция Action Stacks, которая позволяет вам

… эффективно помочь вам создать очередь действий [контроллера] для выполнения во время запроса.

Возможно, вы хотели бы изучить эту возможность в Laravel и кэшировать результаты этих «действий» (прямое кэширование представления).

Просто мысль, а не рекомендация.

Существует библиотека для кэширования просмотров / частей в Laravel (и не только) – Flatten.

Это мощная система кэширования для кэширования страниц во время выполнения. То, что он делает, довольно просто: вы говорите ему, какая страница должна быть кэширована, когда кеш должен быть сброшен, а оттуда Flatten обрабатывает все это. Он будет спокойно сглаживать ваши страницы до простого HTML и хранить их. Если кто-то посетит страницу, которая уже была сглажена, все PHP будет перевыполнен, чтобы вместо этого отобразить простую 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