Пользовательская потоковая оболочка с include или eval?
Обзор
В настоящее время я пишу механизм шаблонов. Он поддерживает даже несколько "форматов". В настоящее время он может анализировать файлы .php
и .tpl
(специфичные для этого движка).
Я приведу вам небольшой пример того и другого, чтобы дать вам Идею.
template.php:
Name: <?php echo $this->h($name) ?>
Posts:
<?php foreach($posts as $post): ?>
- <?php echo $this->h($post->name) ?> (<?php echo count($post->comments) ?> comments)
<?php echo $this->render('post/shortpost', array('post' => $post)) ?>
<?php endforeach ?>
Это просто стандартный PHP.
template.tpl
Name: {>$name}
Posts:
{foreach($posts as $post):}
- {>$post->name} ({=count($post->comments)} comments)
{=:render('post/shortpost', array('post' => $post))}
{endforeach}
Этот шаблонный "язык" просто переводится на PHP выше.
Comparission
Eval()
В настоящее время эти шаблоны анализируются с помощью eval()
.
Pro
Contra
- При возникновении ошибки в шаблоне вы получаете только бесполезное сообщение об ошибке, которое не
сообщите вам, в каком файле произошла ошибка, и иногда номер строки даже ошибочен.
- Безопасность? Файлы шаблонов нужны только для чтения?
- Сложно отлаживать код.
- Код сложнее понять
- больше..?
обтекатели потоков и include()
Недавно я прочитал об обтекателях потока в php. Вы даже можете создать свой собственный. Другим решением, чем eval
, было бы создание персонализированной обертки потока для каждого формата шаблона и использование include для анализа шаблона.
Это имеет следующие (потенциальные) недостатки:
Pro
- может решить проблемы с отображением неправильного файла/номера строки в сообщениях об ошибках (есть ли у кого-нибудь опыт?)
- вы можете обрабатывать файл шаблона именно так, как его нужно обрабатывать. Полный контроль.
Contra
-
allow_url_(fopen|include)
должен быть включен?
- Это медленно? (и
eval()
слишком медленный?)
- нет безопасности. включить в основном то же самое, что и eval.
- больше...?
EDIT: кэшированные проанализированные файлы и включают()
Третий вариант должен был бы проанализировать шаблон на PHP-код и кэшировать его (как это предложил @Jen-YaKovalev).
Pro
Contra
- если возникает ошибка при включении созданного шаблона и возникает ошибка
сообщение об ошибке не указывает вам на правильный файл/в конечном итоге показывает вам
неправильный номер строки.
- Для сохранения проанализированных файлов вам понадобится дополнительный
tmp/
каталог. Вам нужно написать
разрешения для PHP/webserver. Было бы более неуверенно, поскольку хакеры
добавит некоторый вредоносный код.
ИЗМЕНИТЬ: фильтры потока и включите ('php://filter')
в последнее время нашли следующие страницы php.net:
Это была бы другая возможность решить эту проблему. Используя include('php://filter/read=filtername/resource=file.php')
, я мог бы включить файл, который сначала будет проходить через фильтр filtername
, прежде чем он будет выполнен.
Pro
- не требуется столько кода, как обтекатели потоков
Contra
- Не так много возможностей, как с обтекателями потоков (кэширование?)
- безопасность?
- скорость?
Вопрос
- У вас есть опыт использования обтекателей потоков для анализа файлов шаблонов или подобных?
- Есть ли еще какое-то другое решение?
- Есть ли больше pro и contras?
- Какой из них вы бы порекомендовали?
Ответы
Ответ 1
Я думаю, что это просто вкус одного стиля кодирования, вам лучше проголосовать за него или что-то в этом роде.
- Я лично думаю, что eval - зло (на каждом языке),
- имел плохие впечатления от включения + php-обертки (даже интегрированные *),
- зная, что все большие (gish) шаблонные системы используют компиляцию в php файле (smarty, twig), это тот, который я бы использовал.
(*) В более раннем проекте мы использовали 1-строчный код (пустое расширение класса) в data-url, который включает, и его производительность была ужасной.
Ответ 2
Конечно, вы не хотите анализировать шаблоны по каждому запросу в производственной среде, это будет пустой тратой ресурсов и, следовательно, медленным и не очень умным подходом, поэтому я настоятельно рекомендую перейти к кэшированные проанализированные файлы и включают() подход.