В документации сказано, что в OctoberCMS доступно кеширование запросов к базе данных: https://octobercms.com/docs/database/query#caching-queries

У меня есть такой код в файле routes.php, генерирующий карту сайта:

use Octoclub\Tutorial\Models\Item;
use Octoclub\Tutorial\Models\Category;

Route::get('sitemap.xml', function () {
    $categories = Category::all();
    $items = Item::all();

    return Response::view('octoclub.tutorial::sitemap', ['items' => $items, 'categories' => $categories])->header('Content-Type', 'text/xml');
});

Так как это карта сайта, то логично её кешировать хотя бы на сутки (1440 минут).
Как я понял, для кеширования мне нужно изменить так:

$categories = Category::remember(1440)->all();
$items = Item::remember(1440)->all();

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

Возможно для кеширования нужно знать настройки из \config\cache.php, у меня они такие:

'default' => 'file',

'stores' => [
        'database' => [
            'driver' => 'database',
            'table'  => 'cache',
            'connection' => null,
        ],

        'file' => [
            'driver' => 'file',
            'path'   => storage_path('framework/cache'),
        ],
    ],

    Koresh В доках вроде есть про кеш

    Пробуй:

    $value = Cache::get('key');

    Это что бы получить кеш, если пусто вернет null

    Cache::has('key');

    Это что бы проверить существует ли в кеше такой ключ

    Доки тут https://octobercms.info/docs/services-cache#cache-usage

    Спасибо, попробую разобраться (раньше с этим никогда не сталкивался).

    • Изменено

    Вот так правильно будет если заменю

    $categories = Category::all();
    $items = Item::all();

    на

    if (Cache::has('categories_sitemap')) {
        $categories = Cache::get('categories_sitemap');
    }
    else {
        $categories = Category::all();
        Cache::put('categories_sitemap', $categories, 14400);
    }
    
    if (Cache::has('items_sitemap')) {
        $items = Cache::get('items_sitemap');
    }
    else {
        $items = Item::all();
        Cache::put('items_sitemap', $items, 1440);
    }

    ?

    Koresh $categories = Category::remember(1440)->all();
    $items = Item::remember(1440)->all()
    Этого достаточно или теперь нужно находить запрос в кеше и изменить код чтобы выводилось из кеша?

    Этого достаточно! Последующие запросы, которые будут исполнять этот код будут пользоваться кешем.

    • Koresh ответили на это сообщение.

      reazzon Этого достаточно! Последующие запросы, которые будут исполнять этот код будут пользоваться кешем.

      Сделал так - страница ломается в ошибку.
      Может нужно что то в use подключать чтобы кеширование заработало?

      • reazzon ответили на это сообщение.

        Koresh В какую ошибку?

        Вот скрин ошибки:

        Текст:

        We're sorry, but an unhandled error occurred. Please see the details below.
        Call to undefined method October\Rain\Database\QueryBuilder::all()
        /www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php line 2483

        Если ставлю просто:

        $categories = Category::all();
        $items = Item::all();

        то работает, но это без кеширования.

        • reazzon ответили на это сообщение.

          Koresh поставь не all(); а get(); одна и таже фигня.

          • Изменено

          Поставил get(); - ошибка исчезла, генерируется правильно.
          А вот как проверить работает кеширование или нет?

          Решил пересохранить item, чтобы обновилась дата обновления и посмотреть в карте сайта изменяется ли значение, но тут проблема - при сохранении item'а у меня перестала обновляться дата.
          Вот этот код не выключил ли даты?

          $item->timestamps = false; // Выключаем на следующие изменения таймстампы
          $item->hits = $item->hits + 1; // Добавляем один просмотр
          $item->save(); // Сохраняем модель

          Неужто после сейва нужно $item->timestamps = true; дописать?

            • Изменено

            Koresh А вот как проверить работает кеширование или нет?

            Можешь поставить Debugbar плагин и посмотреть скорость выполнения запросов в SQL вкладке.

            Когда кеша нет (то-есть ты его очистил или его время истекло) запрос будет выполнятся как обычно, но когда зайдешь еще раз уже на кешированный запрос, увидишь что произойдет)

            Koresh Неужто после сейва нужно $item->timestamps = true; дописать?

            Честно не знаю, поэкспериментируй.

            • Изменено

            Могу посоветовать использовать Cache::remember, в доках подробнее есть. Суть в том, что этот метод сам делает проверку, на то, есть ли в кэше нужный запрос или нет, если нет - создает.

            • reazzon ответили на это сообщение.

              Koresh Проверить просто. Например ты закешировал вывод на какое-то время, лучше на очень малое время что бы проверить. Посмотрел в вывод там, например 5 записей. В бд создай еще одну запись, посмотри вывод еще раз будет все равно 5 записей, потому что кеш не обновился.

              Это может не работать с созданием записи через админку, потому что есть вероятность, что при сохранении кеш очищается. Но я точно не уверен.

              sko6 Точно так-же делает и remember().

              • sko6 ответили на это сообщение.

                reazzon
                Блин, я не увидел прост в самом начале(

                Понаблюдал за поведением создавая новые записи, вот так кеширование запросов отрабатывает правильно:

                $categories = Category::remember(1440)->get();
                $items = Item::remember(1440)->get();

                При чистке кеша запрос обновляется.

                19 дней спустя

                Интересно, есть ли разница от того где в цепочке будет стоять remember?
                Я думаю вот так по логике правильно:

                $items = Item::where('published', '1')->remember(1440)->get();

                или поставить цепочку так:

                $items = Item::remember(1440)->where('published', '1')->get();

                Или может оба варианта неправильны и remember нельзя ставить в одной цепочке вместе с where?

                • reazzon ответили на это сообщение.