Кэширование по url

pilot911

Новичок
Кэширование по url

Создаю кэширование (всю страницу в память) по URL с учетом сессии и авторизации пользователя. Уверен, что подобное уже было реализовано. Поэтому возник один вопрос: Где посмотреть хорошую реализацию ?
 

zerkms

TDD infected
Команда форума
т.е. ты уверен, что один пользователь будет одну и ту же страницу просматривать миллион раз, и она при этом меняться не будет?
 

pilot911

Новичок
Автор оригинала: zerkms
т.е. ты уверен, что один пользователь будет одну и ту же страницу просматривать миллион раз, и она при этом меняться не будет?
например - список исходящих писем - меняется очень редко у среднестатистического пользователя

это очень удобно - или 30-40 мсек на генерацию страницы из кэшированных блоков или 5 мсек на выдачу всей страницы
 

zerkms

TDD infected
Команда форума
хех :)
а по поводу реализации - в чём именно затык-то?
ты, судя по всему, однозначно можешь определить контент по паре "урл+user_id" вот это и есть твой PK для кэша. реализация кеширования контента - есть в ZFW, но я не понимаю что именно тут может быть неясно. PK есть - достали, показали. Нет - сохранили, показали. ы?
 

pilot911

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

ключ кэша приватной страницы вычисляется по URL+user_id...

да, ты прав, похоже, такой кэш не будет отдан другому юзеру :)
 

AmdY

Пью пиво
Команда форума
тебе нужно $_REQUEST ещё смотреть, а то при post пролетишь
 

Иван 76

Новичок
Автор оригинала: HraKK
Смотри ZF_Cache там есть все.
Согласен. Вещь действительно сильная.
Кстати с аналогичной проблемой недавно сталкивался, и вот что подумал.

Например, есть страница какой-то новости. Обычно делается так. Если пользователь неавторизован - на странице выводится форма авторизации. Если пользователь авторизован, и обладает правом редактирования - то показывать административные ссылки (редактировать, удалить и пр.), персональное меню и пр.

Если такую страницу кэшировать по url + uid - будет расти избыточность объема кеша.
В ряде систем предлагается делать т.н. "дырки в кэше". Подобные решения можно наблюдать в cakePHP, Smarty и пр.

Возник вопрос. Как сделать малой кровью такую фишку в ZF?

Уже давно я пробовал трюк в callback + replace. Был доволен, но подход не слишком удобен.

Мысли мои пошли в следующую сторону.
Вот сам шаблон идеи.
PHP:
/* ... some code ...*/

<?php print '<'.'?'.'php'; ?> if (!$this->loggedIn()): <?php print '?'.'>' ?>
    <?= $this->loginForm ?>
<?php print '<'.'?'.'php'; ?> 
    else: 
    $acl = "<?= $this->acl; ?>"; // Кешируем инфу о владельце новости и о доступе на редактирование
<?php print '?'.'>' ?>

/* ... print personal link ...*/

<?php print '<'.'?'.'php'; ?> endif; <?php print '?'.'>' ?>
/* ... some code ...*/
т.е. мы генерируем вид, который после рендеринга содержит код.
Перед запуском кеша страницы ловим все в буфер, и по окончании генерации страницы (или вызова ее из кеша) - исполняем содержимое буфера еще раз.
Таким образом, - реализуется т.н. "динамическое окно", или "дырка в кеше".
Страница в кеше - одна, а отображение различно, в зависимости от того, авторизован посетитель или нет, имеет он право редактировать страницу, или нет.

У этого способа есть один недостаток. Если мы недосмотрим, и предоставим пользователям возможность "внедрить php-code" - то получаем огромную дыру в безопасности.

Для подстраховки, можно сделать так:
PHP:
/* ... some code ...*/

<nocache key="shfkuigfbk78"> if (!$this->loggedIn()): </nocache key="shfkuigfbk78">
    <?= $this->loginForm ?>
<nocache key="shfkuigfbk78">
    else: 
    $acl = "<?= $this->acl; ?>"; // Кешируем инфу о владельце новости и о доступе на редактирование
</nocache key="shfkuigfbk78">

/* ... print personal link ...*/

<nocache key="shfkuigfbk78"> endif; </nocache key="shfkuigfbk78">
/* ... some code ...*/
Перед исполнением необходимо обезвредить таги php, например
PHP:
$str = str_replace(array('<'.'?', '?'.'>'), array('&lt;?', '?&gt;'), $str);
И сделать исполняемыми таги <nocache key="shfkuigfbk78">, т.е. заменить их на <?php и ?>

Получается двойная защита. Во-первых, маловероятно что xml-фильтр вводимых данных пропустит таг <nocache>.
Во вторых, даже если мы что-то недосмотрим, наш таг защищен секретным ключом, который злоумышленнику неизвестен.
Т.е., даже если он и сможет найти дыру, - то маловероятно, что он сможет разгадать секретную подпись.

Чтобы не вводить каждый раз вручную секретную строку, и сделать ее легкозаменяемой, - несложно написать хелпер nocache
И получится что-то типа такого:

PHP:
/* ... some code ...*/

<?= $this->nocache() ?> if (!$this->loggedIn()): <?= $this->nocache(true) ?>
    <?= $this->loginForm ?>
<?= $this->nocache() ?>
    else: 
    $acl = "<?= $this->acl; ?>"; // Кешируем инфу о владельце новости и о доступе на редактирование
<?= $this->nocache(true) ?>

/* ... print personal link ...*/

<?= $this->nocache() ?> endif; <?= $this->nocache(true) ?>
/* ... some code ...*/
В результате мы избавляемся от огромной избыточности кэша. Авторизованные юзеры просматривают страницы так же из кэша, хотя для них уже нет авторизационной формы, а вместо нее - персональное меню.

Решение до боли простое, достигнуто малой кровью, и Zend_Cache используется на полную мощность.
 
Сверху