1. Головна
  2. Колонка автора
  3. Проста система кешування і буферизації на PHP

Проста система кешування і буферизації на PHP

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

Для роботи з буфером виведення в PHP використовується функція Ob_start. Функції для роботи з буфером мають префікс "ob_" (скорочення від output buffer). Весь наступний вивід після функції Ob_start потраплятиме в буфер виведення. Для збереження даних та обробки виведення необхідно скористатися функцією Ob_get_contents. Після збереження даних можна очистити і відключити буфер за допомогою функції Ob_end_clean.
ob_start();
echo 'hello world';
$buffer = ob_get_contents();
ob_end_clean();
Якщо вивід не був здійснений користувачем, тоді PHP самостійно виконає "скидання" буфера виводу у веббраузер користувача. Буфер можна відправити (скинути) у веббраузер (ключове слово flush), очистити (clean) або відключити (end).

Зараз майже всі сучасні вебсайти використовують динамічні генерації сторінок. Щоб заощадити ресурси і час, використовують кешування сторінок. Практично одним недоліком даного процесу є його старіння. Наприклад, вміст сторінки змінився, а кеш далі продовжує відображати старі дані. Боротися з цим можна, якщо контролювати життя кешу за часом або самостійно його очищати при редагуванні матеріалу:
// Отримуємо ім'я файлу з URL за допомогою шифрування md5 
$cache_file = $_SERVER['DOCUMENT_ROOT'].'/cache/'.md5($_SERVER['REQUEST_URI']).'.tmp';
// Якщо файл кеша існує і оновлювався менш ніж годину тому, тоді підключаємо його
if (file_exists($cache_file) && (time() - filemtime($cache_file)) < 3600) {
exit(include($cache_file));
} else {
// Включаємо буферизацію виведення
ob_start();
// Тут повинна бути згенерована сторінка
echo 'text text text';

// Зберігаємо вміст сторінки в кеш-файл
$fopendb = fopen($cache_file, 'w+');
flock($fopendb, LOCK_EX);
fwrite($fopendb, ob_get_contents());
flock($fopendb, LOCK_UN);
fclose($fopendb);
ob_end_flush();
}
Спочатку скрипт перевіряє, чи існує файл з кешем, якщо результат успішний - робить ще перевірку на життя файлу в 3600 секунд, тобто одну годину. Якщо умова виконується, тоді просто підключаємо файл-кеш, інакше включаємо буферизацію виведення, виводимо динамічний вміст сторінки, записуємо у файл вміст буфера, очищаємо і відключаємо буферизацію виведення з відображенням вмісту буфера користувачеві. Цей код дуже швидкий, легкий, і може принести дуже велику продуктивність і швидкість вашого вебсайту.

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

Для прикладу, кешовані файли будуть зберігатися у директорії cache, але у різних підкатегоріях, в залежності від типу сторінки, наприклад:
/cache/comments
/cache/post
Вміст сторінки зберігатиметься у змінній $content.
function operation_cache($operation, $path, $cacheData = '') {
// Перевірка існування директорії
if (!is_dir($_SERVER['DOCUMENT_ROOT'].'/cache/'.$path)) return false;
// Отримуємо зашифрований в MD5 URL
$cache_file = $_SERVER['DOCUMENT_ROOT'].'/cache/'.$path.'/'.md5($_SERVER['REQUEST_URI']).'.tmp';
switch ($operation) {
// Перевірка
case "exists":
// Створюємо глобальну змінну, яка містить дані для кешування
global $cache_data;
$cache_data = '';
// Повертаємо результат
return file_exists($cache_file) ? file_get_contents($cache_file) : false;
break;
// Створення
case "create":
$fopendb = fopen($cache_file, 'w+');
flock($fopendb, LOCK_EX);
fwrite($fopendb, $cacheData);
flock($fopendb, LOCK_UN);
fclose($fopendb);
return $cacheData;
break;
// Видалення
case "clear":
$array_delete_files = glob($_SERVER['DOCUMENT_ROOT'].'/cache/'.$path.'/*');
foreach ($array_delete_files as $object) {
@chmod($object, 0777);
unlink($object);
}
break;
}
}

$content = '';
// Перевіряємо існування файла кешу
if ($cache_import = operation_cache('exists', 'comments')) {
// Якщо існує, передаємо зміст змінній
$content .= $cache_import;
} else {
// Виводимо зміст сторінки
$cache_data .= 'text text text';

// Зберігаємо кеш файл и повертаємо результат
$content .= operation_cache('create', 'comments', $cache_data);
}

// Очищуємо директорію з кешованими сторінками
operation_cache('clear', 'comments');

Пояснення до коду міститься у коментарях, тому більш докладно пояснювати не потрібно.

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

Коментарі

Підписуйтесь на наш канал у Telegram! 🚀

@kovelpost