Люблю развиваться и изучать что-то новое. Недавно был покорен PDO, и сделан на его основе драйвер бд (не окончательная версия) и его синглтон реализация. После я решил простую реализацию шаблонизатора типа
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function view_include($fileName, $params = array()) { //создаются переменные с названием КЕЙ и значением ВАЛ foreach ($params as $key => $val) { $$key = $val; } ob_start(); include $_SERVER['DOCUMENT_ROOT'] . "/view/$fileName.php"; return ob_get_clean(); } |
перевести на Smarty и использовать так же его возможности кеширования. Это отняло у меня день жизни.
Чтение документации можно производить отсюда. http://www.smarty.net/docsv2/ru/index.tpl
Все на русском, установка понятна – копирование класса с либами в папку на своем сайте, указание папок для шаблонов, компилированных шаблонов, кеша и конфига. Так же я воспользовался предложенным в доке решением по наследованию Smarty и присвоения настроек в конструкторе, плюс добавил синглтон.
Далее был перевод шаблонов. Smarty имеет свой язык, похожий на php, с помощью которого можно даже немного программировать в шаблоне. Настоятельно рекомендую читать доку по ссылке, просто все подряд.
Вложенные шаблоны реализуются с помощью ф-ии fetch() – то же, что в случае ob_get_clean() – парсится вывод в переменную. Так же понравились следующие возможности:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$smarty = new Smarty(); $vars = array( 'article' => $article, 'message' => $message ); //вот так можно присвоить переменные из массива $smarty->assign($vars); //подключаем внутренний шаблон $content = $smarty->fetch('article.tpl'); $vars = array( 'title' => $title, 'content' => $content ); //Вообще из массива это быстрый $smarty->assign('name_val',$value); $smarty->assign($vars); //внутренний шаблон в главный и вывод $smarty->display('main.tpl'); |
Конечно это все разбить по контроллерам. Но смысл думаю понятен. Теперь самое интересное и геморное – кеширование. Для его включения нужно написать $smarty->caching = true. Так же стоит перед этим отметить, что компилированные версии шаблонов создаются в папке compile_dir например, и чтобы при изменении шаблона менялось и скомпилированное нужно $smarty->compile_check = true. В этом случае при изменении шаблона будет меняться его компиль версия и связанный с ней кеш. Кеш можно включать в каждом контроллере и управлять отдельно, ставить разный caсhe_lifetime, я это делаю все в конструкторе.
1 2 3 4 5 6 |
$this->compile_check = true; $this->caching = true; //$this->cache_modified_check = TRUE; $this->cache_lifetime = 3600; |
Вообще пишу я это все для того, чтобы поделиться мыслями по поводу граблей с этим самым кешированием.
Дело в том, что если у вас одна точка входа, которая меняется по параметрам – будет создана одна версия кеша. И при изменении кол-ва статей, например, т.е. удаления их из базы, любые изменения не связанные с изменением шаблона – не будут отображаться. Кеш должен быть разумно сконфигурирован по кеш-ид, и он должен быть уникальным для каждой версии страницы, т.е. зависеть от ее содержания. Другого механизма я не придумал.
Например если есть список статаей на странице, который берется из базы, то логично взять его за основу Ид кеша. В этом случае при удалении-изменении стаей изменится и ИД. ИД надо передавать в ф-ии fetch() и display(), когда формируется кеш.
Для генерации cache_id придумал ф-ю.
1 2 3 4 5 6 7 8 9 10 11 |
//получение ид по уникальным данным function get_cache_id ($data) { return md5(md5(serialize($data))); } $this->articles = $art->all(); //далее в контроллере $smarty->cache_id = $smarty->get_cache_id($this->articles); $smarty->display('index.tpl', $smarty->cache_id); |
Если у вас страница зависит от ИД статьи – включайте это в ИД кеша. Или ИД может быть одно и то же, а выдается разное сообщение в зависимости от действий – включайте сообщение в ИД кеша. Все возможные отклонения на странице должны быть учтены и придать уникальности ИД кеша.
Иначе вас ждут жесткие баги, такие как:
– вы удалили статью, она осталась в списке, при переходе по ссылке выдается сообщение, что статья не найдена
– вы открыли статью для просмотра или редактирования, там ее тайтл и текст, открыли другую статью, а там остался тайтл и текст с прошлой
– вы зашли в редактирование статьи, обновили ее, выдалось сообщение “обновлено”. Вы вышли, зашли в редактирование другой – сообщение “обновлено” осталось висеть.
Вывод: cache_id должен быть уникальным!
зы. если сюда кто-то забредет, кто знает более универсальный способ кеширования – буду рад обсудить.