Не понял, при чем здесь противопоставление «нейтив — шаблонизаторы».
Очевидно же, что разговор здесь идет о шаблонизаторах вообще, любых.
Все описанные выше принципы относятся к «шаблонизаторам» в той же самой мере. В них точно так же должна быть поддержка фильтров, которая должна иметь ту или иную внутреннюю реализацию. Вот варианты реализации фильтров мы и обсуждаем здесь.
На момент вызова tmpl::set() мы вообще не знаем, какой конкретно синтаксис в шаблонизаторе используется — нейтив или самопал. И не должны знать, по-хорошему.
Ну, это уже вкусовщина. У кого-то от угловых рябит, у кого-то — от фигурных.
А по поводу остальных фич — надо различать РНР как язык разметки шаблонов и Шаблонизатор как модуль приложения. Чистый PHP не означает «чисто include()» как обработчик шаблонов — такой обработчик все равно пишется специально. и в нем уже можно реализовать и наследование и многие другие вкусности
Я думаю, в хорошем приложении наборов должно быть больше.
«неэскейпенные» — это, на самом деле, частный случай, один из фильтров.
Но фильтров может быть много — urlencode, JSON к примеру.
Выхд-выход.
Это то, о чем я говорил выше. Безопасность важнее функциональности.
Всё правильно — выше описана, в сущности, идеальная модель разработки:
— по умолчанию всё форматируем наиболее безопасным способом
— для отличного контекста специально выставляем соответствующий контексту фильтр
— если разработчик зевнул и не выставил, то вывод бьётся
— не беда — когда разработчик это замечает, то просто добавляет соответствующий фильтр
Ну, на моей памяти из недавнего — например, об особенностях работы mysqli_multi_query(). Документация очень невнятная а результаты собственных экспериментов очень легко мисинтрпретировать.
Или вот я ещё спрашивал про удивительный баг — все функции для работы с файлами как одна молча отказывались работать с HTTP враппером. Ответ, правда, я получил уже после того, как написал воркараунд, но тем не менее.
После ФБ не было бешеного роста. Вот характерная картинка — www.google.ru/trends/explore#q=%2Fm%2F060kv
Она, хоть, и в собственных гуглопопугаях, но тренд совершенно очевиден.
Взрывной рост интереса к ПХП начался в начале века, когда он занял абсолютно пустую нишу, да ещё и предложил нулевой порог вхождения. Но уже к середине первой декады пошел на спад. А в середине второй, я, как активный участник многих ПХП-сообществ, невооруженным глазом вижу снижение интереса и трафика.
Фреймворки развиваются на фоне падения популярности.
Новичок читает статьи типа этвудовской «The PHP Singularity» с двойным гвоздодёром на картинке и выбирает что помоднее. Благо, выбор у него есть.
Бангалорские неприкасаемые не пишут энтерпрайз. Они побираются на одеске за еду. И, сколько в них денег ни влей, «Войну и мир» они не напечатают, увы
А организатор бизнес-процессов тоже анализирует тренды и выбирает наиболее, на его взгляд, перспективные.
Вокруг Друпала и Уордпресса уже сложились эффективные экосистемы, в которых 99% пользователей устраивает базовый функционал, а запросы остальных удовлетворяет имеющееся сообщество разработчиков — и особого прорыва с той стороны не видно.
В общем, падение популярности РНР в последние годы — это факт. И фреймворки — это действительно второе дыхание языка.
Вот — это очень дельный комментарий.
В отличие от SQL, в котором неверное форматирование не приведет к проблемам в безопасности, а, в худшем случае — просто к ошибке приложения, в HTML не так всё просто.
Я так думаю, что для дефолтного искейпинга надо применять более расширенный набор символов, чем тот, который используется в htmlspecialchars().
Ну это-то как раз просто.
Переменные в шаблон в любом случае должны передаваться какой-нибудь tmpl::set() — и вот у этой функции должен быть дополнительный параметр, который, скажем, делает переменную свойством специального объекта, или помещает в отдельный список — способов много.
Ну, я писал выше — в современных объектах далеко не все свойства доступны через public переменные, которые можно вытянуть через get_object_vars().
Всякий lazy loading, getters и прочая магия сильно затрудняют такой прямолинейный подход.
К тому же, возвращать данные может не только свойство, но и метод.
Но сам по себе подход хорош. Я пытался решить задачу таким же примерно наскоком, но обломался, по причинам, изложенным выше.
И вообще, очень приятно видеть ответы с кодом. Очень люблю такой подход!
Речь идет о событиях, которые просходят уже после описываемых.
Интерес к РНР в мире стабильно падает уже несколько лет, и никакой ФБ этому не помеха.
Сообщества закрываются, трафик на ресурсах падает. На Хабре частота статей по пхп упала в несколько раз. На Стаковерфлоу, скажем, бешеный трафик поддерживается исключительно за счет бангалорских бедняков, для которых писать на пхп — это альтернатива ручной разборке океанских лайнеров на металлолом. И пхп там — исключительно процедурная лапша из прошлого века (которая, кстати, на мой взгляд, и есть главный двигатель популярности). И в начале статьи упоминается именно этот факт.
Так что важность фреймворков, действительно, проявляется не где-то в истории, а прямо сейчас.
Должен-должен.
Это как в SQL — по умолчанию все передаваемые данные обрабатываются как строки. Любые исключения надо оговаривать специально. Иначе проблем не избежать
Это очень скоропалительный комментарий, не проходит проверку практикой.
Как раз в PHP, как языке общего назначения, так делать ни в коем случае нельзя.
Ведь проблема касается только одной ипостаси, РНР-как-шаблонизатора.
правда, для <?=?> оно с одной стороны, идеально подходит, но с другой — настолько ломать обратную совместимость — я думаю, невозможно.
Беда в том, что как раз в приведённом выше примере мы имеем объект $order, и это очень показательно.
А объекты — штука тонкая. К моменту попытки автоискейпинга объект может ещё не знать, что у него такое свойство есть.
Или вообще его не иметь.
Ну то есть да — если заставить разработчика передавать в шаблон только скаляры и массивы — это работает.
Но, увы, я еще не встречал ни одного, который бы не хотел передать в шаблон объект $user и уже в шаблоне обращаться к его свойствам/методам. Хотя сам считаю это порочной практикой.
Ну вот это «очень легко решается» и проблема.
Кто-то стал решать, но не зная технологии, насовал в _e() кучу бесполензного мусора.
Кто-то вообще не знал, что что-то решать надо.
Кто-то знал, да забыл.
В общем — типичный «пхп-стайл», и типичный же результат, ЕВПОЧЯ.
Я не зря привел аналогию с SQL — там эти баталии на тему «легко решается» уже (надеюсь) отгремели, и все согласились наконец-то, что ручное экранирование должно быть забыто как страшный сон.
Ну вот кстати это тоже неправильно. Автоэкранирование должно быть в дефолтном операторе, а всё остальное — опция.
то есть, всё должно быть наоборот — в Laravel пишем {{{ }}} по дефолту, а можно написать {{ }}, если надо вывести данные как есть. А вообще определять вывод количеством скобочек — это мина замедленного действия
Эта ерунда с подсчетом скобочек еще аукнется многочисленными XSS-ами.
Ну, учитывая, что большинство пользователей похапешечки не вышли из ясельного возраста, то им такая реклама как раз.
Те же, которые вышли, или сами понимают сильные и слабые стороны движка безо всякой рекламы, либо вообще пилят большой портал на собственном софте, и им поп-фреймворки перпендикулярны.
А так-то да — ORM и роутенг преподносятся прям как исключительные заслуги Лярвы, и чуть фанфары из каждого абзаца не играют.
У нейтив ПХП есть один очень серёьзный недостаток — невозможно сделать нормальный авто-искейпинг.
А это, пожалуй, в шаблонизаторе главное.
«приятный синтаксис», «экономия целых двух символов на оператор» — это всё ерунда. А вот собственный оператор вывода, которым можно управлять — это очень, очень важно.
Ведь на самом деле в нейтив должно быть что-то вроде
<li><?=_e($order->title) ?></li>
— а с таким довеском идея как-то уже меркнет.
В какой-то мере можно рассматривать {{ $order->title }} как аналог плейсхолдера в SQL. А <?=$order->title ?>, соответственно — как прямую интерполяцию, со всеми вытекающими.
Ладно, так и быть, я попробую один раз.
Хотя заранее уверен, что не получится — уж больно случай запущенный.
Любая проверка входящих данных не имеет ни малейшего отношения к работе с БД.
Ну, то есть, в типичном похапе-стайл говнокоде, где «роутер» — это if (isset($_POST['submit'])), после которого данные сразу же пихаются в mysql_query — тут вполне возможно визуально проконтролировать, что попадающие в запрос данные были проверены некой кривой регуляркой. Но так, вообще-то, никто давно не пишет.
Ты и сам упомянул роутер — за язык тебя никто не тянул. Наличие же роутера предполагает наличие мало-мальски структурированного приложения. В котором слой работы с БД отделен от роутера многими другими слоями. И к моменту, когда надо исполнять запрос, код не имеет ни малейшего представления о том, откуда взялись данные — из роутера, из POST-а, из БД, из файла, из веб-сервиса стороннего. Больше того — ему это знать и НЕ НАДО. А вот программисту желательно понимать принцип разделения полномочий. Хотя, о чем это я? Программистов среди пользователей похапе — раз-два, и обчёлся.
Получается, чтобы учесть результаты проверки роутером, надо прицеплять к данным какую-то специальную бирочку, мол, «мы тут в роутере проверили, всё чисто — можно в запрос писать напрямую». Разумеется, это будет глупость несусветная. Это заберет ресурсов в сто раз больше, чем сэкономит, и на пустом месте усложнит систему.
Плюс, учитывая, что роутер — не единственный источник данных, получается, что там таких бирочек надо миллион. Учитывая очевидную глупость такого подхода, так никто и не делает. И идея про «всемирно принятую практику разработки» — это исключительно твои эротические фантазии.
Мировая же практика — для любых данных, независимо от их источника, использовать подготовленные выражения. Где вместо самих данных в запросе ставятся метки — плейсхолдеры. Если тебе не хватает ума понять принцип типизованных плейсхолдеров (повсеместно уже пол-века применяемый в функциях семейства printf()) — ничего страшного, пусть будут обычные. Типизация — это всего лишь возможность унифицировать работу с данными различных типов, не раздувая код, давая малограмотному разработчику единый инструмент для любых типов данных. Но внутри у там все равно лежит тот же самый принцип подготовленных выражений (впрочем, судя по твоему последнему каменту, ты даже не понимаешь, что плейсхолдер — это обязательный, ключевой элемент подготовленного выражения, без которого оно бесполезно).
И в итоге, написав «Зачем городить огород из [типизированных] плейсхолдеров?» — и тут же предложив взамен проверку входящих данных! — ты поставил всё с ног на голову — отрицая действительно общепринятую практику, и продвигая левый бессмысленный самопал.
В общем, я надеюсь что ты поумнеешь всё-таки (лет, где-нибудь, через 10), и когда-нибудь поймешь, какую глупость ты тут написал.
Да дело-то ведь не в авторе. А в том что каша в голове. Всё буквально с ног на голову.
Ерунда с входной валидацией у него — это «всемирно принятая практика».
А на самом деле всемирно принятая практика (использование подготовленных выражений) — для него это «зачем городить огород».
Очевидно же, что разговор здесь идет о шаблонизаторах вообще, любых.
Все описанные выше принципы относятся к «шаблонизаторам» в той же самой мере. В них точно так же должна быть поддержка фильтров, которая должна иметь ту или иную внутреннюю реализацию. Вот варианты реализации фильтров мы и обсуждаем здесь.
На момент вызова tmpl::set() мы вообще не знаем, какой конкретно синтаксис в шаблонизаторе используется — нейтив или самопал. И не должны знать, по-хорошему.
А по поводу остальных фич — надо различать РНР как язык разметки шаблонов и Шаблонизатор как модуль приложения. Чистый PHP не означает «чисто include()» как обработчик шаблонов — такой обработчик все равно пишется специально. и в нем уже можно реализовать и наследование и многие другие вкусности
«неэскейпенные» — это, на самом деле, частный случай, один из фильтров.
Но фильтров может быть много — urlencode, JSON к примеру.
Это то, о чем я говорил выше. Безопасность важнее функциональности.
Всё правильно — выше описана, в сущности, идеальная модель разработки:
— по умолчанию всё форматируем наиболее безопасным способом
— для отличного контекста специально выставляем соответствующий контексту фильтр
— если разработчик зевнул и не выставил, то вывод бьётся
— не беда — когда разработчик это замечает, то просто добавляет соответствующий фильтр
Или вот я ещё спрашивал про удивительный баг — все функции для работы с файлами как одна молча отказывались работать с HTTP враппером. Ответ, правда, я получил уже после того, как написал воркараунд, но тем не менее.
После ФБ не было бешеного роста. Вот характерная картинка — www.google.ru/trends/explore#q=%2Fm%2F060kv
Она, хоть, и в собственных гуглопопугаях, но тренд совершенно очевиден.
Взрывной рост интереса к ПХП начался в начале века, когда он занял абсолютно пустую нишу, да ещё и предложил нулевой порог вхождения. Но уже к середине первой декады пошел на спад. А в середине второй, я, как активный участник многих ПХП-сообществ, невооруженным глазом вижу снижение интереса и трафика.
Фреймворки развиваются на фоне падения популярности.
Новичок читает статьи типа этвудовской «The PHP Singularity» с двойным гвоздодёром на картинке и выбирает что помоднее. Благо, выбор у него есть.
Бангалорские неприкасаемые не пишут энтерпрайз. Они побираются на одеске за еду. И, сколько в них денег ни влей, «Войну и мир» они не напечатают, увы
А организатор бизнес-процессов тоже анализирует тренды и выбирает наиболее, на его взгляд, перспективные.
Вокруг Друпала и Уордпресса уже сложились эффективные экосистемы, в которых 99% пользователей устраивает базовый функционал, а запросы остальных удовлетворяет имеющееся сообщество разработчиков — и особого прорыва с той стороны не видно.
В общем, падение популярности РНР в последние годы — это факт. И фреймворки — это действительно второе дыхание языка.
В отличие от SQL, в котором неверное форматирование не приведет к проблемам в безопасности, а, в худшем случае — просто к ошибке приложения, в HTML не так всё просто.
Я так думаю, что для дефолтного искейпинга надо применять более расширенный набор символов, чем тот, который используется в htmlspecialchars().
Переменные в шаблон в любом случае должны передаваться какой-нибудь tmpl::set() — и вот у этой функции должен быть дополнительный параметр, который, скажем, делает переменную свойством специального объекта, или помещает в отдельный список — способов много.
Всякий lazy loading, getters и прочая магия сильно затрудняют такой прямолинейный подход.
К тому же, возвращать данные может не только свойство, но и метод.
Но сам по себе подход хорош. Я пытался решить задачу таким же примерно наскоком, но обломался, по причинам, изложенным выше.
И вообще, очень приятно видеть ответы с кодом. Очень люблю такой подход!
Интерес к РНР в мире стабильно падает уже несколько лет, и никакой ФБ этому не помеха.
Сообщества закрываются, трафик на ресурсах падает. На Хабре частота статей по пхп упала в несколько раз. На Стаковерфлоу, скажем, бешеный трафик поддерживается исключительно за счет бангалорских бедняков, для которых писать на пхп — это альтернатива ручной разборке океанских лайнеров на металлолом. И пхп там — исключительно процедурная лапша из прошлого века (которая, кстати, на мой взгляд, и есть главный двигатель популярности). И в начале статьи упоминается именно этот факт.
Так что важность фреймворков, действительно, проявляется не где-то в истории, а прямо сейчас.
Это как в SQL — по умолчанию все передаваемые данные обрабатываются как строки. Любые исключения надо оговаривать специально. Иначе проблем не избежать
Как раз в PHP, как языке общего назначения, так делать ни в коем случае нельзя.
Ведь проблема касается только одной ипостаси, РНР-как-шаблонизатора.
правда, для <?=?> оно с одной стороны, идеально подходит, но с другой — настолько ломать обратную совместимость — я думаю, невозможно.
А объекты — штука тонкая. К моменту попытки автоискейпинга объект может ещё не знать, что у него такое свойство есть.
Или вообще его не иметь.
Ну то есть да — если заставить разработчика передавать в шаблон только скаляры и массивы — это работает.
Но, увы, я еще не встречал ни одного, который бы не хотел передать в шаблон объект $user и уже в шаблоне обращаться к его свойствам/методам. Хотя сам считаю это порочной практикой.
Кто-то стал решать, но не зная технологии, насовал в _e() кучу бесполензного мусора.
Кто-то вообще не знал, что что-то решать надо.
Кто-то знал, да забыл.
В общем — типичный «пхп-стайл», и типичный же результат, ЕВПОЧЯ.
Я не зря привел аналогию с SQL — там эти баталии на тему «легко решается» уже (надеюсь) отгремели, и все согласились наконец-то, что ручное экранирование должно быть забыто как страшный сон.
то есть, всё должно быть наоборот — в Laravel пишем {{{ }}} по дефолту, а можно написать {{ }}, если надо вывести данные как есть. А вообще определять вывод количеством скобочек — это мина замедленного действия
Эта ерунда с подсчетом скобочек еще аукнется многочисленными XSS-ами.
Те же, которые вышли, или сами понимают сильные и слабые стороны движка безо всякой рекламы, либо вообще пилят большой портал на собственном софте, и им поп-фреймворки перпендикулярны.
А так-то да — ORM и роутенг преподносятся прям как исключительные заслуги Лярвы, и чуть фанфары из каждого абзаца не играют.
А это, пожалуй, в шаблонизаторе главное.
«приятный синтаксис», «экономия целых двух символов на оператор» — это всё ерунда. А вот собственный оператор вывода, которым можно управлять — это очень, очень важно.
Ведь на самом деле в нейтив должно быть что-то вроде
— а с таким довеском идея как-то уже меркнет.
В какой-то мере можно рассматривать {{ $order->title }} как аналог плейсхолдера в SQL. А <?=$order->title ?>, соответственно — как прямую интерполяцию, со всеми вытекающими.
Хотя заранее уверен, что не получится — уж больно случай запущенный.
Любая проверка входящих данных не имеет ни малейшего отношения к работе с БД.
Ну, то есть, в типичном похапе-стайл говнокоде, где «роутер» — это if (isset($_POST['submit'])), после которого данные сразу же пихаются в mysql_query — тут вполне возможно визуально проконтролировать, что попадающие в запрос данные были проверены некой кривой регуляркой. Но так, вообще-то, никто давно не пишет.
Ты и сам упомянул роутер — за язык тебя никто не тянул. Наличие же роутера предполагает наличие мало-мальски структурированного приложения. В котором слой работы с БД отделен от роутера многими другими слоями. И к моменту, когда надо исполнять запрос, код не имеет ни малейшего представления о том, откуда взялись данные — из роутера, из POST-а, из БД, из файла, из веб-сервиса стороннего. Больше того — ему это знать и НЕ НАДО. А вот программисту желательно понимать принцип разделения полномочий. Хотя, о чем это я? Программистов среди пользователей похапе — раз-два, и обчёлся.
Получается, чтобы учесть результаты проверки роутером, надо прицеплять к данным какую-то специальную бирочку, мол, «мы тут в роутере проверили, всё чисто — можно в запрос писать напрямую». Разумеется, это будет глупость несусветная. Это заберет ресурсов в сто раз больше, чем сэкономит, и на пустом месте усложнит систему.
Плюс, учитывая, что роутер — не единственный источник данных, получается, что там таких бирочек надо миллион. Учитывая очевидную глупость такого подхода, так никто и не делает. И идея про «всемирно принятую практику разработки» — это исключительно твои эротические фантазии.
Мировая же практика — для любых данных, независимо от их источника, использовать подготовленные выражения. Где вместо самих данных в запросе ставятся метки — плейсхолдеры. Если тебе не хватает ума понять принцип типизованных плейсхолдеров (повсеместно уже пол-века применяемый в функциях семейства printf()) — ничего страшного, пусть будут обычные. Типизация — это всего лишь возможность унифицировать работу с данными различных типов, не раздувая код, давая малограмотному разработчику единый инструмент для любых типов данных. Но внутри у там все равно лежит тот же самый принцип подготовленных выражений (впрочем, судя по твоему последнему каменту, ты даже не понимаешь, что плейсхолдер — это обязательный, ключевой элемент подготовленного выражения, без которого оно бесполезно).
И в итоге, написав «Зачем городить огород из [типизированных] плейсхолдеров?» — и тут же предложив взамен проверку входящих данных! — ты поставил всё с ног на голову — отрицая действительно общепринятую практику, и продвигая левый бессмысленный самопал.
В общем, я надеюсь что ты поумнеешь всё-таки (лет, где-нибудь, через 10), и когда-нибудь поймешь, какую глупость ты тут написал.
Ерунда с входной валидацией у него — это «всемирно принятая практика».
А на самом деле всемирно принятая практика (использование подготовленных выражений) — для него это «зачем городить огород».