Прощай Smarty или простой шаблонизатор
13:30На прошлой недели запускал один проект и что-то мне не понравилась скорость генерации страниц. Начал искать в чем дело. Оказалось, в шаблонизаторе!
Думаю, очень многие разработчики используют в качестве шаблонизатора Smarty. По-моему, это самый известный шаблонный движок. Чем он знаменит?
- легок в освоении, понятен даже человеку не владеющему php;
- легко интегрируется в готовые проекты;
- очень функционален, обладает практически своим языком программирования.
И вот тут-то “собака и зарыта”. Программисты использующие Smarty, пушит шаблоны на его (довольно корявом) языке, чтобы шаблонизатор потом постоянно перегонял эти шаблоны в PHP-код (куча никому не нужной работы!!!). Если вдуматься, получается самая большая глупость во всей истории программирования на PHP!
Не проще ли сразу писать шаблоны на PHP?
Какая разница писать: {$title} или <?php echo $title?> (либо <?=$title?>)? Да первый вариант, короче. Но это скорее дело привычки, а вот скорость приложений на “нативных” шаблонах, выростает в 2-3 раза! По-моему, неплохой результат, и ради него можно написать пару-тройку лишних символов.
Два с лишним года я был ярым сторонником Smarty, но теперь я послал Smarty в пешее эротическое путешевствие. Все теперь только “нативные” шаблоны – многие вещи в них сделать гораздо легче, чем в каких либо других шаблонизаторах. Шаблонизатор уровня Smarty – это настоящие грабли!
В замен 300-килобайтному Smarty, я за 10 минут написал свой простенький шаблонизатор. Его задача – собирать переменные в одно место и рендерить шаблоны. И все! Больше от шаблонизатора ничего не нужно.
И так код:
<?php class VIEW_View { private $_path; private $_template; private $_var = array(); public function __construct($path = '') { $this->_path = $_SERVER['DOCUMENT_ROOT'] . $path; } public function set($name, $value) { $this->_var[$name] = $value; } public function __get($name) { if (isset($this->_var[$name])) return $this->_var[$name]; return ''; } public function display($template, $strip = true) { $this->_template = $this->_path . $template; if (!file_exists($this->_template)) die('Шаблона ' . $this->_template . ' не существует!'); ob_start(); include($this->_template); echo ($strip) ? $this->_strip(ob_get_clean()) : ob_get_clean(); } private function _strip($data) { $lit = array("\\t", "\\n", "\\n\\r", "\\r\\n", " "); $sp = array('', '', '', '', ''); return str_replace($lit, $sp, $data); } public function xss($data) { if (is_array($data)) { $escaped = array(); foreach ($data as $key => $value) { $escaped[$key] = $this->xss($value); } return $escaped; } return htmlspecialchars($data, ENT_QUOTES); } } ?>
Вот и все. Метод xss будет полезен при выводе данных для предотвращения XSS-уюзвимости.
Пример использования:
<?php require_once('class.view.php'); $view = new View('/tpl/'); $view->set('title', 'Наш заголовок'); $view->set('content', 'Какой-то текст.'); $view->display('index.tpl'); ?>
Файл шаблона /tpl/index.tpl
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251" /> <title><?php echo $this->title?></title> </head> <body> <h1><?php echo $this->title?></h1> <?php echo $this->content?> </body> </html>
По моему, все просто и удобно.
Замечение: “сложности” могут возникнуть с циклами foreach. Из-за бага в PHP . Данная ошибка уже исправлена в версиях PHP выше 5.0.5. Пользователям предудыщих версий просто придется писать:
forearch($t = $this->array as $k => $v)
вместо:
forearch($this->array as $k => $v)