Как правило, вы находите и заменяете в своем сохраненном содержимом, чтобы соответствовать тем заполнителям (формат которых вы можете свободно решать) и заменить их результатом оценки выражения, которое вы получаете от них. Для этого нет необходимости (или хорошей идеи) использовать eval
, вы можете легко свернуть свой собственный код, похожий на eval, который поддерживает только безопасное подмножество того, что делает eval
.
Предположим, вы выбрали {{{xxx}}}
в качестве шаблона-заполнителя. Чтобы соответствовать этому, самый простой способ - использовать regular expressions через preg_match
или другую функцию в том же семействе; так как мы хотим также заменить, и мы хотим, чтобы замена производилась динамически, мы отправимся с preg_replace_callback
.
модель для замены будет '/{{{([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";
}
See it in action.
ничего себе, это здорово! Спасибо миллион, попробуем реализовать его как можно скорее :) – ThomasH
Извините, что беспокою вас снова :) Я более или менее адаптировал ваше решение для удовлетворения моих потребностей ... передача переменных в функцию, которую я запускаю, была проблемой. .. Единственное, на что я не могу окутать голову, вероятно, очень просто: у меня есть несколько вызовов, например {{{showMap}}, {{{showRating}}}, {{{subItems}}} на той же странице. Если у меня есть три разных вызова, выполняется только первый, но отображается три раза. Любые советы, указывающие на меня в правильном направлении? Благодаря :) – ThomasH