2012-03-20 3 views
1

Представьте, что у вас есть хранимые статьи mysql db.Использование php-кода в html ... в php

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() является частью решения (хотя риск для безопасности?), Но любые предложения, указатели и т. Д. Приветствуются!

ответ

2

Как правило, вы находите и заменяете в своем сохраненном содержимом, чтобы соответствовать тем заполнителям (формат которых вы можете свободно решать) и заменить их результатом оценки выражения, которое вы получаете от них. Для этого нет необходимости (или хорошей идеи) использовать 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.

+0

ничего себе, это здорово! Спасибо миллион, попробуем реализовать его как можно скорее :) – ThomasH

+0

Извините, что беспокою вас снова :) Я более или менее адаптировал ваше решение для удовлетворения моих потребностей ... передача переменных в функцию, которую я запускаю, была проблемой. .. Единственное, на что я не могу окутать голову, вероятно, очень просто: у меня есть несколько вызовов, например {{{showMap}}, {{{showRating}}}, {{{subItems}}} на той же странице. Если у меня есть три разных вызова, выполняется только первый, но отображается три раза. Любые советы, указывающие на меня в правильном направлении? Благодаря :) – ThomasH

1

Есть много шаблонов, которые делают это, вы можете сделать это, не используя eval(). С расширенным классом парсинга. Предопределите список функций и т. Д. И используйте его. Или просто используйте Templating engine.

+0

Вы можете сделать это с помощью пяти строк кода. Нет необходимости в шаблонах двигателей, разборе классов и т. Д. – Jon

+0

Спасибо за отзыв! Будет читать на шаблонах двигателей. – ThomasH

+0

@Jon Да, но я пишу ответ как общий не только для одной функции – safarov

Смежные вопросы