Примечание: я использую Zend Framework, но я думаю, что большая часть этого относится к кодированию PHP в целом.
Я пытаюсь выбрать стратегию написания скриптов представлений, возможно, с помощью шаблонизатора. Мотивация: ясность и безопасность . Я просто не доволен написанием сценариев .phtml. Этот синтаксис ужасно многословен для выполнения наиболее часто необходимой вещи - вывода переменной:
<?php echo $this->escape($this->myVariable); ?>
В дополнение к длинному коду, ИМХО автору шаблона не нужно помнить (и беспокоиться) о написании escape-вызова каждый раз, когда он хочет вывести переменную. Забывание вызова почти наверняка приведет к уязвимости XSS.
У меня есть два возможных решения этой проблемы:
Решение 1: шаблонизатор с автоматическим экранированием
Я думаю, что по крайней мере Smarty имеет возможность автоматического экранирования html-сущностей при выводе переменных. Против Smarty очков есть , но, возможно, по крайней мере некоторые из них будут рассмотрены в предстоящем 3.0 - я еще не проверял.
Механизмы шаблонов на основе XML, такие как PHPTAL , также будут по умолчанию скрывать любые данные. Хотя для начинающего они могут показаться странными. Может быть, все еще стоит попробовать?
Решение 2. Сброс данных в модели
Конечно, другим вариантом будет экранирование необходимых данных, уже находящихся в модели (или даже в контроллере?). Модель уже должна знать тип содержимого (в основном простой текст или текст HTML) каждого поля, поэтому было бы логично экранировать данные там. Представление может рассматривать все данные как безопасный HTML. Это позволило бы, например. изменение типа данных поля с простого текста на HTML, не касаясь сценария представления - только путем изменения модели.
Но опять же, это не похоже на хорошую практику MVC. Кроме того, есть проблемы с этим подходом:
- иногда представление хочет печатать только первые n символов, и мы не хотим в конечном итоге обрезать данные
foo & bar
как foo &am
(сначала экранируя их как foo & bar
)
- возможно, представление хочет создать URL-адрес с varName = $ varName в строке запроса - опять же, экранирование уже в модели будет плохим.
(Эти проблемы могут быть решены путем предоставления двух версий данных или удаления из шаблона в шаблоне. Мне это кажется плохим.)
Идеи? Я что-то пропустил? Что вы считаете «лучшей практикой»?
PS. Этот пост посвящен поиску общего решения для любых предоставленных пользователем текстовых данных, которые могут содержать <
или >
или любые другие символы. Таким образом, фильтрация данных перед их сохранением в базе данных не является решением.
Обновление:
Спасибо за все комментарии. Я провел еще несколько исследований и в следующий раз оценим Twig и, возможно, Open Power Template . И то, и другое кажется интересным: Twig выглядит очень просто, но проект молодой. На стороне XML синтаксис OPT выглядит немного лучше, чем синтаксис PHPTAL. И Twig, и OPT достаточно хорошо документированы.