ProfiPHPProfiPHP
Категория: Полезное в PHP

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

В данной теме опишем реализацию простой системы кеширования страниц в PHP.

На данный момент совсем не важно, как именно осуществляется вывод динамической информации сайта, или чтением из файла или с MySQL, мы все равно организуем перевод динамики в статику.

Несколько слов о самом процессе кэширования и буферизации.

Существует много вариантов реализации буферов вывода. Помимо пользовательского буфера существует специальные модули web-сервера для выполнения данного задания, плюс браузеры умеют работать с буфером.

Работа с буфером вывода в PHP всегда должна начинается с функции Ob_start.
// включаем буфер
ob_start( );
echo 'hello world';
Функции для работы с буфером имеют префикс "ob_", что являет собой сокращение от "output buffer".

Весь последующий вывод после функции Ob_start будет попадать в буфер вывода.

Для сохранения данных и обработки вывода можно воспользоваться функцией Ob_get_contents.
ob_start( );
echo 'hello world';
$buffer = ob_get_contents( );
После сохранения данных можно очистить и отключить буфер. Для этих целей существует функция Ob_end_clean.
ob_start( );
echo 'hello world';
$buffer = ob_get_contents( );
ob_end_clean( );
Если вывод не был осуществлен пользователем, тогда PHP самостоятельно выполнит "сброс" буфера вывода в браузер пользователя.

Буфер можно отправить (сбросить) в браузер (ключевое слово flush), очистить (clean) или отключить (end).

Ob_clean — очищаем буфер вывода;

Ob_flush — отправляем буфер вывода;

Ob_end_clean — буфер вывода отключаем и очищаем;

Ob_end_flush — буфер вывода отключаем и отправляем в браузер;

Ob_get_clean — получаем буфер вывода, очищаем и отключаем;

Ob_get_flush — отправляем буфер вывода, очищаем и отключаем;

Операции над буфером определяются параметром $flags при вызове функции Ob_start.

Если захотите создать обертку над всем кодом, можно включить директиву Output_buffering. Данная директива поможет избежать ошибок вида "headers already sent", но ее использование нежелательно.

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

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

Приступим к практической стороне данной проблемы:
// Получаем имя файла с 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 секунд, то есть одного часа. Если условие выполняется, тогда просто подключаем файл-кэш, иначе включаем буферизацию вывода, выводим динамическое содержимое страницы, записываем в файл содержимое буфера, очищаем и отключаем буферизацию вывода с выводом содержимого буфера пользователю.

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

Добавить комментарий

Имя:
Текст комментария: