Кэширование данных

Кэширование данных

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

Для демонстрации решения задачи текущего урока, мы воспользуемся исходниками урока Вывод многоуровневого меню с неограниченным уровнем вложенности

скачать исходникискачать урок

Многоуровневое меню – это как раз тот элемент, который лучше всего покажет принцип и необходимость кэширования. Наше многоуровневое меню использует 2 ресурсоемкие операции – работа с БД и рекурсия. При использовании кэша мы можем избежать обеих операций. Вместо них мы просто считаем файл кэша с готовым html-кодом меню, и выведем это меню там, где нам нужно.

Итак, для вывода многоуровневого меню мы используем функцию view_cat(), которая не возвращает результат, а сразу выводит его на экран. Если мы хотим использовать кэширование, то нас не устраивает подобное поведение функции, нам нужно, чтобы функция именно возвращала код меню, а не выводила его на экран. Поэтому давайте немного изменим ее код, возвращая код:

//вывод каталогa с помощью рекурсии		
function view_cat($arr,$parent_id = 0) {

	//Условия выхода из рекурсии
	if(empty($arr[$parent_id])) {
		return;
	}
	$menu .= '<ul>';
	//перебираем в цикле массив и выводим на экран
	for($i = 0; $i < count($arr[$parent_id]);$i++) {
		$menu .= '<li><a href="?category_id='.$arr[$parent_id][$i]['id'].
					'&parent_id='.$parent_id.'">'
					.$arr[$parent_id][$i]['title'].'</a>';
		//рекурсия - проверяем нет ли дочерних категорий
		$menu .= view_cat($arr,$arr[$parent_id][$i]['id']);
		$menu .= '</li>';
	}
	$menu .= '</ul>';
	
	return $menu;
}

Теперь в файле с меню получим результат работы функции в переменную $menu и выведем значение переменной:

// получаем массив каталога
$result = get_cat();
$menu = view_cat($result);

//Выводи каталог на экран с помощью рекурсивной функции
echo '<div style="width:300px;float:left; padding:10px; border:1px solid #074776">';
echo $menu;
echo '</div>';

Отлично! Меню выводится. Теперь добавим опцию кэширования. Давайте определимся с алгоритмом.

Сейчас мы в любом случае вызываем 2 функции – get_cat() и view_cat() – для вывода меню. Первая функция работает с БД, вторая – с рекурсией. Сейчас же мы должны работать с этими функциями по условию – только в том случае, если у нас нет файла кэша. Если же файл кэша есть и в нем есть содержимое, тогда мы просто считаем это содержимое, не обращаясь к двум указанным функциям.

В файле functions.php создадим 2 дополнительные функции – функция для создания файла кэша и для чтения этого файла.

// создание файла кэша
function cache_file_create($data, $file){

}

// чтение файла кэша
function cache_file_read($file){

}

Функция cache_file_create() в качестве параметров принимает данные для записи в файл кэша. Функция cache_file_read() в качестве параметра принимает путь к файлу кэша.

Теперь создадим папку для файлов кэша – cache. Файл с кэшем меню у нас будет называться menu.html. Давайте определим в индексном файле переменную, в которой будем хранить путь к файлу кэша:

$menu_cache = "cache/menu.html";

Ну и создадим условие, согласно которому будем получать данные из кэша или из БД:

$menu_cache = "cache/menu.html";

if( file_exists($menu_cache) ){
	$menu = cache_file_read($menu_cache);
}else{
	// получаем массив каталога
	$result = get_cat();
	$menu = view_cat($result);
	
	cache_file_create($menu, $menu_cache);
}

Итак, здесь все довольно просто. Мы проверяем, существует ли файл кэша. Если он существует – получаем результат работы функции cache_file_read(). Иначе – получаем данные из БД и записываем их в кэш функцией cache_file_create().

Осталось описать функции для работы с кэшем. Функция cache_file_create():

// создание файла кэша
function cache_file_create($data, $file){
	$handle = fopen($file, "w"); // открываем файл на запись или создаем, если его нет
	flock($handle, LOCK_EX); // блокируем файл для единоличного пользования
	fwrite($handle, $data); // записываем в него данные
	flock($handle, LOCK_UN); // разблокируем файл
	fclose($handle); // закрываем файл
}

Функция cache_file_read():

// чтение файла кэша
function cache_file_read($file){
	if( !$menu = file_get_contents($file) ){
		// если файл пуст
		$result = get_cat(); // получаем данные из БД
		$menu = view_cat($result); // формируем меню
		cache_file_create($menu, $file); // записываем меню в кэш
	}
	return $menu; // возвращаем меню
}

Вот, собственно и все. Мы решили задачу создания простой системы кэширования для сайта. Теперь в Ваших силах улучшить ее и адаптировать под собственные нужды. Например, можно объединить обе функции кэширования в одну, можно учесть устаревание данных кэша для их автоматического периодического обновления и т.д.

На этом наш урок завершен. Удачи Вам и до новых встреч!

Хотите узнать, что необходимо для создания сайта?

Посмотрите 3-х минутное видео и у Вас будет четкий пошаговый план по созданию сайта с нуля!

Смотреть видео

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (4)

  1. VLAD

    А что если файл существует и я в базе что-то изменил? Мне придётся его удалять, чтобы он перезаписался. Как сделать так, что если сервер вернул заголовок not modified, то брать из кэша, а если нет, то из базы?

    • Андрей Кудлай

      Если не ошибаюсь, то в уроке я об этом говорил. Все зависит от частоты обновления кэшируемого материала и перекэшировать можно по времени (периодически файл кэша перезаписывается обновленными данными) либо же по требованию (в админке создается функция обновления файла кэша).

  2. Армен

    Поясните, пожалуйста, в чем изюминка данной системы кеширования…
    Исходя из кода, в качестве альтернативы получения меню из БД, получаем то же самое меню из файла (после проверки на его существование). В этом случае, не проще ли хранить всю разметку меню в файле и без всяких проверок инклюдить…

    • Андрей Кудлай

      Изюминка кэширования заключается в выигрыше в скорости. Например, если взять определение термина кэш из Википедии, то можно прочесть, что:
      Кэш — промежуточный буфер с быстрым доступом, содержащий информацию, которая может быть запрошена с наибольшей вероятностью. Доступ к данным в кэше осуществляется быстрее, чем выборка исходных данных из более медленной памяти или удаленного источника, однако её объем существенно ограничен по сравнению с хранилищем исходных данных.
      Относительно урока, суть заключается в том, мы можем опустить несколько этапов (получение данных из БД, построение дерева меню) и сразу взять готовое меню из кэша. Тем самым мы получаем очевидный выигрыш в скорости.
      По поводу проверки на существование файла, то она необходима. Изначально (как только запустили сайт) ведь файла просто быть не может… ну разве что мы его создадим вручную. Именно поэтому данная проверка необходима. К тому же иногда просто необходимо произвести операцию очистки кэша, в данном случае попросту удалить файл с готовым меню. Сделать эту операцию нужно в том случае, если изменилась структура меню в БД: добавился или удалился пункт меню и т.п. Поэтому мы должны перестроить кэш, удалив файл, и далее создать файл с новым меню. Вот поэтому-то и нужна данная проверка, поскольку в момент сброса кэша файла попросту не будет, и мы должны его создать, поместив в него готовое меню.

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree