Кешування сторінок ================== Кешування сторінок — це кешування всього вмісту сторінки. Кешування сторінок може зустрічатися в різних місцях. Наприклад, обравши відповідний сторінці заголовок, браузер користувача може кешувати сторінку, яка переглядається, на деякий час. Веб-додаток також може сам зберігати вміст сторінки у кеші. У цьому підрозділі ми розглянемо саме другий варіант. Кешування виводу ---------------- Кешування сторінки може бути розглянуто як окремий випадок [кешування фрагмента](/doc/guide/caching.fragment). Через те, що вміст сторінки часто генерується застосуванням макета до представлення, кешування не буде працювати, якщо ми просто викличемо в макеті методи [beginCache()|CBaseController::beginCache] та [endCache()|CBaseController::endCache]. Причина цього у тому, що макет застосовується при виклику метода [CController::render()] *після* формування вмісту представлення. Для кешування всієї сторінки ми повинні пропустити етап формування вмісту сторінки. Для виконання цього завдання ми можемо використовувати клас [COutputCache] як [фільтр](/doc/guide/basics.controller#filter) дії. У коді нижче показано, як можна сконфігурувати фільтр кешу: ~~~ [php] public function filters() { return array( array( 'COutputCache', 'duration'=>100, 'varyByParam'=>array('id'), ), ); } ~~~ Вищенаведена конфігурація фільтру створює фільтр, який застосовується до всіх дій контролера. Ми можемо обмежити цю поведінку одним або кількома діями, використовуючи оператор `+`. Докладніше з роботою фільтрів можна ознайомитися в темі [фільтри](/doc/guide/basics.controller#filter). > Tip|Підказка: Ми можемо використовувати клас [COutputCache] як фільтр, оскільки він успадковує клас [CFilterWidget], тобто обидва ці класу одночасно є і віджетами, і фільтрами. Фактично, спосіб роботи віджету дуже схожий на роботу фільтра: віджет (фільтр) виконується до того, як будь-який вкладени вміст (дія) буде сформовано (виконано), а виконання віджету (фільтра) закінчується після того, як вкладений вміст (дія) буде сформовано (виконано). Кешування HTTP -------------- На додаток до кешуванню простого виводу данних дії, Yii надає [CHttpCacheFilter] (починаючи з версії 1.1.11). Цей фільтр допомагає у налаштуванні вищезазначених заголовків повідомити клієнту, що зміст сторінки не змінився з моменту останнього запиту, тому сервер не буде повторно передавати зміст. [CHttpCacheFilter] може бути встановлений ​​аналогічно до [COutputCache]: ~~~ [php] public function filters() { return array( array( 'CHttpCacheFilter + index', 'lastModified'=>Yii::app()->db->createCommand("SELECT MAX(`update_time`) FROM {{post}}")->queryScalar(), ), ); } ~~~ Вищенаведений код встановлює останню дату як значення заголовку `Last-Modified`, коли повідомлення було оновлено. Ви також можете використовувати [CHttpCacheFilter::lastModifiedExpression] для встановлення заголовку `Last-Modified`, використовуючи вираз php. > Tip|Підказка: Обидва, [CHttpCacheFilter::lastModifiedExpression] та [CHttpCacheFilter::lastModified] можуть бути цілим числом, яке представляє Unix timestamp, або довільним рядком, що представляє *зрозумілу* дату. До тих пір, поки значення можливо розібрати через [strtotime()](http://php.net/manual/function.strtotime.php), ніяка додаткова конвертація не потрібна. Заголовок "Entity Tag" (або скорочено `ETag`) може бути встановлений таким же чином, через [CHttpCacheFilter::etagSeed] та [CHttpCacheFilter::etagSeedExpression], відповідно. Обидва будуть серіалізовані (так що ви зможете використовувати або одне значення, або весь масив) і використовуються для генерації base64-кодованого SHA1 хеша в лапках, який виступає у якості контенту для заголовка `ETag`. Це відрізняється від того, як [веб-сервер Apache](http://httpd.apache.org) та інші створюють свої ETags. Однак, цей метод цілком відповідає вимогам RFC і виявився більш прийнятним для використання у framework. > Note|Примітка: Для того, щоб відповідати [RFC 2616, розділу 13.3.4](http://tools.ietf.org/html/rfc2616#section-13.3.4), [CHttpCacheFilter] буде надсилати заголовки `ETag` та `Last-Modified`, якщо вони обидва можуть бути згенеровані. Відтак, вони обидва будуть використовуватися для перевірки кешу при відправці клієнту. Відколи *entity tags* це хеші, вони дозволяють більш складних і/або більш точних стратегій кешування, ніж заголовки `Last-Modified`. Наприклад, ETag може бути визнаний недійсним, якщо сайт змінив свою тему. > Tip|Підказка: *Важкі* вирази для [CHttpCacheFilter::etagSeedExpression] можуть суперечити меті [CHttpCacheFilter] і запровадити зайве навантаження, так як вони мають бути повторно обчислені при кожному запиті. Спробуйте знайти простий вираз, який визнає недійсним кеш, якщо зміст сторінки було змінено. ### SEO наслідки Як правило, пошукові боти поважають заголовки кешу. Оскільки деякі сканери мають обмеження на кількість сторінок в межах домену, які вони обробляють за певний проміжок часу, запровадження заголовків кешу може допомогти індексації сайту, оскільки вони зменшують кількість сторінок, які повинні бути оброблені.