[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Кэширование для нубов
noo
Сорри, не нашел нужный раздел, но тема, думаю, выйдет полезная.
Итак, что надо:

имеем большое количество запросов к бд для генерации страницы.
Хотим эту страницу кэшировать.

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

Гугл помог следующими примерами:

1) http://www.codenet.ru/webmast/php/mcaching.php - тут я не пойму как вместо файла, который там подкачивается, сохранять все мои запросы, идеально было бы все в одном файле чтоб. Зато вроде все действительно просто и быстро в этом примере.

2) http://www.internet-technologies.ru/articl...rticle_286.html - тут целый класс. D принципе, спобо работает - кэш саоздает, но не может потом его получить по соответствию с url. выдает мне 2 ошибки. На эту строчку короче ругается:
$url=$GLOBALS['REQUEST_URI']; //Получаем url файла

Скорее всего из-за того, что я использую ЧПУ и url!=метонахождению_php_файла


Подскажите простейший способ кеширования. Желательно попобробнее, хочу разобраться.



Спустя 1 час, 1 минута, 47 секунд (7.07.2010 - 17:59) Basili4 написал(а):
Сначала разберемся что тоакое кеширование кеширование это использование ранее с генерированной страницы. Как это организовать? Очень просто делеаем таблицу из трех полей первое имя файла 2 дата генирации и 3 время жизни при обращении к базе с запросом генерации страницы сомтри эту таблицу выбирай запись по имени файла сверяй текущую запись и дату генерации +плюс время жизни если текущая больше то генерируй страницу и вписывай текущее время в поле дата генерации иначе выдавай скешированную страницу. ВСЕ если сам не сделаешь а бкдет нужен скрипт пиши в личку цена вопроса $20

Спустя 11 минут, 36 секунд (7.07.2010 - 18:10) Gabriel написал(а):
мне кажется или всеже кеш сайта должен жить на клиентской стороне?
а данные методы (второй особенно) больше напоминает сохранения HTML страницы и дальнейшего ее использования.
http://your-hosting.ru/terms/rk/cache/
http://www.google.com/support/adsense/bin/...ru&answer=32760

Спустя 12 минут, 23 секунды (7.07.2010 - 18:23) noo написал(а):
Basili4, по-моему как-то глупо использовать БД для хранения даты кеша.
Не проще ли хранить дату первой строчкой самого файла кэша?

Gabriel, вам кажется. Не путайте кэш браузера с кэшем страницы на сервере.


Все же хотелось бы узнать о способах кэширования, с примерами функций и т.д.
Какой самый простой способ?

Спустя 6 минут, 49 секунд (7.07.2010 - 18:30) Basili4 написал(а):
noo
храните. по мне так разницы нет только в этом случае страницу парсить надо чтоб дату пользователю не отправлять

Спустя 52 минуты, 52 секунды (7.07.2010 - 19:22) KaFe написал(а):
Basili4 blink.gif Первый раз слышу что для технологии кеширования используют БД, это нонсенс, вы явно не очень осведомлены.
Технология проста. Кэширования динамических страниц производится на стороне сервера. Кэшированые страницы хранятся в файловой системе сервера. Кэширование выполняет как минимум две функции.
  • Разгрузку машинных ресурсов сервера, путем отдачи клиентам статических страниц.
  • Аварийную работу сайта при падении БД.
Функций может быть больше, но я не стал вдумываться wink.gif

noo вам описать способ работы самого оптимального кэша страниц либо дать скрипт? dry.gif

Спустя 59 минут, 34 секунды (7.07.2010 - 20:22) noo написал(а):
Цитата (KaFe @ 7.07.2010 - 16:22)
noo вам описать способ работы самого оптимального кэша страниц либо дать скрипт?

Желательно и то и другое. В идеале скрипт с подробными комментариями smile.gif

Спустя 3 часа, 4 минуты, 17 секунд (7.07.2010 - 23:26) KaFe написал(а):
Цитата (noo @ 7.07.2010 - 17:22)
В идеале скрипт с подробными комментариями

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

Не буду описывать принципы киширования и бла бла бла, т.к за меня уже все написано, но посмотрите тут http://spectator.ru/technology/php/caching

Спустя 1 час, 9 минут, 40 секунд (8.07.2010 - 00:36) noo написал(а):
KaFe, вы не поверите, но я буквально 15 минут назад нашел в яндексе ваш сайт (эту статью) и попробовал реализовать (там все понятно написано).

Что получилось:
1) кэш от site/page/ выдается и при загрузке site/page/1 и при загрузке site/page/2
2) у меня блочный дизайн, т.е. хедер в одном месте, динамическая часть в другом.
Обрабатываю только динамическую часть, соответственно она и кэшируется и выводится тоже только она (без хедера).

Помогите, пожалуйста, решить эти 2 проблемы.

Спустя 11 часов, 21 минута, 38 секунд (8.07.2010 - 11:58) KaFe написал(а):
Цитата (noo @ 7.07.2010 - 21:36)
т site/page/ выдается и при загрузке site/page/1 и при загрузке site/page/2
dry.gif Это через rewrite, а реальные адреса какие.




Цитата (noo @ 7.07.2010 - 21:36)
2) у меня блочный дизайн, т.е. хедер в одном месте, динамическая часть в другом.
Обрабатываю только динамическую часть, соответственно она и кэшируется и выводится тоже только она (без хедера).
Кэшируйте (обрабатывайте) вместе с хедером.Будет намного проще.

Спустя 15 минут, 34 секунды (8.07.2010 - 12:13) noo написал(а):
Цитата
Кэшируйте (обрабатывайте) вместе с хедером.Будет намного проще.

у меня одна точка входа, один хедер, а кэшировать нужно только некоторые модули (блоки)

Цитата
Это через rewrite, а реальные адреса какие.

вроде такого site.ru?page=1&num=1

Подскажите, особенно по блочному, почему нельзя только блок потом выдавать из кэша. Как это поправить?

Спустя 10 часов, 6 минут, 37 секунд (8.07.2010 - 22:20) KaFe написал(а):
Вот тут посидел, подумал и решил что мне надо это скрипт написать, в принципе ничего нового, но есть комментарии и защита от глюков, ладно хватит лирики, вот он самый простой способ кэширования страниц

<?php
//Время при котором кэш должен быть обновлен, tchange время в секундах
$tchange=600;unset($makefile);
//Читаем url, какой сайт и какие параметры страницы, больше нам ничего не нужно
$url=$_SERVER['HTTP_HOST'].$_SERVER['QUERY_STRING'];
//Сначала преобразуем все символы в нижный регистр, а потом считаем md5
$name=md5(strtolower($url));
//Путь до файла кэша, папку cash лучше создать заранее
$page='cash/'.$name.'.html';
//Проверяем есть ли кэшированная страница для данного url
if (is_file($page))
{
//Смотрим последнюю дату модификации
$modtime=time()-filemtime($page);
//Сверяем прошло ли время кэшу обновиться
if ($modtime<$tchange)
{include($page);}
else
//Время пришло, задаем переменную
$makefile='ok';
}
else
//Файла кэша не существует, задаем переменную
$makefile='ok';

//проверяем задана ли переменная $makefile если да то кэшуруем страничку
if ($makefile)
{
//Начинаем буферизировать вывод
ob_start();
//Тута место вашим программерским изыскам
//=========================
//Сюда вставляем, инклюдим свой бездарнейший скрипт
//=========================
//Записываем вывод в переменную, очишаем вывод

$content=ob_get_contents();ob_end_clean ();
//Записываем весь вывод в файл кэша
$fp = fopen ($page, "w");
flock($fp, LOCK_EX);
fwrite ($fp, $content);
fclose ($fp);
//Благополучно выводим наш контент
echo $content;
}
?>

Сразу понятно, что я не учел работу с базой, просто не способен у меня сервер работать с SQL потому при падении SQL такой кэш будет функционировать 10 минут wink.gif

Спустя 16 часов, 25 минут, 47 секунд (9.07.2010 - 14:46) noo написал(а):
KaFe, спасbбо большое. Все понятно, кроме одного момента.
Зачем
else $makefile='ok';
? Объясните, пожалуйста, логику.

Спустя 1 час, 5 минут, 44 секунды (9.07.2010 - 15:51) KaFe написал(а):
Все я добавил комментарии для большей ясности wink.gif

Спустя 9 минут, 53 секунды (9.07.2010 - 16:01) noo написал(а):
понял, а я все думал, а к чему этот "ок" smile.gif оказалось просто чтобы дать значение переменной. Плюсанул!

Спустя 2 минуты, 18 секунд (9.07.2010 - 16:03) twin написал(а):
KaFe
Чтобы таких вопросов не задавали, пиши
else $makefile = true;
smile.gif

А вообще
//Время при котором кэш должен быть обновлен, tchange время в секундах
$tchange=600;unset($makefile);

зачем тут уничтожается несуществующая переменная?
//Читаем url, какой сайт и какие параметры страницы, больше нам ничего не нужно
$url=$_SERVER['HTTP_HOST'].$_SERVER['QUERY_STRING'];

а как быть со вложенными страницами?
//Записываем весь вывод в файл кэша
$fp = fopen ($page, "w");
flock($fp, LOCK_EX);
fwrite ($fp, $content);
fclose ($fp);

без блокировки такой код для кэша - самоубийство. Да и с блокировкой не очень то хорошо.

И компановка не шибко красивая.

Спустя 11 минут, 35 секунд (9.07.2010 - 16:15) KaFe написал(а):
Цитата (twin @ 9.07.2010 - 13:03)
а как быть со вложенными страницами?

Что вы имеете ввиду??

Цитата (twin @ 9.07.2010 - 13:03)
И компановка не шибко красивая.

Что именно вам не нравится??

Просто я хочу знать, может я где то допустил критическую ошибку?

P.S: обнулять переменные - привычка у меня такая, не могу избавиться.

Спустя 1 час, 4 минуты, 25 секунд (9.07.2010 - 17:19) noo написал(а):
twin:
Цитата
без блокировки такой код для кэша - самоубийство. Да и с блокировкой не очень то хорошо.

А как сделать лучше?

Спустя 19 минут, 30 секунд (9.07.2010 - 17:39) KaFe написал(а):
noo
замени
	$fp = fopen ($page, "w");
flock($fp, LOCK_EX);
fwrite ($fp, $content);
fclose ($fp);


на
file_put_contents($page,$content);

я думаю мне сразу надо было так написать

Спустя 18 минут (9.07.2010 - 17:57) twin написал(а):
Цитата
P.S: обнулять переменные - привычка у меня такая, не могу избавиться.
Странная привычка... А почему только одну? smile.gif

Со вложенными... Ну вот такими:
http://site.ru/dir/dir/dir/page.php


А про компановку... Лучше сделать это двумя файлами, тогда можно смело подключать системку в уже готовый сайт.
Вот такой первый:
<?php 

//Время при котором кэш должен быть обновлен, tchange время в секундах
$tchange = 600;
//Читаем url
$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
//Сначала преобразуем все символы в нижный регистр, а потом считаем md5
$name = md5(strtolower($url));
//Путь до файла кэша, папку cache создать заранее
define('CAHCE', $_SERVER['DOCUMENT_ROOT'] .'/cache/'. $name .'.html');
//Проверяем есть ли кэшированная страница для данного url
if (file_exists(CAHCE) && time() - filemtime(CAHCE) < $tchange)
exit(file_get_contents(CAHCE));
else
ob_start();

его нужно подключить первой строчкой. А вот этот:
<?php   

$buffer = ob_get_contents();
ob_end_clean();
file_put_contents(CAHCE, $buffer);
echo $buffer;
последней.

Можно дальше пойти, засунуть это функции и сделать кэш управляемым.

Спустя 37 минут, 38 секунд (9.07.2010 - 18:35) KaFe написал(а):
twin можно и так, в принципе это дела не меняет.

А вот про это, то
http://site.ru/dir/dir/dir/page.php

Это дело ситуации.

Спустя 30 секунд (9.07.2010 - 18:35) noo написал(а):
twin, все хорошо, но
почему тут:
 if (file_exists(CAHCE) && time() - filemtime(CAHCE) < $tchange)      
exit(file_get_contents(CAHCE));
else
ob_start();

а не
 if (file_exists(CAHCE) && time() - filemtime(CAHCE) < $tchange)      
echo file_get_contents(CAHCE);
else
ob_start();
?

Спустя 2 минуты, 15 секунд (9.07.2010 - 18:37) KaFe написал(а):
noo это потому что он использовал немного другой способ работы с кэшом, следственно при выводе кэшированной страницы, нам нужно останавливать дальнейшее выполнение скрипта, чтобы скрипт не выполнялся дальше.

Спустя 2 минуты, 43 секунды (9.07.2010 - 18:40) noo написал(а):
да я заметил, что это тот же принцип, только наоборот.
Просто в моем случае нужно продолжить работу скрипта, поэтому exit не вариант.

Спустя 3 минуты, 13 секунд (9.07.2010 - 18:43) KaFe написал(а):
noo ты не понял dry.gif Принцип тот же самый, но более универсален и может быть использован в любом скрипте сайта.

Спустя 53 секунды (9.07.2010 - 18:44) twin написал(а):
Как скрипт может продолжать работу, если результат берется из кэша?
Или ты кэшируешь участки? Тогда ни первая ни вторая схема тебе не годится.

Спустя 4 минуты, 55 секунд (9.07.2010 - 18:49) KaFe написал(а):
Цитата (twin @ 9.07.2010 - 15:44)

Или ты кэшируешь участки? Тогда ни первая ни вторая схема тебе не годится.

Абсолютно точно! biggrin.gif

Спустя 13 минут, 11 секунд (9.07.2010 - 19:02) noo написал(а):
Цитата (twin @ 9.07.2010 - 15:44)
Как скрипт может продолжать работу, если результат берется из кэша?

как может, легко, тут же if-else, есть кэш и время не истекло - берем кэш, истекло - создаем заново.
Цитата (twin @ 9.07.2010 - 15:44)

Или ты кэшируешь участки? Тогда ни первая ни вторая схема тебе не годится.

А какая годится?
я уже объяснял схему, сейчас повторюсь:

1) есть 1 точка входа
2) есть общий хедер
3) есть модули, некоторые из которых нужно кешировать
в модулях что-то вида:
if (is_numeric(isset($_GET['page']))) {
}

else {}

и мне приходится применять предложенный вами способ два раза - в if и else
Если делать exit, то не обрабатывается последующая часть (и хедер не сработает)

Спустя 4 минуты, 52 секунды (9.07.2010 - 19:07) KaFe написал(а):
noo мы вам предоставили способ кэширования страниц, ваше дело отталкиваться от этого, мы за вас писать скрипты не будем

Цитата
Думайте сами, решайте сами...


Я умываю руки laugh.gif

Спустя 2 минуты, 24 секунды (9.07.2010 - 19:10) twin написал(а):
Ну теоретически это возможно, но не очень то оптимально.
Чисто из любопытсва - какие модули у тебя кэшируются по времени? Я плохо себе такое представляю просто.

Тут написать универсальное решение несколькими строчками не выйдет. Но основу KaFe показал, дерзай. smile.gif

Спустя 6 минут, 35 секунд (9.07.2010 - 19:16) noo написал(а):
twin, это динамические модули, вроде топа пользователей, топа сайтов и т.д.

Я не прошу написать за меня скрипт, мне просто интересно чем плох ваш способ для кэша отдельных блоков?

Спустя 16 минут, 27 секунд (9.07.2010 - 19:33) twin написал(а):
Если участок один, то ничего страшного. Если много - куча обращений к ФС.

Спустя 21 минута, 6 секунд (9.07.2010 - 19:54) noo написал(а):
а, ну тогда нормально)

Спустя 2 месяца, 15 часов, 39 минут, 52 секунды (10.09.2010 - 11:34) mouserok написал(а):
добрый ...
есть выпадающий список который заполнен из базы
как правильно закэшировать выпадающий список (чтоб постоянно не коннектился к sql) ??

Спустя 48 минут, 44 секунды (10.09.2010 - 12:22) mouserok написал(а):
спрошу по другому: в кэш можно поместить только стр. целиком ??
и еще как вывести время последнего кэша страницы???

Спустя 2 минуты (10.09.2010 - 12:24) Nikitian написал(а):
Цитата
есть выпадающий список который заполнен из базы
как правильно закэшировать выпадающий список (чтоб постоянно не коннектился к sql) ??


$cachefile='cachefile.txt';
$cachedata='';
if(!file_exists($cachefile) && is_writable(dirname($cachefile))){
$result=mysql_query($yoursql,$link);
if(is_resource($result) && mysql_num_rows($result)>0){
while($res=mysql_fetch_assoc($result)){
$cachedata.='<option value="'.$res['value'].'">'.$res['label'].'</option>';
}
}

file_put_contents($cachefile,$cachedata);
}
elseif(file_exists($cachefile)){
$cachedata=file_get_contents($cachefile);
}
?>
<select name="yourname"><?=$cachedata;?></select>
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.