Кэширование вывода вида в 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);


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



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

739   2  

2 ответов:

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

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

Более ремонтопригодный(?) метод

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

Шаги, которые я бы предпринял:

  1. создайте библиотеку / пакет. Цель состоит в том, чтобы создать класс, который расширяет логику представления Laravel. После того, как вы посмотрите, вы можете расширить этот - это View фасад
  2. Если вы расширили фасад вида своим собственным (иначе говоря, если мое предположение о файле в шаге 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 в коде.
<?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 будет вызван. Обратите внимание, что это должно имитировать функциональность Illuminate\View\ViewServiceProvider для создания расширенного класса Environment.
<?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, чтобы загрузить нашего поставщика услуг и заменить фасад иллюмината на наш собственный. Edit 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

    Ничего не найдено.