Разработка сайта для Вашего бизнеса. Веб дизайн. Дизайн логотипа, фирменного стиля, рекламная фотография . Комплексный рекламный креатив.

Ralex. We do the work.
На рынке с 1999го года. Средняя ценовая категория. Ориентация на эффективность решений.
Ознакомтесь с нашим портфолио
Узнайте больше о услугах
Свяжитесь с нами:
E-mail: [email protected]
Tel: (044) 587 - 84 - 78
Custom web design & дизайн и разработка сайта "под ключ"
Креативный, эффективный дизайн. Система управления сайтом (СУС).
Custom flexible разработка систем электронной коммерции
Система e-commerce разрабатывается под индивидуальные потребности. Гибкая функциональность.
Search Engine Optimzation & оптимизация под поисковые системы (SEO)
Постоянная оптимизация и мониторинг сайта в поисковых системах. Достигаем результата быстро и эффективно
Custom logo design & дизайн логотипа и фирменного стиля
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.
профессиональная рекламная фотография
креативно, смело, качественно
Custom logo design & рекламный креатив. дизайн рекламы
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.

Кешування в PHP

  1. Вступ
  2. Як я попереджа кешування сторінки браузерами?
  3. Internet Explorer і кешування завантаження файлів
  4. Як я можу захопити дані на стороні сервера для кешування?
  5. Кілька слів про кешуванні за допомогою шаблонів
  6. Приклад 1. Файл: 1.php
  7. Заголовки HTTP і буферизація виводу
  8. Використання буферизації виведення для кешування на стороні сервера
  9. Приклад 2. Файл: 2.php
  10. блокова буферизация
  11. Приклад 3. Файл: 3.php
  12. Приклад 4. Файл: 3.php
  13. Приклад 5. Файл: 3.php
  14. Приклад 6. Файл: 3.php (закінчення)
  15. вкладені буфери
  16. Як мені керувати кешуванням на стороні клієнта засобами PHP?
  17. Закінчення строку життя сторінки
  18. Приклад 7. 6.php
  19. Час зміни сторінки
  20. Кешування ваших сторінок в 5 кроків
  21. Регенерація змісту на льоту
  22. Проблема з кешуванням сторінок у Internet Explorer.

Вступ

Наша взаимовыгодная связь https://banwar.org/

У старі добрі часи, коли створення web-сайтів являло собою таке просте заняття, як набір декількох HTML-сторінок, відправка web-сторінок в браузер була простою відправкою файлу web-сервером. Відвідувачі сайту могли бачити ці невеликі, виключно текстові сторінки, майже миттєво (якщо не брати до уваги користувачів повільних модемів). Як тільки сторінка була завантажена, браузер кешируєт її де-небудь на локальному комп'ютері, щоб в разі повторного запиту сторінки, можна було взяти його локальну версію з кешу, пославши лише короткий запит, щоб переконатися, що сторінка на сервері не була змінена. Запити оброблялись швидко і як можна ефективніше, і всі були щасливі (крім використовують модеми 9600 бод).

Поява динамічних web-сторінок змінило стан речей в гіршу сторону, ефективно «зламавши» цю модель обслуговування web-сторінок завдяки наявності двох проблем:

  1. Коли сервером отриманий запит динамічної web-сторінки, проводиться деяка проміжна обробка, наприклад синтаксичний аналіз (парсинг) скрипта движком PHP, яка повинна бути завершена. Завдяки цьому отримуємо затримку перед тим, як web-сервер почне відправку виведення в браузер. Для простого PHP -скріпта це не суттєво, але для більш складного додатка движок PHP може виконати багато дій перш ніж сторінка буде готова для відправки. Ці додаткові дії призводять до помітної затримки між запитами користувачів і реальним відображенням сторінок в їх браузерах.
  2. Типовий web-сервер, наприклад Apache, використовує час модифікації файлу щоб правильно повідомити web-браузеру стан кешу запитуваної сторінки. Для динамічних web-сторінок, фактично PHP -скріпт може змінюватися тільки зрідка, в той час як відображається їм контент, можливо розташований в базі даних, змінюється часто. Web-сервер не має можливості знати про наявність змін в базі даних, проте він не відправляє дату останньої модифікації. Якщо клієнт (браузер) не отримує ніякого ознаки того, як довго дані є коректними, він передбачає, що наступного разу необхідно запросити сторінку за новою. Web-сервер завжди буде відповідати оновленою версією сторінки, незалежно від того, чи змінилися дані. Щоб уникнути цього недоліку більшість web-розробників використовують мета-теги або HTTP -заголовкі, щоб повідомити браузеру ніколи не використовувати кешовану версію сторінки. Однак це заперечує природну здатність web-браузера кешувати web-сторінки і володіє деякими істотними недоліками. Наприклад, зміст динамічної сторінки може змінюватися раз на добу, тому вигода, одержувана від наявності навіть 24-годинного кешування сторінки браузером, очевидна.

Зазвичай для маленьких PHP-додатків цілком можна ігнорувати існування цих проблем, проте зі збільшенням складності і підвищенням трафіку Вашого сайту Ви можете зіткнутися з проблемами. Проте, обидві ці проблеми можуть бути вирішені, перша шляхом кешування на стороні сервера, друга шляхом управління кешуванням на стороні клієнта з вашого застосування. Підхід, який ви будете використовувати для вирішення проблем, буде залежати від вашої області застосування, але в цьому розділі ми побачимо, як ви можете вирішити обидві проблеми використовуючи PHP і деякі класи бібліотеки PEAR.

Як я попереджа кешування сторінки браузерами?

Перш ніж ми розглянемо методи клієнтського і серверного кешування, в першу чергу ми повинні зрозуміти, як взагалі запобігти кешування сторінок web-браузером (і проксі-серверами). Основний спосіб досягнення цього використовує мета-теги HTML:

<Meta http-equiv = "Expires" content = "Mon, 26 Jul +1997 5:00:00 GMT" /> <meta http-equiv = "Pragma" content = "no-cache" />

Вставивши минулу дату в мета-тег Expires, ви повідомляєте браузеру, що кешована копія сторінки завжди є застарілою. Це означає, що браузер ніколи не повинен кешувати сторінку. Мета-тег Pragma: no-cache досить добре підтримуване угоду, якому слід більшість web-браузерів. Виявивши цей тег, вони зазвичай не кешують сторінку (хоча ніяких гарантій немає, це всього лише угода).

Це добре звучить, але є дві проблеми, пов'язані з використанням мета-тегів:

  1. Якщо тег не існував коли сторінка була запрошена браузером вперше, але з'являється пізніше (наприклад, ви модифікували включається файл pageheader.php який є шапкою кожної web-сторінки), браузер залишиться в блаженному невіданні і скористається звий кешованої копалень оригіналу.
  2. Проксі-сервери, кешуючий web-сторінки, як наприклад загальний ISP, взагалі не буде досліджувати безпосередньо вміст HTML-документа. Замість цього вони покладаються тільки на web-сервер, з якого прийшли документи, і протокол HTTP . Іншими словами, web-браузер може вважати, що не повинен кешувати сторінку, але проксі-сервер між браузером і вашим web-сервером ймовірно не знає цього - і продовжить відправляти клієнту ту ж саму, вже застарілу, сторінку.

Кращий підхід полягає в тому, щоб використовувати безпосередньо протокол HTTP за допомогою функції PHP header () , Еквівалентно наведеними вище двом мета-тегах:

header ( 'Expires: Mon, 26 Jul 1997 5:00:00 GMT'); header ( 'Pragma: no-cache');

Ми можемо піти на один крок вперед, скориставшись заголовком Cache-Control сумісним з браузерами, які підтримують HTTP 1.1:

header ( 'Expires: Mon, 26 Jul 1997 5:00:00 GMT'); header ( 'Cache-Control: no-store, no-cache, must-revalidate'); header ( 'Cache-Control: post-check = 0, pre-check = 0', FALSE); header ( 'Pragma: no-cache');

Це гарантує, що ніякої web-браузер або проміжний проксі-сервер не буде кешувати сторінку, таким чином відвідувачі завжди отримають найостаннішу версію контенту. Фактично, перший заголовок повинен бути самодостатнім, це кращий спосіб гарантувати, що сторінка не кешируєтся. Заголовки Cache-Control і Pragma додані з метою «підстрахуватися». Хоча вони не працюють у всіх браузерах або проксі, вони відловлять деякі випадки, в яких Expires не працює належним чином (наприклад, якщо дата на комп'ютері клієнта встановлена неправильно).

Звичайно, повна відмова від кешування забезпечує нас проблемами, які ми обговорювали на початку цього розділу. Зараз ми розглянемо рішення цих проблем.

Internet Explorer і кешування завантаження файлів

Якщо при обслуговуванні завантаження файлу PHP -скріптом використовуються такі заголовки, як наприклад Content-Disposition: attachment, filename = myFile.pdf або Content-Disposition: inline, filename = myFile.pdf у вас будуть проблеми з Internet Explorer 'ом, якщо ви повідомите браузер не кешувати сторінку.

Internet Explorer оперує завантаженням досить незвичайним чином, виконуючи два запити до web-сайту. Перший запит завантажує файл і зберігає його в кеші, поки не буде створено другий запит (без збереження відгуку). Цей запит викликає процес передачі файлу кінцевому користувачеві відповідно до типу файлу (наприклад, запускає Acrobat Reader, якщо файл є PDF-документ). Це означає, що якщо ви відправили заголовки, що забороняють браузеру кешувати сторінку, Internet Explorer видалить файл між першим і другим запитом, в результаті чого кінцевий користувач нічого не отримає. Якщо файл, який ви віддаєте PHP -скріптом, не змінюється, одним з найпростіших рішень буде прибрати «забороняють кешування» заголовки з скрипта.

Якщо файл завантаження регулярно змінюється (тобто ви хочете, щоб браузер завантажував нову версію), ви повинні використовувати заголовок Last-Modified, який буде розглянуто в цій главі пізніше, і гарантувати, що час модифікації між двома послідовними запитами не змінюється. Ви повинні зробити це таким чином, щоб не вплинути на користувачів браузерів, правильно оперують завантаженням. Одним з рішень в цьому випадку буде збереження файлу на вашому web-сервері і надання простий посилання до нього, надавши web-серверу повідомляти за вас заголовки кешування. Звичайно, це рішення не може бути прийнятним, якщо передбачається авторизований доступ до файлу, це рішення допускає безпосередню завантаження збереженого файлу.

Як я можу захопити дані на стороні сервера для кешування?

Настав час подивитися на те, як ми можемо зменшити затримку за допомогою кешування виведення на стороні сервера. Загальний підхід починає надавати сторінку як зазвичай, виконуючи запити до бази даних і так далі на PHP. Проте, перед відправкою результату в браузер, ми захоплюємо його і зберігаємо готову сторінку, наприклад, у файлі. При наступному запиті, PHP -скріпт спочатку перевіряє наявність кешованої версії сторінки. Якщо вона існує, скрипт відправляє в браузер версію з кешу, виключаючи таким чином затримку на повторне створення сторінки.

Кілька слів про кешуванні за допомогою шаблонів

шаблонні движки часто говорять про кешуванні шаблонів. Зазвичай ці движки пропонують вбудований механізм для збереження скомпільованій версії шаблону (тобто генерують з шаблону PHP -ісходнік), що оберігає нас від необхідності парсити шаблон кожен раз, коли запитується сторінка. Це не потрібно плутати з кешуванням виведення, яке має відношення до кешуванню наданого HTML (або іншого висновку), який посилає PHP в браузер. Ви можете успішно використовувати обидва типи кешування одночасно на одному і тому ж сайті.

Зараз ми розглянемо вбудований механізм кешування на PHP, який використовує буферизацию виведення, який може використовуватися вами незалежно від способу створення контенту (з шаблонами або без шаблонів). Розглянемо ситуацію в якій ваш скрипт відображає результат використовую, наприклад, echo або print , Щоб видати дані безпосередньо в браузер. В такому випадку ви можете використовувати функції управління виводу PHP для зберігання даних в буферній пам'яті, над якою ваш PHP -скріпт має і доступ, і контроль.

Приклад 1. Файл: 1.php
// Починаємо буферизацию виведення ob_start (); // Виводимо деякий текст (який зберігається в буфері); echo '1. Виводимо це в буфер <br /> '; // Отримуємо вміст буфера $ buffer = ob_get_contents (); // Зупиняємо буферизацию і очищаємо буфер виведення ob_end_clean (); // Виводимо деякий текст звичайним чином echo '2. Нормальний висновок <br /> '; // Висновок вмісту буфера echo $ buffer;

Сам буфер зберігає висновок як рядок. Так, у вищенаведеному скрипті ми починаємо буферизацию з ob_start () і використовуємо echo , Щоб вивести що-небудь. Потім ми використовуємо ob_get_contents () , Щоб вибрати дані, поміщені в буфер оператором echo, і зберегти їх в рядку. функція ob_end_clean () зупиняє буферизацию виведення і знищує його вміст, як альтернативу можна використовувати ob_end_flush () , Щоб вивести вміст буфера.

Вищеописаний скрипт виведе:

2. Нормальний висновок
1. Виводимо це в буфер

Іншими словами, ми захопили висновок першого echo, потім послали його браузеру після другого echo. Як видно з цього простого прикладу, буферизація виводу є дуже потужним інструментом для формування вашого сайту, вона забезпечує рішення для кешування, як ми скоро побачимо, і є відмінним способом приховати помилки від відвідувачів вашого сайту (дивіться Обробка помилок ). Вона також забезпечує альтернативну можливість для переадресації браузера в ситуаціях типу аутентифікації користувача.

Заголовки HTTP і буферизація виводу

Буферизація виводу може допомогти вирішити найбільш загальну проблему, пов'язану з функцією header () , не кажучи вже про session_start () і setcookie () . Зазвичай, якщо ви викликаєте будь-яку з цих функцій після того, як почалося виведення сторінки, ви отримаєте противне повідомлення про помилку. При включеній буферизації виведення єдиним типом виведення, що уникає буферизації, є HTTP -заголовкі. використовуючи ob_start () на самому початку виконання вашої програми, ви можете посилати заголовки в будь сподобалася точці програми, не стикаючись зі звичайними помилками. Потім, як тільки ви будете впевнені, що більше виводити HTTP -заголовкі не буде потрібно, ви можете відразу ж вивести вміст сторінки з буфера.

(прим. перекладача: слід зауважити що подібне використання даної функції вкрай невиправдано. У більшості випадків необхідності в використанні буферизації виведення для позбавлення помилок зазначеного типу просто не існує і все з легкістю може бути виправлено правильним проектуванням додатки)

Використання буферизації виведення для кешування на стороні сервера

Ви вже бачили базовий приклад буферизації виведення, тепер наступний крок, в якому буфер зберігається в файл:

Приклад 2. Файл: 2.php
// Якщо існує кешована версія: if (file_exists ( './ cache / 2.cache')) {// Читаємо і виводимо файл readfile ( './ cache / 2.cache'); exit (); } // Починаємо буферизацию виведення ob_start (); // Виводимо решті HTML?> <! DOCTYPE html PUBLIC "- // W3C // DTD XHTML 1.0 Strict // EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" > <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title> кешуватися сторінка </ title> <meta http-equiv = "Content-Type" content = "text / html ; charset = utf-8 "/> </ head> <body> Ця сторінка кешується засобами PHP <a href="http://www.php.net/outcontrol"> Функції управління виводу </a> </ body> </ html> <? // Отримуємо вміст буфера $ buffer = ob_get_contents (); // Зупинка буферірованія і висновок буфера ob_end_flush (); // Збереження кеш-файлу з контентом $ fp = fopen ( './ cache / 2.cache', 'w'); fwrite ($ fp, $ buffer); fclose ($ fp); ?>

Спочатку вищеописаний скрипт перевіряє наявність існування версії сторінки в кеші, і, якщо вона є, скрипт читає і виводить її. В іншому випадку, він використовує буферизацию виведення для створення версії сторінки в кеші. Вона зберігається як файл, після використання ob_end_flush () для відображення сторінки користувачеві.

Файл 2.cache містить точну копію HTML, яку надає скрипт: <! DOCTYPE html PUBLIC "- // W3C // DTD XHTML 1.0 Strict // EN" "http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd "> <html xmlns =" ​​http://www.w3.org/1999/xhtml "> <head> <title> кешуватися сторінка </ title> <meta http-equiv =" Content-Type " content = "text / html; charset = utf-8" /> </ head> <body> Ця сторінка кешується засобами PHP <a href="http://www.php.net/outcontrol"> Функції управління виводу </ a> </ body> </ html>

блокова буферизация

Спрощений підхід кешируєт виведений буфер як одну сторінку. Однак цей підхід позбавляє вас реальних можливостей, що надаються функціями управління виводу PHP, що поліпшують продуктивність вашого сайту методом відповідно розрізняються термінів життя вашого контенту.

Поза всяким сумнівом, деякі частини відправляється вами відвідувачеві сторінки змінюються дуже рідко, наприклад, такі як шапку, меню і нижній колонтитул. Однак інші частини, типу таблиць, що містять обговорення в форумі, можуть змінюватися досить часто. Буферизація виводу може використовуватися до кешуванню розділів сторінки в окремих файлах, потім створювати з них сторінку - рішення, що усуває необхідність повторних запитів до бази даних, циклів while і т.д. Ви можете призначати кожному блоку сторінки дату закінчення терміну, після якої пересоздаётся кеш-файл, або крім того, ви можете включити в вашу програму механізм, який буде видаляти кеш-файл кожного разу, коли збережений в ньому контент змінений.

Ось приклад, який демонструє цей принцип:

Приклад 3. Файл: 3.php
<? / * Запис кеш-файлу * @param string contents - зміст буфера * @param string filename - ім'я файлу, що використовується при створенні кеш-файлу * @return void * / function writeCache ($ content, $ filename) {$ fp = fopen ( './cache/'. $ filename, 'w'); fwrite ($ fp, $ content); fclose ($ fp); } / * Перевірка кеш-файлів * @param string filename - ім'я перевіряється кеш-файлу * @param int expiry - максимальний "вік" файлу в секундах * @return mixed вміст кеша або false * / function readCache ($ filename, $ expiry) {if (file_exists ( './ cache /'. $ filename)) {if ((time () - $ expiry)> filemtime ( './ cache /'. $ filename)) return FALSE; $ Cache = file ( './ cache /'. $ Filename); return implode ( '', $ cache); } Return FALSE; }?>

Перші дві певні нами функції, writeCache і readCache, використовуються відповідно для створення кеш-файлів і перевірки їх існування. Функція writeCache отримує дані для кешування в першому аргументі, і ім'я файлу, що використовується при створенні кеш-файлу. Функція readCache отримує ім'я кеш-файлу в першому параметрі, разом з часом в секундах, після якого кеш-файл повинен вважатися застарілим. Якщо вона вважатиме кеш-файл допустимим, скрипт поверне його вміст, в іншому випадку він поверне FALSE, щоб показати, що-небудь кеш-файлу не існує, або він застарів.

У цьому прикладі я використав процедурний підхід. Однак я не раджу робити це на практиці, оскільки це закінчиться дуже брудним кодом (дивись наступні рішення з кращою альтернативою) і, ймовірно, призведе до проблем з блокуванням файлу (наприклад, що трапиться, коли хтось звертається до кешу в момент його оновлення? ).

Давайте продовжимо цей приклад. Після того, як запущена буферизація висновку, починається обробка. Спочатку скрипт викликає readCache, щоб дізнатися, чи існує файл 3_header.cache, він містить шапку сторінки - заголовок HTML і початок тіла. Ми використовуємо функцію date () щоб вивести час, коли сторінка фактично була згенерована, таким чином ви побачите різні кеш-файли в роботі, коли не буде працювати.

Приклад 4. Файл: 3.php
<? // ПОЧИНАЄМО буферизацию Виведення ob_start (); // Обробка шапки if (! $ Header = readCache ( '3_header.cache', 604800)) {// Висновок шапки?> <! DOCTYPE html PUBLIC "- // W3C // DTD XHTML 1.0 Strict // EN" "http: //www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns = "http : //www.w3.org/1999/xhtml "> <head> <title> Сторінка, кешована по блоках </ title> <meta http-equiv =" Content-Type "content =" text / html; charset = utf -8 "/> </ head> <body> Час создания шапки: & lt ;? = Date ( 'H: i: s'); ?&gt; <br /> <? $ Header = ob_get_contents (); ob_clean (); writeCache ($ header, '3_header.cache'); }?>

Що ж Трапляється коли кеш-файл не знайдено? Виводу Деяк контент и прісвоюється змінної с помощью ob_get_contents () , После чего буфер очіщається функцією ob_clean () . Це дозволяє нам перехоплюваті Висновок по Частина І зіставляті їх з індівідуальнімі кеш-файлами с помощью writeCache. Заголовок сторінки тепер зберігається як файл, який може бути використаний без нашого втручання в перезбирання сторінки. Давайте повернемося на секунду до початку умовного оператора. Коли ми викликали readCache, ми передали їй час життя кешу в 604800 секунд (один тиждень), readCache використовує час модифікації кеш-файлу, щоб визначити, чи є кеш-файл все ще допустимим.

Для вмісту (тіла) сторінки ми як і раніше будемо використовувати той же процес. Однак цього разу при виклику readCache ми будемо використовувати час життя кешу в п'ять секунд, кеш-файл буде модифікуватися кожен раз, коли він «старше» 5 секунд:

Приклад 5. Файл: 3.php
<? // Обробка тіла сторінки if (! $ Body = readCache ( '3_body.cache', 5)) {echo 'Час створення тіла:'. date ( 'H: i: s'). '<br />'; $ Body = ob_get_contents (); ob_clean (); writeCache ($ body, '3_body.cache'); }?>

Нижній колонтитул ефективно змінювати так само, як заголовок. Після цього буферизація висновку зупиняється і відображається вміст трьох змінних, що містять дані сторінки:

Приклад 6. Файл: 3.php (закінчення)
<? // Обробка нижнього колонтитула сторінки if (! $ Footer = readCache ( '3_footer.cache', 604800)) {?> Час створення нижнього колонтитула: & lt;? = Date ( 'H: i: s'); ?> <br /> </ body> </ html> <? $ Footer = ob_get_contents (); ob_clean (); writeCache ($ footer, '3_footer.cache'); } // зупиняємо буферизацию ob_end_clean (); // Виводимо вміст сторінки echo $ header. $ Body. $ Footer; ?>

Кінцевий результат виглядає приблизно так:

Час створення шапки: 17:10:42 Час створення тіла: 18:07:40 Час створення нижнього колонтитула: 17:10:42

Тема і нижній колонтитул оновлюються щотижня, в час як тіло модифікується, коли воно старіше 5 секунд.

Блок-схема на малюнку підсумовує методологію блокової буферизації.


Блок-схема блокової буферизації виведення

вкладені буфери

Ви можете вкладати один буфер в інший фактично до нескінченності, просто викликавши ob_start () Неодноразово. Це може бути корисним, якщо у вас є безліч операцій, що використовують буфер виведення, наприклад, одні перехоплюють повідомлення PHP про помилки, інші мають справу з кешуванням. Ви повинні упевнитися, що ob_end_flush () або ob_end_clean () викликаються кожен раз, коли використовується ob_start () .

Як мені керувати кешуванням на стороні клієнта засобами PHP?

Настав час подивитися на механізм, який дозволить нам контролювати кеш на стороні клієнта засобами PHP. Цей підхід буде працювати тільки якщо ви використовуєте PHP у зв'язці з сервером Apache, оскільки ми будемо використовувати функцію getallheaders () , Щоб отримати заголовки, передані браузером. Ця функція працює тільки в Apache.

Нові імена функцій

Якщо ви використовуєте PHP 4.3.0 з Apache, HTTP-заголовки доступні функцією apache_request_headers () и apache_response_headers () . функція getallheaders () стала псевдонімом для нової функції apache_request_headers () .

Механізмом для роботи з кешем web-браузера знову є HTTP. Безліч заголовків залучений в інструктування web-браузерів і проксі-серверів незалежно кешувати сторінку, ситуація ускладнюється тим фактом, що деякі з них доступні тільки з HTTP 1.1.

Перевірка HTTP-заголовків у вашому браузері

Простим але дуже зручним інструментом для перевірки заголовків запитів і відгуків є LiveHttpHeaders - аддон до браузеру Mozilla. Необхідно точно знати, які заголовки посилає ваш скрипт, особливо коли ви маєте справу з заголовками кешування HTTP.

Для простоти ми розглянемо тільки заголовки кешування HTTP 1.0, а саме Expires, Last-Modified і If-Modified-Since, а також статус-код HTTP 304 (Not Modified).

Інші заголовки, доступні з HTTP 1.1, наприклад Cache-Control і ETag, призначені для забезпечення розширеного механізму, який може використовуватися спільно зі станом web-сесії, іншими словами, версія даної сторінки, яка відображається неавторизованого відвідувачеві, може значно відрізнятися від інформації, авторизованому користувачеві. Заголовки HTTP 1.1 спочатку додавалися для того, щоб дозволити кешувати такі сторінки.

Закінчення строку життя сторінки

Найпростішим у використанні заголовком є заголовок Expire, який встановлює дату (можливо, майбутню), коли сторінка застаріє. До цього моменту web-браузеру дозволяється використовувати кешовану версію сторінки.

Приклад 7. 6.php
<? / ** * Посилає заголовок Expires HTTP 1.0. * @Param int $ expires - кількість секунд до часу закінчення терміну життя * / function setExpires ($ expires) {header ( 'Expires:'. Gmdate ( 'D, d MYH: i: s', time () + $ expires) . 'GMT'); } // Встановлюємо заголовок часу закінчення терміну життя Expires setExpires (10); // Відображаємо echo 'Ця сторінка самознищиться через 10 секунд & lt; br / & gt;'; echo 'Зараз'. gmdate ( 'H: i: s'). 'GMT & lt; br / & gt;'; echo '& lt; a href = "'. $ _SERVER [ 'PHP_SELF']. '" & gt; Подивитися знову & lt; / a & gt; & lt; br / & gt;'; ?>

Функція setExpires відправляє заголовок HTTP Expires з майбутнім часом, заданому в секундах. Вищенаведений приклад показує поточний час за Гринвічем і виводить посилання, яка вам дозволяє перейти на сторінку знову. Використовуючи кнопку Refresh вашого браузера, ви можете повідомити браузеру про бажання оновити кеш. Використовуючи посилання, ви побачите, що час змінюється тільки раз в 10 секунд.

Дати і час в HTTP

Дати в HTTP завжди обчислюються відносного меридіана часом Грінвіча (GMT). функція PHP gmdate () точно така ж функція, як date () , За винятком того, що вона автоматично компенсує час за Гринвічем, засноване на системному годиннику і настройках регіону вашого сервера.

Коли браузер стикається з заголовком Expires, він кешируєт сторінку. Усі наступні запити сторінки, зроблені до зазначеного часу закінчення терміну життя, використовують версію сторінки з кешу, ніяких запитів до web-серверу при цьому не відбувається.

Тема Expires переважно простий в реалізації, але в більшості випадків, якщо ви не високоорганізована людина, ви не можете знати точно, коли дана сторінка вашого сайту оновлена. Оскільки браузер увійде в контакт з сервером тільки після того, як сторінка застаріє, немає жодного способу повідомити браузеру, що сторінка, яка перебуває в його кеші, застаріла. Ви також втрачаєте деяку частину трафіку до вашого web-сайту, оскільки браузер не звертається до сервера при запиті сторінки з кешу.

Час зміни сторінки

Більш практично використовувати заголовки Last-Modified і If-Modified-Since, доступні в HTTP 1.0. Технічно він відомо як виконання умовного GET-запиту, ви повертаєте будь-який контент, грунтуючись на умови прийшов заголовка запиту If-Modified-Since.

При використанні цього методу ви повинні відправляти заголовок Last-Modified кожен раз, коли звертаються до вашого PHP-скрипту. При наступному запиті сторінки браузером, він відправить заголовок If-Modified-Since, що містить час, за яким ваш скрипт може визначити, оновлювалася чи сторінка з часу останнього запиту. Якщо це не так, ваш скрипт посилає код статусу HTTP 304, щоб вказати, що сторінка не змінювалася, не вивільняючи при цьому вмісту сторінки.

Встановлюємо час модифікації кеш-файлу цим рядком: $ lastModified = filemtime ($ cache_file);

Потім, використовуючи час модифікації кеш-файлу, ми посилаємо заголовок Last-Modified. Нам потрібно посилати її для кожної наданої сторінки, щоб змусити браузер посилати нам заголовок If-Modified-Since з кожним запитом.

// Видаємо заголовок HTTP Last-Modified header ( 'Last-Modified:'. Gmdate ( 'D, d MYH: i: s', $ lastModified). 'GMT');

Використання функції getallheaders () забезпечує нам отримання від PHP всіх вхідних заголовків у вигляді масиву. Потім ми повинні перевірити, що заголовок If-Modified-Since дійсно існує, якщо він є, ми повинні обробити спеціальний випадок старих версій Mozilla (нижче 6й версії), який додавав в кінець додаткове поле до заголовку If-Modified-Since. Використовуючи функцію PHP strtotime () , Ми отримуємо таймштамп дати, переданої нам браузером. Якщо такого заголовка немає, ми присвоюємо таймштампу нуль, змушуючи таким чином PHP віддати відвідувачеві останню версію сторінки.

<? // Отримуємо заголовки запиту клієнта - тільки для Apache $ request = getallheaders (); if (isset ($ request [ 'If-Modified-Since'])) {// Поділяємо If-Modified-Since (Netscape & lt; v6 віддає їх неправильно) $ modifiedSince = explode ( ';', $ request [ 'If- Modified-Since ']); // Перетворимо запит клієнта If-Modified-Since в таймштамп $ modifiedSince = strtotime ($ modifiedSince [0]); } Else {// Встановлюємо час модифікації в нуль $ modifiedSince = 0; }?>

Нарешті, ми перевіряємо, чи був модифікований кеш з тих пір як відвідувач отримував цю сторінку в останній раз. Якщо це не так, ми просто посилаємо в заголовку відгук Not Modified і припиняємо виконання скрипта, не навантажуючи канал передачі даних і заощаджуючи процесорний час, інструктуючи браузер відобразити кешовану версію сторінки.

<? // Порівнюємо час останньої модифікації контенту з кешем клієнта if ($ lastModified <= $ modifiedSince) {// Розвантажуємо канал передачі даних! header ( 'HTTP / 1.1 304 Not Modified'); exit (); }?>

І на закінчення готовий шматок коду, що дозволяє кешувати все статичні ваші сторінки.

index.php - через нього завантажуються всі файли з сервера. Налаштування зроблена за допомогою .htaccess

<? $ Url = $ _SERVER [ 'REQUEST_URI']; if ($ url == "" || $ url == "/") $ url = "index.htm"; else $ url = substr ($ url, 1); if (! file_exists ($ url)) {header ( "HTTP / 1.0 404 Not Found"); exit ();} // Отримуємо час останньої модифікації кеш-файлу $ lastModified = max (filemtime ($ url), filemtime ( 'index.php')); $ SlastModified = gmdate ( 'D, d MYH: i: s', $ lastModified). 'GMT'; // Видаємо заголовок HTTP Last-Modified header ( 'Last-Modified:'. $ SlastModified); // Отримуємо заголовки запиту клієнта - тільки для Apache $ headers = getallheaders (); if (isset ($ headers [ 'If-Modified-Since'])) {// Поділяємо If-Modified-Since (Netscape <v6 віддає їх неправильно) $ modifiedSince = explode ( ';', $ headers [ 'If-Modified -Since ']); // Перетворимо запит клієнта If-Modified-Since в таймштамп $ modifiedSince = strtotime ($ modifiedSince [0]); // Порівнюємо час останньої модифікації контенту з кешем клієнта if ($ lastModified <= $ modifiedSince) // Розвантажуємо канал передачі даних! {Header ( 'HTTP / 1.1 304 Not Modified'); exit (); }} Echo "<DOCTYPE HTML PUBLIC \" - // W3C // DTD HTML 4.0 Transitional // EN \ "> \ n <HTML> \ n"; echo "<HEAD> \ n"; echo "<META HTTP-EQUIV = \" Content-Type \ "CONTENT = \" text / html; charset = utf-8 \ "> \ n"; echo "<meta http-equiv = \" Last-Modified \ "content = \" ". $ slastModified." \ "& gt; \ n"; ?>

Якщо ви об'єднаєте підхід часу останньої зміни зі значенням часу, що є вже доступним у вашому додатку (наприклад, час самої останньої новинний статті, або час старіння з системи серверного кешування, яке ми бачили в останньому рішенні), ви зможете скористатися перевагами кеша web-браузера і розвантажите канал передачі даних, по можливості заощадивши інформаційний трафік з вашого сайту і поліпшивши його продуктивність.

Будьте обережні при тестуванні будь-якого кешування, виконаного в такому стилі, якщо ви зробите це неправильно, ви можете змусити ваших відвідувачів завжди мати застарілі копії вашого сайту.


Кешування ваших сторінок в 5 кроків


оригінал: Posted in PHP / JavaScript by ibzi on the February 17th, 2007
Переклад: Кузьма Феськов ( [email protected] , http://kuzma.russofile.ru )

Кешування ваших сторінок може виявитися красивим і корисним механізмом, особливо, якщо вони генеруються засобами PHP і роблять безліч SQL запитів. Як тільки ви застосуєте кешування, ваш сервер тут же знизить навантаження і перестане з'їдати багато пам'яті на генерацію сторінок - він просто буде завантажувати їх з кешу. Я покажу вам, як PHP може кешувати сторінки і, в подальшому, ви зможете витрачати на це хвилин 5.


Розглянемо технологію кешування пошагам:

  1. В домашній директорії створюємо файли .htaccess, start_cache.php, end_cache.php, а також папку з назвою cache_files.
  2. Папці cache_files необхідно проставити атрибути 777.
  3. Усередині .htaccess файлу пропишіть наступні рядки: php_value auto_prepend_file /home/username/public_html/start_cache.php php_value auto_append_file /home/username/public_html/end_cache.php Рядок / home / username / public_html / необхідно замінити на шлях до вашої домашньої директорії.
  4. У скрипт start_cache.php поміщаємо наступний код: <? Php // розділ налаштувань, які ви можете змінювати $ settings_cachedir = '/ home / username / public_html / cache_files /'; $ Settings_cachetime = 3600; // час життя кешу (1 година) // код $ thispage = 'http: //'. $ _SERVER [ 'HTTP_HOST']. $ _SERVER [ 'REQUEST_URI']; $ Cachelink = $ settings_cachedir.md5 ($ thispage). ". Html"; if (file_exists ($ cachelink)) {$ cachelink_time = filemtime ($ cachelink); if ((time () - $ settings_cachetime) <$ cachelink_time) {readfile ($ cachelink); die (); }} Ob_start (); ?> Не забувайте виправляти шлях / home / username / public_html / на шлях до вашої домашньої директорії.
  5. А наступний код помістіть в скрипт end_cache.php: <? Php $ fp = fopen ($ cachelink, 'w'); fwrite ($ fp, ob_get_contents ()); fclose ($ fp); ob_end_flush (); ?>

Всі ваші сторінки будуть кешуватися на 3600 секунд = 1 годину. Цей параметр ви легко можете поміняти в скрипті start_cache.php. Кеш сторінок буде збережений в папці cache_files.

Цілком очевидно, що в даному випадку атрибути 777 є певним порушенням безпеки. У зв'язку з чим, рекомендую винести папку cahce_files за межі public_html, наприклад, помістити її на один рівень вище. Це закриє доступ до знаходяться в ній файлів користувачів вашого сайту, але ніяк не вплине на працездатність системи.

Також, у даного методу є ще один серйозний недолік: автор статті складає весь кеш в одну папку, що, при достатній кількості сторінок на вашому сайті, викличе проблему, наприклад, в системах Unix спостерігається достатня уповільнення працездатності при наявність в папці більш ніж 1000 файлів . У зв'язку з чим, в алгоритм необхідно внести ряд змін і розкладати файли по окремим підпапках всередині папки cache_files. Наприклад, використовуючи для цього перші 3-4 символу md5 кеша.

Для динамічних ресурсів цілком можливо вибрати час кешування в кілька (5-10) секунд або 1-2 хвилини, що вже значно знизить навантаження на сервер, але не завдасть шкоди інтерактивності сайту.

Для сторінок, для яких особливо важлива інтерактивність, можна ввести виключення в .htaccess , Що дозволить саме їм постійно змінюватися, а для решти сторінок можна застосовувати кешування.

всі функції PHP для буферизації виведення

Регенерація змісту на льоту

Динамічно створені, але статично обслуговуються сторінки, тобто сторінки які повинні передаватися як чисто статичні (зчитуються з файлової системи і потім передаються на вимогу), проте вони повинні бути динамічно сгенерірованни веб-сервером якщо вони відсутні в файлової системі. Таким чином ви можете мати сторінки згенеровані PHP які є статично обслуговуються якщо тільки хто-небудь (або планувальник) не вилучено статичну зміст. В такому випадку зміст оновлюється.

Це робиться наступним набором директив:

RewriteCond% {REQUEST_FILENAME}! -S RewriteRule ^ page \ .html $ page.php [T = application / x-httpd-php, L]

Тут, запит до page.html призводить до внутрішнього запуску відповідного page.php, якщо page.html все-ще відсутня або має нульовий розмір. Фокус тут в тому що page.php це звичайний PHP скрипт який на додаток до власного висновку, записує свій висновок в файл page.html. Запустивши це один раз, сервер передає дані page.html. Коли веб-майстер хоче оновити зміст, він просто видаляє page.html (зазвичай за допомогою cronjob).

Проблема з кешуванням сторінок у Internet Explorer.

У IE при роботі з заголовком "Vary" зустрічається одна неприємна помилочка, пов'язана з кешуванням сторінок. Проблема вирішується додаванням в .htaccess наступних рядків:

BrowserMatch "MSIE" brokenvary = 1 BrowserMatch "Mozilla / 4. [0-9] {2}" brokenvary = 1 BrowserMatch "Opera"! Brokenvary SetEnvIf brokenvary 1 force-no-vary
Директиви кешування в заголовку HTTP-запиту
Читати далі: Обробка помилок в PHP
Як я попереджа кешування сторінки браузерами?
Як я можу захопити дані на стороні сервера для кешування?
Net/outcontrol"> Функції управління виводу </a> </ body> </ html> <?
Наприклад, що трапиться, коли хтось звертається до кешу в момент його оновлення?
ПОЧИНАЄМО буферизацию Виведення ob_start (); // Обробка шапки if (! $ Header = readCache ( '3_header.cache', 604800)) {// Висновок шапки?
Date ( 'H: i: s'); ?
Gt; <br /> <?
Категории
  • Биология
  • Математика
  • Краеведению
  • Лечебная
  • Наука
  • Физике
  • Природоведение
  • Информатика
  • Новости

  • Новости
    https://banwar.org/
    Наша взаимовыгодная связь https://banwar.org/. Запустив новый сайт, "Пари Матч" обещает своим клиентам незабываемый опыт и возможность выиграть крупные суммы.


    Наши клиенты
    Клиенты

    Быстрая связь

    Тел.: (044) 587-84-78
    E-mail: [email protected]

    Имя:
    E-mail:
    Телефон:
    Вопрос\Комментарий: