Перевод: Шаблонизаторы в PHP — подведение итогов

:

Перевод итога обсуждений поста в блоге Фабиена (Fabien Potencier) на тему PHP шаблонизаторов и Twig.

-----------------------------------------------------------------------
Мой пост о шаблонизаторах в PHP (прим. перевод ) получил более 70 комментариев на данный момент. Можно отметить, что многие из них хорошо продуманы и аргументированы. Спасибо всем кто потратил свое время на принятии участия в конструктивной дискуссии. Я действительно горд тем, что PHP сообщество (по крайней мере, та его часть которая читает мой блог) способна дискутировать на эту рискованную тему, не приступая к флейму (flame war)! Я так же впечатлен количеством людей желающих продвинуть свои собственные шаблонизаторы ;)

Перед тем как начать отвечать на некоторые вопросы, я хотел бы напомнить о том что мне нравятся шаблоны на чистом PHP. И нужно помнить что в symfony используются шаблоны на чистом PHP с самого начала. Как факт, я выступал в защиту использования для шаблонов чистого PHP со своего первого проекта на PHP и никогда не использовал ни одного стороннего шаблонизатора. Итак, я не против PHP для шаблонов; я просто понял что ограничения PHP, как шаблонизатора, стали все больше и больше меня раздражать.

Как указал Eli, «Я [Fabien] представляю шаблоны на PHP в таком виде потому что хочу продвинуть шаблонизатор который я создал»

Мне также понравился комментарий от Tchalvak: «Вопрос о том что лучше PHP или шаблонизатор не самый главный, гораздо важнее (и на что проще ответить) это использовать шаблоны или нет. Шаблоны — и выделение представления — необходимы. А в каком виде оно представлено, не так уж важно. » Он отлично подвел итог вопросу обсуждения.

Я понимаю все моменты поднятые в комментариях, и, по-просту, согласен с большинством из них. Сейчас же я хочу ответить на несколько интересных комментариев.

Twig. Причина.


Я начал искать шаблонизатор несколько месяцев назад. Люди, знающие меня, знают что я не люблю изобретать колесо. Поэтому я не хотел создавать свою новую библиотеку с нуля.

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

Т.е. ты не продался… все еще?


Даже если вы не верите в мои аргументы, это нормально. Я не хочу делать из Twig универсальный шаблонизатор для PHP. Я действительно думаю что Twig не один на рынке шаблонизаторов, но я первый кто решил что он не будет использоваться во всех новых проектах на PHP!

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

И даже лучше — вы можете использовать Twig и компонент Symfony Templating для получения наилучших результатов. Используйте компонент для всех ваших шаблонов, и Twig если вам необходим режим «песочницы».

О синтаксисе


Множество комментариев на тему синтаксиса, и проблем синтаксиса PHP, которую я поднял. Речь не красоте синтаксиса, и, если вы считаете что мои аргументы являются обсуждением «цвета велосипедных навесов» (прим. русская версия), подумайте еще раз.

Ключевым моментом моих аргументов является то что шаблонзаторы должны стремиться к золотой середине (?? sweet spot). Шаблонизаторы должны найти компромисс в наличии возможностей — достаточно, но не слишком много. Как я и говорил в предыдущем посте, язык шаблонизатора относится к логике представления. И, конечно, простые условия и циклы это часть логики представления. Но желаете ли вы использовать функцию array_chunk() в шаблонах? Скорее нет. Это должно быть реализовано в контроллере или модели, зависит от того что вы хотите сделать.

Также в шаблонах много HTML кода с небольшим содержанием PHP. И этот кусок кода для меня полностью неприемлем:

<?php
    if ($items) {
        foreach ($items as $item) {
            echo "* {$item}\n";
        }
    } else {
        echo "No item has been found.\n";
    }
?>

Многим, кажется, нравятся короткие теги PHP. Первое — математика. Если вы сравните запись <?= $var ?> с записью <?php echo $var ?>, то увидите разницу в 7 символов, а не 2. Но это не главная проблема.

Кроме проблем с поддержкой XML и тем что параметр конфигурации short_open_tag различается у хостинг-провайдеров, это также вопрос стандартизации кода:

  • PEAR: «Всегда используйте <?php ?> для отделения PHP кода, не краткий вариант <? ?>. Это обязательно по соглашению PEAR и также является наиболее гибким путем использования PHP кода на разных операционных системах и различных конфигурациях»
    «Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is required for PEAR compliance and is also the most portable way to include PHP code on differing operating systems and setups.»
  • Zend: «Короткие теги не разрешены ни в коем случае.»
    «Short tags are never allowed.»

Pear и Zend достаточно серьезные проекты, поэтому у них были причины запретить короткие теги, не так ли?

Но как Eli упоминал в своем посте, я бы тоже был рад знать что в PHP занялись этой проблемой: "… есть ряд людей (включая меня [Eli]), которые думают о предложении новой возможности директивы short_tags в PHP, дающей возможность не только включать и выключать ее. Но и добавляющей 3й вариант — который разрешит <?= ?>, запрещая <? ?>"

О верстальщиках


(прим. оригинальное web-designers здесь и далее будет переведено как верстальщик)

Споры не о том должны ли верстальщики понимать PHP или нет. И, несомненно, не о том что верстальщики не достаточно умны. Конечно, они могу могут узнать немного PHP… до тех пор пока не узнают слишком много и не начнут писать код не относящийся к их шаблонам (например выбирать записи напрямую из БД). Ну конечно, они бы не допускали такой ошибки если бы знали о паттерне MVC. Но стоп, они уже не верстальщики — они программисты.

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

Экранирование


Некоторые комментарии выступают в защиту того что экранирование должно быть выполнено в контроллерах. Это не будет работать. Как писал John Campbell: «Проблема в том, что контроллеры не знают что будет выведено, и им также неизвестно как именно нужно экранировать»

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

Говоря о автоматическом экранировании, можно сказать, что я знаю об этом достаточно, потому что в symfony это возможность существует с 2006 года. Могу вам рассказать, что издержки скорости работы такой функциональности очень большие. В Twig это все компилируется, и поэтому издержки отсутствуют.

О «песочнице»


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

Развитие безопасности Dwoo и Smarty это правильный шаг в этом направлении, но не такой мощный как полный режим «песочницы». Насколько я понимаю, все это в основном о разрешении PHP кода в шаблонах или нет, а также об ограничении доступных PHP-функций (поправьте меня если я ошибаюсь).

Режим песочницы контролирует все — от допустимых тегов, до разрешенных методов объектов ( документация Twig объясняет концепцию и то, как она работает)

О скорости


Большинство шаблонизаторов компилируют шаблоны в PHP код. Поэтому скорость лексинга (lexing), парсинга (parsing) и компиляции не играет большой роли, какую играет скорость выполнения. Ниже скомпилированная версия шаблона Hello {{ name }}:
/* Hello {{ name }} */
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
{
  public function display($context)
  {
    $this->env->initRuntime();
 
    // line 1
    echo "Hello ";
    echo (isset($context['name']) ? $context['name'] : null);
  }
}
Многие беспокоятся о отладке. Как вы можете видеть, сгенерированный код очень чист, содержит название и строки оригинального шаблона. Этого должно быть более чем достаточно, чтобы с легкостью отладить все проблемы.

Вы можете посчитать это невероятно многословным (verbose) чем PHP версия, и, конечно, версия на PHP будет невероятно проще:

Hello <?php echo $name ?>

Но обратите внимание на сгенерированный код большинства шаблонизаторов и вы сами увидите что Twig генерирует наиболее чистую и короткую версию.

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

Я также протестировал шаблоны на чистом PHP. Ниже обновленная таблица:

Библиотека Время (сек) Память (Кб)
Чистый PHP 2.4 114
Twig 3 383
PHPTAL 3.8 598
Dwoo 6.9 1 645
Smarty 2 12.9 610*
Smarty 3 14.9 799*
Calypso 34.3 614
eZ Templates 53 2 783

Обратите внимание что количество памяти, использованное Smarty, гораздо меньше чем в моем предыдущем тесте, потому что я обернул весь цикл в ob_start()/ob_end_clean() что было нечестным по отношению к другим шаблонизаторам. Сейчас это было исправлено.

Как и ожидалось, PHP быстрее чем Twig для простых шаблонов. Но чем они будут сложнее, тем меньше будет разница, благодаря чистоте кода который генерирует Twig.

Тестовые скрипты запускались из коммандной строки без PHP аккселераторов, которые в этом случае все равно не помогли бы, потому что весь тест происходит в одном PHP процессе.

Тесты вы можете скачать здесь: fabien.potencier.org/benchmarks.tgz

Twig и Symfony


Этот раздел для тех, кого интересует внедрение Twig в Symfony.

Symfony 1.3/1.4


Очевидно, что Twig не будет частью symfony 1.3 т. к. в конце следующей недели подходит срок заморозки развития функциональности (feature-freeze deadline), а так же потому что symfony 1.3 это эволюция symfony 1.2, а не революция.
Если кто-то желает сделать Twig плагином к symfony 1.3, начните дискуссию в списке рассылок разработчиков symfony, и я помогу вам приступить к работе.

Symfony 2.0


На данный момент ничего конкретного по поводу Symfony 2 еще не решено, но Twig не будет шаблонизатором по умолчанию. Я думаю Twig будет доступен в качестве опционального плагина, хорошо интегрированного с ядром. Например, он может быть использован для генерации бэкенда (admin-generator) — для упрощения его настройки (кастомизации).

И, спасибо компоненту Symfony Templating, разработчики смогут использовать Twig и чистый PHP вместе, в зависимости от необходимостей.

Итак, если вы не хотите связываться с шаблонизаторами — используйте чистый PHP; но если вы захотите выиграйть используя Twig вы можете использовать и его (он будет встроен). И, конечно, если у вас есть другие плагины они не станут проблемой.

Итог


Надеюсь что этот пост ответил на некоторые вопросы поднятые в комментариях.