Представьте, что вы храните статьи mysql db.
Html хранится так:
<h1>I'm just foo</h1> <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p> <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
…
И отображается с помощью mysql_query и выполняется через результаты.
Но вот rub: Время от времени вы можете использовать предопределенную функцию, например, для вставки карты в html. Как пользователь вводит это, в html? Я не могу очень просто ввести:
<?php insertMap() ?>
поскольку это будет отображаться как php-теги с php-тегами внутри.
Я видел, как разные CMS обрабатывают его по-разному. Например, используя {{{insertMap}}} для вызова функции. Но тогда, как мне выполнить код, ища {{{}}} и запускать его как функцию?
Google и я чувствую, что eval () является частью решения (хотя риск для безопасности?), Но любые предложения, указатели и т. Д. Приветствуются!
В основном вы находите и заменяете в своем сохраненном содержимом, чтобы соответствовать тем заполнителям (формат которых вы можете свободно решать) и заменить их результатом оценки выражения, которое вы получаете от них. Для этого нет необходимости (или хорошей идеи) использовать eval
, вы можете легко свернуть свой собственный код, похожий на eval, который поддерживает только безопасное подмножество того, что делает eval
.
Предположим, вы выбрали {{{xxx}}}
качестве шаблона-заполнителя. Чтобы соответствовать этому, самый простой способ – использовать регулярные выражения через preg_match
или другую функцию в том же семействе; так как мы хотим также заменить, и мы хотим, чтобы замена производилась динамически, мы перейдем к preg_replace_callback
.
'/{{{([a-zA-Z_]+)}}}/'
для замены будет '/{{{([a-zA-Z_]+)}}}/'
, который соответствует последовательности одной или нескольких букв и подчеркивания между фигурными фигурными скобками. В круглых скобках есть синтаксис, зависящий от регулярного выражения, и я использовал их, чтобы впоследствии я мог просто ссылаться только на часть внутри (например, имя «шаблона»), не беспокоясь о фигурных скобках.
Обратный вызов будет функцией, которая производит заменяющий контент с учетом шаблона:
function produce_replacement($match) { // $match[1] means "the part of the template inside the braces"; // read up on the documentation of preg_replace_callback for more. $producerName = 'evaluate_'.strtolower($match[1]); return function_exists($producerName) ? $producerName() : null; }
Эта функция предназначена для получения имени шаблона (например, xxx
в {{{xxx}}}
) и посмотреть, существует ли функция, называемая evaluate_xxx
. Если это так, он вызывает функцию и возвращает результат; если нет, он возвращает null
. В любом случае результатом будет замена шаблона в исходном тексте.
Важно: это дизайнерское решение, обеспечивающее безопасность для реализации! Мы сделали это так, чтобы пользователь мог использовать любой «шаблон», который им нужен в тексте, но эти шаблоны приведут только к выполнению кода, если этот код находится в функции с именем evaluate_xxx
или аналогичной. Учитывая, что присутствие или отсутствие этих функций – это то, что вы контролируете, пользователь ограничен тем, что может сделать их разметка.
Итак, теперь вы можете:
$text = "Hello there {{{name}}}!"; $pattern = '/{{{([a-zA-Z_]+)}}}/'; $text = preg_replace_callback($pattern, 'produce_replacement', $text); echo $text; function evaluate_name() { return "Joe"; }
Смотрите в действии .
Есть много шаблонов, которые делают это, вы можете сделать это, не используя eval()
. С расширенным классом парсинга. Предопределите список функций и т. Д. И используйте его. Или просто используйте Templating engine.