Как стать автором
Обновить

Комментарии 170

Читая любые статьи про сравнение шаблонизаторов, возникает вопрос, чем вам не нравится стандартный php код:
<?=$client->name?>
Он будет всегда работать быстрее любого шаблонизатора.
Кеширование в любом случае правильнее делать средствами nginx.
Аргумент про красоту кода — не принимается,
В общем не понимаю. Заранее спасибо за ответ.
Одного механизма наследования шаблонов может быть достаточно, чтобы сделать свой выбор в пользу шаблонизаторов.
1. Можно сделать include
2. Можно написать свою маленькую обертку для include
Include не прокатит. Include это сверху вниз. Подключением в этот шаблон какой-то еще. А наследование это подключение вышестоящего шаблона. Обратный порядок.
Наследование реализуется абсолютно тривиально, были статьи на эту тему.
Не говоря уже о том что от него можно легко отказаться, за счет разрастания структуры файлов (выигрыш в производительности будет очень ощутим)
Да все реализуется не слишком сложно. Только зачем, если все это уже реализовано в шаблонизаторах? В итоге получится все равно еще один шаблонизатор. Только свой.
Скорость.
Если вам нужна реальная скорость, забудьте про PHP ;) Он мееееедленный. :)
Да, да вот C++ — он быстрее…
C++ это еще не предел, лучше шаблоны на ассемблере писать )
Проще так: 0001011100000111001101110111010101010
Здесь нужно знать только 0 и 1, а в смарти какой сложный синтаксис видели? да ну его.
сразу программировать фотоны в квантовых компьютерах, или ИИ, или что там можно сейчас :)?
скорость зависит не от языка а от архитектуры.
хотим скорость — танцуем с бубном HipHop
Почему? HipHop = C. Если вы код на одном языке оттранслируете в код на другом, язык изменится :)
читай первую часть комментария
вчера был на собеседовании в одну контору,
они разрабатывают игры, платформа Java
с спросил:
— зачем Вам ПХПешник, раз вы на java специализируетесь?
— ПХПешника найти проще и они дешевле…
купить $php-ков
сказать заказчику, что делаем проект на €java.
Профит:
*скорость разработки увеличилась
*можно демпинговать ценой за «java»-час и «java»-проект
Есть не только скорость выполнения, а и скорость разработки и поддержки. И в 99 процентах случаев второе — важнее. Поэтому шаблонизаторы и используются.
если это к ответу на вопрос по Си то тут двоякое мнение:

Скорость разработки WEB проекта на С++ соизмерима со скоростью разработки на РНР,
так же есть scgi/fastcgi библиотеки и шаблонизаторы, libhttp и прочие…

Есть проект HipHop — который компилирует РНР код в С++, получается быстрый полноценный fastcgi сервер.
А по-моему несоизмерима. На С++ выйдет сложнее и дольше, PHP всё-таки специально для веба создавался и вся его динамичность сильно облегчает работу.
просто ты не писал на С++ под WEB
было дольше 10 лет назад,
сейчас уже создана куча специализированных библиотек
лично у меня скорость разработки на плюсах на 10-15% ниже чем на РНР
но и опыта на 70% меньше, чем на РНР
но выйдет дороже минимум на 30%, так как грамотных специалистов на С++
не так много, особенно специализирующихся в WEB
использую Twig из-за паттерна two step view, который не решается с помощью include Вначале написал свою реализацию, но в итоге из-за дополнительных плюшек перешел на готовое решение.
Можете попробовать Two Step View в Zend Framework (Zend_Layout, Zend_View) и это все без компиляций, на нативном пхп. Можно использовать без самого фреймворка.
include и наследование довольно разные механизмы.
* Красота кода тоже полезна, т.к. с шаблонизаторами чаще всего работает не программист, а верстальщик.
Мне не встречались верстальщики, владеющие тегами Smarty или в данном случае Twig, и при этом не знающие простейших конструкций php типа foreach и if.
Вам не повезло.
По вашему, foreach в php и в smarty сильно отличаются? Лично я начал использование smarty нативно используя аналогичные конструкции из php в коде smarty.
Что в смарти что в твиге они отличаются от plain PHP. Где в смарти скобки? Нету. И закрывается блок в PHP не с помощью /foreach.
Я с Вами согласен — синтаксис отличается. Но логика работы операторов аналогичная. Потому было довольно просто начать использовать Smarty.
Ну, так мой «упрек» выше был не об этом. Да и тред больше про шаблонизаторы для верстальщиков, а не для программистов.
НЛО прилетело и опубликовало эту надпись здесь
Может вы хотели написать так?
<?php echo htmlcpecialchars($client->name); ?>


Вот поэтому и предпочитаю шаблонизатор.
это очень спорный кусок кода, вы всегда занимаетесь эскапом в шаблонах? и можете объяснить почему экранирование вообще должно быть в шаблоне?
По моему опыту, в шаблоне бОльшую часть переменных приходится экранировать, и лишь иногда — не нужно. Поэтому логично по-умолчанию экранировать все, и лишь иногда вручную экранировку отключать. Мне кажется из этого и исходили авторы Twig
Практически всегда. Нельзя доверять данным, полученным извне (файлы, БД, внешние сервисы), а в идеале шаблон вообще не должен знать, откуда данные получены.
я лично данные перед записью в БД фильтрую если вы наоборот, то причем тут шаблон?
+ короткие теги никто не собирается исключать, поэтому код вполне может быть =e($client->name)
p.s. конфликтов с короткими тегами не разу не было за 5 лет работы у меня… и вообще есть автоматическое экранирование например как в слое sf1 сделано где можно и raw data получить и безопасные данные по умолчанию
Экранирование осуществляется не против атак, а против, например, неэкранированных кавычек в
Хабр съел код — имел в виду кавычек в input value=«значение с кавычкой»
в базу пишутся html entities понимаете?… зачем мне это делать в шаблоне? вы идете путем переноса логики контроллера в сторону толстого view, и пытаетесь это сделать единственно верным подходом, это не так. mvc это не только zf sf и другие php фреймы,… далеко ходить не надо, по принципу symfony отправку мыла формы должна быть в классе формы, а например в django часто может быть в модели, поэтому когда пхпешник видит разрыв шаблон ему мозг выносит. как так mvc такое какое я не знаю, значит это не mvc. вот в чем бред.
А на мой взгляд хранить экранированную кавычку вместо естественной в базе — странный выход. Ведь из тех же данных может потребоваться построить PDF, вывести в консоль — и что тогда, разэкранировать обратно? На мой взгляд логично хранить данные «как есть» и адаптировать под каждый вывод, если это необходимо.
т.е. вам логичнее хранить не безопасные данные в базе? как по мне это странный подход.
смотрите я раз экранирую и перевожу в сущности(зная что это будет использоваться именно так), и все. вы же каждый раз это делаете. а если мне придется когда то где то назад сделать это тегами или кавычками то это не проблема.
ну просто это глупость когда шаблонизатор работает в 10 раз медленее чем генерация страницы в целом т.е. если страница генерится за 0.03 + шаблонизатор это 0.15 на простых данных, если загрузить его данными(объектами, массивами) то можно и в целых полсекунды генерацию из шаблонизатора загрузить. Ну и зачем мне такое нужно?
Данные безопасны! Небезопасно их в исходном виде помещать в HTML, а вот в PDF — вполне себе безопасно. Сравнил кстати на приведенном в топике выводе (кстати безумно гипертрофированном) производительность с экранированием и без — разница всего в 3 раза. Для типичного сайта, где шаблонизация — одна из самых коротких задач это несущественно.
ну ну… мой пример у меня быстрее 10 запросов(c джойнами) в БД выполняются чем генерация шаблона twig-ом, ну и зачем мне это узкое место, самое узкое во всем проекте!!! в чем выгода? в том что он за чем isset сделает? или escape? я отлично без них обойдусь
короче шаблонизаторы такого уровня как в статье это выгода для сайтов аля 1000 уников в день, на проектах по серьезнее, это узкое место.
Несете несусветную чепуху. На крупных проектах узким местом может быть невозможность его поддерживать или развивать, потому что шаблоны испичканы инструкциями. Проблемы же производительности шаблонизатора решаются дополнительными мощностями сервера и кэшированием.

Код пишется для людей, а не для машин. Если вы пытаетесь на php написать приложение, которое будет работать реактивно быстро само по себе, то вы делаете это неверное — вам нужно писать сайты на Assembler или C. А теперь фокус: даже написав свой сайт полностью на Assembler, вы потратите в разы больше денег и ресурсов чем я, пишущий чистый код на php + twig и поставивший дополнительную коробку в серверную. И через полгода я посмотрю на скорость развития вашего проекта по сравнению с чисто написанным моим ;-) Я это к чему — хватит уже экономить на спичках.

А к вопросу «шаблоны на чистом php такие же читабельные» вам сюда:
habrahabr.ru/blogs/webdev/127906/#comment_4224465
Это вы несете чушь, причем тут Assembler. Я использовал twig и использовал symfony с первой веткой 3 года проработал, если что. я знаю кто вы и знаю что вы будете до последнего защищать то что творит fabien. Но можете не утруждаться я считаю все продукты за исключением некоторых компонентов от symfony2 ущербными, для php. Они почти все медленны и крайне абстрагированы, вам не на php нужно писать а scala, там очень высокая абстракция, но для php это суицид. Если что я на django перешел и на plain php. И знаете что я начал писать быстрее после того как отказался от symfony. Кто фабъену сказал в twitter что «I think premature abstraction is often more dangerous than premature optimization» вот я думаю это в точку может он задумается.
Так что про C или Asm речь вообще не идет, вы играете в игру make java from php, вместо фокус держать на реальных задачах.
вы играете в игру make java from php, вместо фокус держать на реальных задачах.

Расскажите про «фокус на реальных задачах» нашему портфолио: knplabs.com/en/portfolio.
я пишу проекты для себя, symfony хорош чтоб поиграться на этом точка. если возьму фрейм то это будет django. в портфолио на sf2 пару проектов, ну че молодцы за полгода))
в портфолио на sf2 пару проектов, ну че молодцы за полгода))

Поверьте, это далеко не все.

В любом случае, покажите свои проекты. А там — поговорим о состоятельности наших методологий, «ущербности компонентов Symfony2 для php», их медленности, а так же о «реальных задачах» и фокусе на них.
Вы можете думать что хотите я ничего не навязываю. Я просто сказал что symfony и почти все его компоненты, понты для приезжих(молодых разработчиков). Я предпочитаю реальные задачи решать, если это a + b то так и будет, а не как это делает SF // this->getVariableAPlusVariableBAndMaybeVariableC… о еще неймспейс на полкилометра
ладно, может когда то поймете что важно быстрее запустить проект и получать прибыль а не неймспесами мерятся
Я просто сказал что symfony и почти все его компоненты, понты для приезжих(молодых разработчиков).

Мдаааа.

Я предпочитаю реальные задачи решать, если это a + b то так и будет, а не как это делает SF // this->getVariableAPlusVariableBAndMaybeVariableC… о еще неймспейс на полкилометра

Я вам показал, что и как делаем мы. Где же ваши «реальные задачи»?
Мне нравится новый аргумент в споре: сперва добейся (с)
Причем здесь что? Оппонент высказался, что я решаю нереальные задачи. Я ему показал портфолио с вполне реальными и уже решенными задачами. Вот и все. Никаких «сперва добейся» или «у меня толще».
Ну просто портфолио это ну не критерий. У меня вон нет портфолио, потому что я работаю над одним проектом уже полтора года. И нельзя сказать, что мои или твои задачи хуже. Просто они разные. Одно дело решать задачи веб-студии, другое — решать задачи стартапа и вообще другое дело строить свой стартап.

И с этой точки зрения а) мерятся портфолио это сущее ребячество, весовые категории другие и б) нет универсальных решений. А значит и нет универсальных рецептов.
Мы делаем проекты совершенно разных уровней. И основная их масса — стартапы. Единственная разница в том, что они не для себя. И я с тобой согласен почти во всем. Но повторюсь: «поле боя» выбрал НЕ Я:
вы играете в игру make java from php, вместо фокус держать на реальных задачах.

symfony хорош чтоб поиграться на этом точка.

в портфолио на sf2 пару проектов, ну че молодцы за полгода))

symfony и почти все его компоненты, понты для приезжих(молодых разработчиков)

может когда то поймете что важно быстрее запустить проект и получать прибыль а не неймспесами мерятся

Ты же сам противоречишь тому, кого защищаешь своим пояснением:
А значит и нет универсальных рецептов.

С которым, кстати, я полностью согласен ;-)
Ну я тоже не со всем сказанным согласен.
Но вцелом могу понять вышеописанную критику.

Проекты которые реально получают профит от неймспейсов имеют уже уровень ентерпрайза. На стартапе малой или средней величине хватало аутолоадера старого симфони: оч редко бывали случаи, что классы назывались одинаково.

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

Симфони2 отличен для расширяемых приложений, для приложений над которыми работает большая команда. Всё можно кастомизировать и больше защиты от говнокодинга. Впринципе в нынешнем проекте мы от симфони1 получаем сейчас много головной боли, ибо изначальные правила уже не работают.

и т.д.

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

Делая ентерпрайз уровня проект, у нас нет возможности переписать его с нуля на Симфони2. Максимум — заюзать компоненты если надо. Сейчас впиливаем Доктрину2…

Т.е. получается нынешняя ниша для Симфони — это проекты в вебстудиях. Там чаще можно делать новые проекты, нужно использовать старые наработки и пр.

Вот как я это вижу.
Да, чуть не забыл. Ещё одна отличная ниша для симфони2 — разработка продуктов ( а не сайтов или сервисов). Но тут как раз будут лучше компоненты Symfony2. Жаль, только, что сейчас к ним нет пока документации и примеров.
Симфони2 отличен для расширяемых приложений, для приложений над которыми работает большая команда. Всё можно кастомизировать и больше защиты от говнокодинга.

Серьезно. Ты когда-нибудь участвовал в проекте, который никто не планировал потом расширять??? Типа: «Реализуем вот эти 2 фичи и все и никакого развития»?

Впринципе в нынешнем проекте мы от симфони1 получаем сейчас много головной боли, ибо изначальные правила уже не работают.

Я от symfony1 получал уйму головной боли уже на проектах среднего уровня. Как только тебе нужно мало-мальское наследование моделей — ты в аду. Да, на мелких проектах ты этого не замечаешь. Но опять, не вижу смысла на мелких проектах использовать как symfony1, так и Symfony2 и Rails. Для этого есть более адекватные средства.

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

Ну так никто и не говорит, что Symfony2 должен и подходит всем и каждому. Если проект мелкий — типа сайт-открытка или социлка с двумя страницами — какой смысл тянуть Symfony2. Так же как и нет смысла тянуть Rails. Я буду использовать Silex в php или Sinatra в руби или более подходящий язык и технологию…

И кстати, пример с пагинацией уже в корне не корректен. Уже достаточно давно проблема решается одним бандлом и одной строчкой в шаблоне и контроллере. Второй симфонии еще четырех месяцев нет. Глупо говорить о том, что у нее чего-то мало (компонентов) по сравнению с матерым Rails, не добавляя уточнения «пока» ;-)

Т.е. получается нынешняя ниша для Симфони — это проекты в вебстудиях. Там чаще можно делать новые проекты, нужно использовать старые наработки и пр.

Ну какбы совсем нет: jirafe.com/, www.exercise.com/, opensky.com/. Три стартапа на Symfony2, которые уже пол-года успешнейше живут и развиваются без «новых проектов».
Серьезно. Ты когда-нибудь участвовал в проекте, который никто не планировал потом расширять??? Типа: «Реализуем вот эти 2 фичи и все и никакого развития»?

А зачем утрировать? Тут скорее вопрос преждевременной абстракции. Если проект вырос до нужного уровня и его нужно расширять, то для этого уже есть намного больше возможностей: времени, денег, людей. И там все средства хороши: твиттер, фейсбук, и т.п. На начальном уровне задачи другие: показать прототип, навесить дизайн, быстро реализовать нужные фичи, получить инвестора или первого клиента. Компании вида: сделай сайт, а завтра мы пригоним туда 100К трафика есть, и я в такой работал. Но это всё равно уже энтерпрайз.

Глупо говорить о том, что у нее чего-то мало (компонентов) по сравнению с матерым Rails, не добавляя уточнения «пока» ;-)

Ну пока был симфони1 он был приблизительно равен по возможностям рельсам. Вдруг было принято решение полностью перейти на всё новое и отбросить все те наработки, что делало сообщество долгие годы. Почему в рельсах столько гемов? Потому что даже при миграции с 2ку на 3ку (а теперь на 3.1) все они быстро обновились, да ещё и новые делаются. А так разрабы Симфони сами поставили себя в неравные условия.

Я от symfony1 получал уйму головной боли уже на проектах среднего уровня. Как только тебе нужно мало-мальское наследование моделей — ты в аду.

Наследование моделей это не совсем симфони, зависит то выбраной ORM. Впринципе наследование в Доктрине1 было неплохим, в Пропеле ввели и не так и давно. Проблемы это упомянутые формы, это жесткая структура (как делать приложение, которое берет данные не с веба, а например, с почты), плагины, и куча ещё всего. Но ад начинается не сразу, а где-то через полгодика )

Ну какбы совсем нет: jirafe.com/, www.exercise.com/, opensky.com/. Три стартапа на Symfony2, которые уже пол-года успешнейше живут и развиваются без «новых проектов».

Три стартапа от евангелистов Симфони…
Логично, что они делаются на Симфонях. Было б цинично контрибьютить в фреймворк, а потом его не юзать =)
Три стартапа от евангелистов Симфони…
Логично, что они делаются на Симфонях. Было б цинично контрибьютить в фреймворк, а потом его не юзать =)

У тебя очень странный взгляд на мир. Не стартапы написаны на Symfony2 из-за того, что их разработчики евангелисты, а Symfony2 такая какая она есть, потому что ее разрабатывали под конкретные нужды. Тогда когда эти проекты начинали писаться — евангелизировать еще было нечего.
Вряд ли это так, уж слишком универсальным является Симфони2, чтобы решать конкретные проблемы конкретных стартапов. Не думаю, что решение делать проект на новом фреймворке (за год до того как он только станет стабильным) диктовалось исключительно бизнес-интересами.

Не стоит убеждать людей, что Симфони2 это круто, а вы все просто не шарите. Пропаганда такого Symfony-way найдет только противников новой симфони. Да, появилось много фанатов из Zend сообщества, но убыло сторонников из sf1, yii, kohana… Стартапы — это та ниша, которую Симфони2 ещё только должен завоевать. И без пересмотра многих концепций этого не получится.

Сколько не объясняй, что Symfony это круто и правильно, но нужно показывать прямые выгоды, которые я смогу показать тимлиду, ПМу, прочему начальству и сказать: новый проект мы делаем на Симфони2. Сейчас, я даже не вижу никаких фич для миграции с сф1 на сф2.
(замена доктрины1 на доктрину2 не в счет)
как же смешно выглядит этот комментарий спустя 4 года.
ещё чуточку уточню: для человека возможно и кажутся задачи нереальными, ибо у него задачи другие. Он пишет что пишет проект под себя, а значит и задачи и методы достижения у него совершенно другие.
Что такое «не безопасные данные»? Есть база и есть данные, просто надо с ними уметь правильно работать.
Для редактируемости данных.
Вам придётся их парсить повторно в обратном направлении, если вы захотите их отредактировать. Притом совсем без гарантий, что обратно получите ровно то, что было изначально.
Для таких случаев в некоторых местах просто храню исходные данные в сжатом виде отдельно.
Это дает отличную производительность. Парсить каждый раз при выводе тысячи сообщений это уж точно не вариант.
Думал об этом варианте. Но не знаю… Каждый раз писать данные дважды? По мне так обращение к БД лишнее — все таки тратит больше времени и ресурсов, чем парсинг из php
Двойная только запись, причем в разные таблицы. Чтение при этом остается быстрым.
Тут все зависит от скорости парсинга. У меня обрабатывается bb-подобный синтаксис. Даже в самом простом варианте все равно быстрее выбирать уже готовые данные чем их парсить каждый раз.
Немного оффтопа: какой парсер для bb-кода используете? Поскольку как раз сейчас обдумываю именно этот вопрос и именно в связи с bb-кодом.
в PECL есть расширение PHP, называется bbcode.
Я использую самописный парсер созданный на основе NBBC и Jevix.
Раньше использовал просто NBBC.
Что думаете насчет xBB?
Хорошая библиотека, свою задачу она выполняет.
Но NBBC мне нравится больше.
Просто я ярый противник использования регулярок не по назначению. Не для парсинга тегов они…
Это одна из причин, почему переписал NBBC. Принцип работы сохранился, но сам код полностью переписан. Лексер работает похоже на Jevix.
В общем это дало ощутимое увеличение в скорости и позволило сильно усложнить логику обработки.
А вы своих наработок в паблик не выложите?
Ну раз такой случай, то выложу на гитхаб на днях. Только почищу от привязок к фреймворку. Пришлю ссылку в личку, как выложу.
И, кстати, ещё интересно, как отображать информацию, если часть её не должна быть доступна кому нибудь? Ну, скажем, bb-код hide.
Я бы парсил как обычно с сохранением обработанной версии и оригинала, но для тех, кто не должен видеть вырезал бы перед отображением.
В действительности просто не использую нигде такой тег ))
Я использую yii фрейморк и его хелперы для генерации форм Html::input() в таких случаях. Многие данные фильтрую при записи в базу. А на те что не целесообразно фильтровать пишу геттеры которые возвращают обработанный текст. От смарти отказался потому что там нельзя прозрачно использовать весь функционал что предоставляет фрейморк. Проблема с наследованием шаблонов из за которой якобы стоит использовать шаблонизатор там тоже решена. Причем очень прозрачно и красиво. Потому использование шаблонизатора я вижу оправданным если используется самописный фреймворк заточенный под него или верстальщик на дух не переносит php (хотя наш наоборот вздохнул с облегчением когда мы отказались от smarty)
Данные — это данные, а представление — это представление. Эти понятия надо отделять. У одних и тех же данных может быть несколько представлений (html/json/pdf) и каждое из них может иметь свои, форматно-особенные уязвимости. Экранирование конкретных данных для защиты их от уязвимостей отдельного типа представления — это логика представления. Не больше не меньше. Или вы экранируете сразу от всего? А потом разэкранируете где надо??? А что если через пол-года вам надо будет ввести новое представление для существующих данных со своими ограничениями? Будете базу мигрировать?
Не для всех а там где нужно(!!!) Вы любите городить кучу абстракций над простыми вещами, я считаю это расточительством. Вот и все.
>> А что если через пол-года…
А что если это в рту начнут расти грибы?
Ну а че… Давайте сразу начнем писать очень очень абстрагировано а то вдруг движок придется использовать для управления шаттлом а он не готов, не порядок…
Вот как выглядит ваше «а что если»…
Мы программисты с годами опыта разработки высоконагруженных проектов, тренингов и консультаций. Использование любой технологии или ее создание обусловлено проектными необходимостями или существующими реальными задачами. Наша любовь к чему бы то ни было тут абсолютно не при чем.
Если известно что выходные данные, например, не должны содержать никакого HTML кода, не логичнее ли фильтровать его еще на стадии добавления данных в БД? Стоит ли хранить мусор? Тогда встает логичный вопрос, только ли представления это логика?
Вы говорите про фильтрацию входных данных. Я про их экранирование на выводе. Это разные задачи и это надо понимать.

Например, если доменная логика подразумевает, что у объекта текст не должен содержать картинок, то, конечно, будет лучше если мы эти данные нормируем (вырежем тэги со strip_tags()) перед тем, как сохранить куда-либо.

А вот, допустим замена запрещенных символов (допустим у вас в тексте есть "&" или ">") — это экранирование. Потому как в этом случае, изначальные данные должны измениться, чтобы соответствовать конкретному представлению. Однако, сами данные должны быть доступны в исходном виде, в соответствии с доменной логикой (без тэгов, но с "&" и ">" в нашем случае).
%s/картинок/тэгов/g
Да, согласен с вами. Наверное вопрос возник после прочтения этой цепочки комментариев в целом. Выше хабраюзер casey утверждал, что данные лучше всего хранить как есть. И возникла мысль, что входные данные должны обрабатываться в модели и храниться в том виде в котором мы ожидаем их получить на входе (то есть отфильтрованными), но при этом все что касается экранирования данных при выводе, как вы и сказали ранее это логика представления.
Что вы спорите, делайте как душе угодно.
Всё равно в каждом проекте и в каждой фирме всё решается по своему, и на многие вопросы нет никаких однозначных ответов. Даже ответ «80 процентов разработчиков так делают» не всегда означает «так правильно».
Не равняйтесь ни на кого, решайте сами.
Вы, наверное ошиблись адресом. Вам сюда: fucking-great-advice.ru/
1. Абстракция это круто
2. Абстракция тормозит

То, что представление надо отделять это всем понятно. И то, что теоретически экранирование это задача шаблона. Но когда страница, которая отображается 100 раз в секунду содержит экранирование, а где то в одном месте есть вывод данных куда-нибудь где экранирование не нужно — это фанатизм. Блин, на больших страницах в Symfony 1.4 у меня в профайлере операции экранирования были выше в топе, чем запросы к БД. Это далеко не экономия на спичках.
Я не говорил, что это не важно. Я говорил, что есть другие способы подобные проблемы решать, которые не включают ухудшение читабельности кода и тормозят дальнейшее развитие проекте в следствие.

Серьезно, вы не кешируете страницу, запрашиваемую 100 раз в секунду???

И да, в Symfony 1.x автоматизированное экранирование в купе с embedded forms — одни из самых ужасных вещей, которые были решены чуть ли не в первую очередь при написании Symfony2. Невозможность сделать на php качественный автоматический эскейпер — это причина, по которой в Symfony2 его нет и почему приоритетным шаблонизатором там является twig, лишенный этих проблем.
Серьезно, вы не кешируете страницу, запрашиваемую 100 раз в секунду???

Контент на странице уникален для каждого пользователя и обязан быть актуален. Данные кешируются по отдельности и идёт постоянное слежение за их актуальностью, чтобы кеш скинуть. Но шаблон в данной ситуации вынужден работать каждый раз. И он работает быстро, т.к. данные уже экранированные лежат в кеше. А вот если бы при каждом выводе они экранировались в самом шаблоне это дало бы лишнюю нагрузку.
И он работает быстро, т.к. данные уже экранированные лежат в кеше. А вот если бы при каждом выводе они экранировались в самом шаблоне это дало бы лишнюю нагрузку.

Просты вы кешируете только данные. А предлагаю кешировать отдельные компоненты.
Но нужно учитывать для чего эти данные записываются в базу. Если я пишу логин пользователя то будет проверка на латинские буквы и цифры. И не будет надобности фильтровать это при выводе. Если это комментарий который не поддерживает html я использую или htmlspecialchars при выводе или strip_tags в зависимости от нужд. И я не вижу нечего плохого что когда пользователь будет редактировать комент он увидит немного другой текст. Система увидела его текст и исправила. Так же если бы он писал в поле для цены к примеру '111q' тут можно или выдать сообщение об ошибке или записать в базу 111. И оба варианта правильные. Просто выбор конкретного зависит от ситуации. Если же в базу нужно писать html то я в любом случае почищу код от XSS. Да и кавычки я никогда не заменяю. Это и правда излишество.
Вы подстраиваете код своего приложения под html-шаблоны, усложняя котроллеры и забывая о том, что эти же данные могут быть выведены в других форматах. Да, вас это устраивает в данный момент времени, но когда нужно будет добавить пару фичей…
А XSS?
А вот для этого, на мой взгляд, как раз служит обработка входящих данных на стороне сервера.
Я глубоко убеждён, что экранированием должен заниматься контроллер перед выводом данных в шаблон, т.к. эти экранированные данные можно (и нужно) очень просто закешировать и пока данные не поменялись (а этой логикой рулят контроллеры) шаблон будет получать на вывод уже готовые данные, которые не нужно экранировать. Учитывая, что в большинстве случаев на посещаемых проектах (мы же думаем о высоких нагрузках, когда на скорость тестируем?) все данные кешируются, это сэкономит довольно большой кусок процессорного времени. Если посмотреть профайлером на генерацию приличной по размеру страницы — львиную долю там отжирает экранирование (на примере Symfony).
Хотя бы автоматическое экранирование. Это тоже самое, что автоматические плейсхолдеры при sql-запросах и экранирование руками. Риск забыть/забить в большом проекте из нескольких программистов во втором случае отличен от нуля.
<? if (isset($item['key']):?> <?= $item['key'] ?> <? else: ?> default <?endif ?>

против
{$item.key | default:'default'}

или
<? if (count($items): ?>
<? foreach ($items as $item): ?>

<? endfofeach ?>
<? else: ?>
nothing found
<? endif ?>

против
{foreach $items as $item}

{elsefeoreach}
nothing found
{endfeoreach}
Разница, конечно существенная, но мне кажется первый пример вы раздули. Можно же так:
<?=(isset($item['key'])?$item['key']:'default'?>
Да, немного раздул:) В любом случае у шаблонизаторов есть много подобных ништяков, где-то на сайте твиг-а его автор даже описывал подробно.
ничего не раздул, всё правильно сделал. А то что вы привели, как по вашему в том месте где находится слово default, вписать предложение которое будет содержать разные кавычки? нужно их экранировать? правильно. А при варианте mr_avi, ни какого экранирование делать не нужно, пиши какие угодно символы. Так что я только за шаблонотизатор. Вас послушать, как будто у всех вас мега супер сайты, с посещаемостью от 100 тыс. хостов. Могу сказать одно, есть у меня 4 сайта с посещаемостью 10-15 тыс хостов на каждом. все они стоят на оном не дорогом сервере, проблем с нагрузкой не ощущаю. Всё это баловство и игра со спичками как тут уже сказали.
>>>Так что я только за шаблонотизатор. Вас послушать…

Ощущение, что на меня наехали. Я не против шаблонизаторов, хотя и не пользуюсь перечисленными (работаю с нативным в ZF). Даже кое-что подчерпнул из комментариев. Мы просто обсудили конкретный пример. Если там где-то минусы, это не моя реакция.
<?=$item['key']?:'default'?>
php 5.3 =)
Notice: Undefined index… ;)
Правильно вот так
<xsl:choose>
<xsl:when test="key!=''"><xsl:value-of select="key"/></xsl:when>
<xsl:otherwise>default</xsl:otherwise>
</xsl:choose>
Выбор XSLT в качестве шаблонизатора моя вторая по величине ошибка после выбора Symfony 1.4 в качестве фреймворка. Может для чего-то он и хорош (я с такими задачами не сталкивался), но не для шаблонов web-сайтов. Перегруженный синтаксис, ограничения, неудобные конструкции, огромное количество кода, необходимость превращения данных в XML. Говорю это как человек, которому приходится поддерживать работу довольно крупного проекта с шаблонами на XSLT. Нет ни одной причины использовать его для обычных сайтов в PHP кроме поклонения стандартам.
Введение шаблонизаторов продиктовано не красотой кода, а стоимостью разработки и сопровождения.
«Красота кода» — это не самоцель. Это побочный продукт в борьбе за скорость кодирования и простоту сопровождения.
А в остальном вы правы что чистый php, что Smarty/Twig — примерно одно г…
Шаблонизаторы могут быть очень удобны в описанных выше ответах вариантах.

Вот чего я действительно не понимаю это чем удобней для юзера запись

[b]жирный текст[/b] чем <b>жирный текст</b>

зачем придуманы эти [b] не понимаю.
Есть подозрение что шаблон с стандартным php кодом будет генерироваться дольше чем текстовый шаблон прочитанный из файла с подстановкой переменных. (DISCLAIM: это просто мнение, я не проверял на реальных тестах.)

Дело может быть в том что используя стандартный php код в шаблонах, PHP движку придется как минимум компилить файл с шаблоном, что само по себе отъедает больше времени чем простое чтение содержимого файла и подстановка переменных.

В качестве подтверждения могу привести пример чтения конфигов описанных в этой статье habrahabr.ru/blogs/php/112402/. В этой статье результаты чтения и разбора INI файлов быстрее чем подключение PHP файлов с массивом данных.
в реальном использовании на php+apc к примеру уже наоборот.
Этот вопрос задают в каждом топике, если он хоть чуть-чуть имеет отношение у шаблонизаторам. Пройдитесь поиском по хабру, это уже обсуждалось тыщу раз
+1 в пользу шаблонизации: разделение логики и дизайна
Дизайнер не должнен знать РНР
ну что касается предпочтений, то это блиц (быстрый и элегантный)
А я написал свой шаблонизатор.

Не знаю, какая у него скорость работы, но скорость разработки очень высокая.

Попробуйте на чистом PHP поработать с формами.

У меня это делается с помощью псевдо HTML:
<~FormAuth>
   <~Input name="username" style="color: red" class="grayname" value="Имя пользователя" />
   <~Password name="password" style="color: red" class="size" />
   <~Submit value="Вход" />
</~>

и кода PHP:
class FormAuth extends Form{
    function onSubmitOk($values){
        //$values = array('username' => ..., 'password' => ...)
    }
}
Скорость выполнения — только один показатель. В третьей версии Smarty стал сам не свой до оперативки. Там на любой чих создается объект. Может Twig себя может лучше показать по этому показателю?
peak memory usage:

На первом тесте Smarty — 28.835.840, Twig — 27.787.264
На втором Smarty 5.242.880, Twig — 2.359.296

Третий у меня не запустился.
Fatal error: Maximum function nesting level of '100' reached, aborting! in C:\Work\Templates\smarty_vs_twig_inheritance\twig\twig\Autoloader.php on line 38
Twig создаёт по красивому классу и объекту для каждого скомпилированного шаблона. Smarty обходится обычной мешаниной из PHP и HTML.

Только что на тесте foreach сделал замеры памяти.

Для Smarty:
$start_time = microtime(true);
$start_memory = memory_get_usage();
$smarty->assign($data);
$smarty->fetch('demo.tpl');
echo memory_get_usage()-$start_memory;
echo "\n";
echo microtime(true)-$start_time;

Для Twig:
$start_time = microtime(true);
$start_memory = memory_get_usage();
$template = $twig->loadTemplate('demo.tpl');
$template->render($data);
echo memory_get_usage()-$start_memory;
echo "\n";
echo microtime(true)-$start_time;

Память во время компиляции:
Smarty: 2139904 байт
Twig: 1103960 байт


Память выполнения скомпилированного шаблона:
Smarty: 26472 байт
Twig: 100824 байт


То есть во время компиляции Smarty потребляет в ≈2 раза больше памяти, при обработке скомпилированного шаблона — в ≈4 раза меньше.
В дополнение оценка занимаемой памяти при инициализации Smarty и Twig.

Код для Smarty:
$start_memory = memory_get_usage();
require('smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->compile_check = false;
echo memory_get_usage()-$start_memory;

Код для Twig:
$start_memory = memory_get_usage();
require('twig/Autoloader.php');
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('templates');
$twig = new Twig_Environment($loader, array(
	'cache' => 'templates_c',
	'autoescape' => false, 
	'auto_reload' => false,
));
echo memory_get_usage()-$start_memory;


Результат:
Smarty: 899872 байт
Twig: 360952 байт


То есть базовый объект Smarty требует в ≈2 раза больше памяти, чем Twig. Хоть память и дешёвая, всё равно хочется надеяться, в следующих версиях Smarty это оптимизируют, поскольку для исполнения скомпилированного шаблона скорее всего не нужно столько богатства, сколько загружает Smarty по умолчанию :)
А почему memory_get_usage() а не memory_get_peak_usage()? ;) Важно ведь сколько памяти скрипт требует на всем процессе работы максимум, а не только в самом конце.
Честно говоря тест выглядит как-то однобоко и мне кажется, что судить в целом о производительности не позволяет.
Предложите, как его улучшить :)
Многое уже улучшили в комментах к статье. Ну а мое мнение что такого рода тесты надо делать более приближенными к реальным условиям.
хуяссе однобоко… базовые функции тестировались — если по тестам на них такой разбег все остальное не имеет смысла тестировать
Ну почему же только? Шаблонизаторы изобретают и в других языках. Хоть в Руби хоть в JavaScript.
Наверное только в Java и Net изобретатение [strike]велосипедов[/strike] препочитают велосипедам то что рекомендованно W3C.
Конечно, это просто был очень толстый пятничный комментарий. Проблемы с шаблонизаторами встречал везде, в основном связанные с их синтаксисом, а с производительностью вот пока нет, так что считаю что не обязательно использовать то что быстрее, а скорее надо использовать то что лучше и удобней для конкретной задачи.
Имхо, с твиг работать удобнее, а если важна производительность, то надо использовать или нативный PHP, или вообще Си-расширение, а то и от PHP отказываться.
У меня отрицательный опыт от использования Blitz — очень затратно поддерживать сложный вывод, только верстальщик один не можем им пользоваться, как это привычно в Twig&Smarty
У нас уже около 20 проектов на Zend+Blitz полет нормальный :)
Верстальщики «въехали» за 1 день быстрой разъяснительной работы.

Единственное — ищем правильную Zend_View обертку под Блитц.
Надо бы «засесть», чтоли. да переписать Смартивскую обертку под Blitz
Использовался ли при тестировании apc/eaccelerator? В статье об этом ни слова.
В конце статьи прикреплен архив с исходниками тестов.
Например, я уже повторил эти тесты на своем сервере (акселераторов не использовалось) все выполнялось конечно быстрее, чем у автора (мощнее машина), но принципиальных отличий нет.
Так в том и фишка! Когда много файлов акселлераторы играют роль, поэтому важно тестировать с ними.
Хорошо. Протестируйте с ними.
Акселераторы в исходники не входят же. А запуск пхп-скриптов на машине без акселератора сейчас, имхо, скорее исключение.
Мне было интересно увидеть результаты на своем сервере. Я скачал файлы и посмотрел. Если Вам интересны результы с акселераторами (или еще какими примочками), то скачайте и протестируйте.
Протестировал. Соотношение не поменялось :-( А я надеялся… Архитектурно Twig конечно красив, но производительность… Увы. Недавно кстати мучал Symfony2 — и тоже разочаровался в производительности. Сравнил пустые проекты из коробки — разница в 10 раз (Symfony аутсайдер), если из дефолтной песочницы Symfony убрать все лишнее — в 7 раз.
А с чем сравнивали? Не понятно из комментария.
Действительно, написал непонятно, да еще и соврал немного :-( Вот как было на самом деле. Тестировал я RoR из коробки с одним контроллером, выводящим Hello World через встроенный шаблонизатор и Symfony2 из коробки, с минимумом необходимых бандлов и тоже выводящий Hello World через Twig. Использовал nginx+fpm, акселлератор — apc. Для RoR использовал thin в самой стандартной конфигурации — thin start, без nginx впереди.

Результат — оказался примерно одинаковый, плюс-минус 5%. Правда, подозреваю что работу RoR приложения можно ОЧЕНЬ сильно оптимизировать настройкой thin и nginx перед ним.
Проверил с APC. В режиме CLI ухудшаются результаты обоих, соотношение скорости выполнения не меняется.
В любом случае после компиляции используется уже чистый php шаблон, по-моему некорректно сравнивать кто быстрее компилит, это одноразовая операция.
Время компиляции я привёл для справки. Время выполнения — во второй колонке «Выполнение».
Всеравно выполняется чистый php код, отличия должны быть минимальны, только на всяких проверках, да и любой accelerator приведет к одному результату.
Очень не хватает графиков в статье. Хотя бы на google charts и чтобы до хабраката. Наглядность наше все!
Хм… Раньше Twig, вроде бы, был быстрее Smarty 3.

Разница в производительности понятна:

Twig:
echo $this->getAttribute($this->getContext($context, 'item'), "id", array(), "any", false);
echo " ";
echo $this->getAttribute($this->getContext($context, 'item'), "title", array(), "any", false);
echo " ";
echo $this->getAttribute($this->getContext($context, 'item'), "var1", array(), "any", false);
echo " ";
echo $this->getAttribute($this->getContext($context, 'item'), "var2", array(), "any", false);
echo " ";
echo $this->getAttribute($this->getContext($context, 'item'), "var3", array(), "any", false);
echo " ";
...


Smarty:
<?php echo $_smarty_tpl->tpl_vars['item']->value['id'];?>
<?php echo $_smarty_tpl->tpl_vars['item']->value['title'];?>
<?php echo $_smarty_tpl->tpl_vars['item']->value['var1'];?>
<?php echo $_smarty_tpl->tpl_vars['item']->value['var2'];?>
...


Думаю в Twig-е есть что оптимизировать. Хочется верить в улучшение скорости Твига, уж очень он нравится.
Ага-ага. Идеологический подход Twig и Symfony мне очень близок, но уж больно медленно оно работает.
любители шаблонизаторов разбушевались )) но я повторюсь, шаблонизатор это медленное гавно для ленивых, потому что если вы ленитесь сделать isset в контроллере то просто не знаете какие данные к вам приходят, т.е. изначально вы делаете кривой проект.
Вы считаете, что шаблонизаторы в любом ЯП ‒ замена isset?
НЛО прилетело и опубликовало эту надпись здесь
А можно код вашего теста?
НЛО прилетело и опубликовало эту надпись здесь
Нативная функция экранирования у смарти черезчур комплексная. вообще нигде ее не использую.
проблема решается в два счета собственным компилером. В скомпилированном виде просто переменная сразу выводится в htmlSpecialChars() с нужными параметрами. Это будет значительно быстрее.
{$var|escape} или просто {$var} с включённым автоэкранированием Smarty преобразует в вызов htmlspecialchars:
echo htmlspecialchars($_smarty_tpl->tpl_vars['var1']->value, ENT_QUOTES, 'UTF-8', true);
Обычный модифиер просто каждый раз вызывается.
НЛО прилетело и опубликовало эту надпись здесь
У меня в вашем тесте получилось 0.22 секунды у Twig и 0.24 секунды у Smarty. При этом у Smarty здесь незначительное отставание обусловлено более тяжёлым assign. Если исключить время работы assign, шаблон отрабатывает за 0.17 секунд.
Smarty предлагает больше возможностей для работы с переменными (пространства переменных, управление кэшированием), и он вынужден сделать foreach по переданному вами в assign массиву переменных, по одной добавляя новые переменные во внутреннюю структуру, будто для каждой из них вы сделали отдельный assign.
Однако, время assign не так критично, потому что в реальной жизни assign редко делается чаще, чем для десятка-двух переменных. А вот в одной переменной массив на несколько сотен элементов — вполне реальная ситуация. То есть, если все ваши 10 тысяч переменных передать в шаблон как один массив, код на Smarty сразу станет на порядок быстрее работать.
Я до сих пор не могу понять как можно было «с чистого листа, с активным использованием PHP5» написать такое убожество (я про внутренности). По крайней мере за это уже можно выбрать twig. А все эти тесты близки к echo vs print.
Интересно, но методика тестирования мало имеет общего с реальной жизнью.

Советую попробовать по такой методике: alexeyrybak.com/blitz/blitz_en.html#performance-benchmarks

Подозреваю, что результаты будут отличаться кардинально.
Исчерпывающая статья, в которой даются ответы на следующие вопросы:
1. Зачем нужны шаблонизаторы? Разве php не шаблонизатор?
2. Что такое Twig и чем он отличается от smarty
3. Тесты и сравнение производительности
+ бурное обсуждение в комментах: fabien.potencier.org/article/34/templating-engines-in-php

Этот топик не нужен
К черту ваши шаблонизаторы., и дело с концом.
Хабр покушал код. Щи.

Вкратце:

1.Оптимизировать шаблонизатор для шаблонов далеких от реальности не будут.

2. В Twig есть функционал, которого нету в Smarty, из-за чего он работает медленней. Например, нотация через точку (.), которая абстрагирует от объектов и массивов, из-за этого шаблоны более гибкие. Smarty подобного не делает.

3. Работают над оптимизацией Twig 1.4
Точнее, сами тесты далеки от реальности.
Надо бы тестирование провести заново, в Twig 1.4 многие вещи, тормозившие в этих тестах сильно оптимизировали.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории