PHP: запустить функцию в определенных местах (preg_callback?)
Я пытаюсь запустить функцию всякий раз, когда есть [%xxx%] (выступая в качестве заполнителя, если хотите), например:
Bla bla bla blabla. Blablabla bla bla.
[%hooray%]
Blabla hey bla bla. [%yay%] blabla bla.
Я в значительной степени новичок в PHP, но мне удалось всколыхнуть голову и придумать следующее (ура - мне как-то удалось понять основы регулярных выражений!):
$maintext = preg_replace("#\[%(.{1,20})%\]#", "display_products('$1')"), $maintext);
echo $maintext;
Я пытался работать с модификатором e, я пытался использовать preg_replace_callback, и все это работает, но мне не нужно запускать функцию до того, как я выведу переменную $maintext.
Любая помощь по этому, ребята?
редактировать Регулярное выражение не проблема - это работает нормально. Мне просто нужно выяснить, как запустить функцию, только когда я эхо $maintext... preg_replace_callback запускает функцию немедленно...
3 ответа
Поскольку PHP является однопоточным процедурным скриптовым языком 1, он не работает так, как вы этого хотите.
Невозможно запустить функцию только при вызове echo
2, что вам нужно, это дополнительная переменная.
$newVariable = preg_replace_callback("#\[%(.{1,20})%\]#", function($matches) {
// Do your thang here
}, $maintext);
// $maintext remains the same as it was when you started, do stuff with it here
// When you come to output the data, do...
echo $newVariable;
Существуют и другие подходы к этой проблеме, например, оборачивание приведенного выше кода в функцию, которая может быть вызвана по требованию, и использование обратного вызова буферизации вывода (см. Сноску № 2), но чтение между строк, я думаю, все это было бы излишним для чего. это относительно простая проблема.
Для справки, я думаю, что ваше регулярное выражение будет лучше, если вы сузите допустимый контент до него, он потенциально будет соответствовать символам, которые вам не нужны. Я подозреваю, что это было бы лучше:
#\[%(\w{1,20})%\]#
Это позволит только персонажам a-zA-Z0-9_
в заполнителе.
1 Другие могут сказать, что PHP теперь является объектно-ориентированным языком, но они ошибаются. Он по-прежнему в основном работает так же, как и язык сценариев, но теперь предоставляет множество ОО-функций.
2 Можно сделать что-то очень близкое к этому, но это очень редко когда-либо хорошая идея, и она слишком продвинута для решения этой проблемы.
РЕДАКТИРОВАТЬ
Важно отметить, что при использовании любого метода для передачи замен через обратный вызов (e
модификатор или preg_replace_callback()
) функция обратного вызова должна возвращать новую строку, а не выводить ее напрямую.
Это связано с тем, что код в любом операторе выполняется изнутри, а "внутренний" echo
оператор (в функции обратного вызова) будет выполнен перед "внешним" echo
заявление (на линии, где preg_replace()
называется, поэтому порядок вывода вещей будет неправильным.
Например:
$str = "This is my string which contains a %placeholder%";
echo preg_replace_callback('/%(\w+)%/', function($matches) {
echo "replacement string";
}, $str);
// Wrong - outputs "replacement stringThis is my string which contains a "
echo preg_replace_callback('/%(\w+)%/', function($matches) {
return "replacement string";
}, $str);
// Right - outputs "This is my string which contains a replacement string"
Если у вас есть сценарий, который многократно использует echo, и вы хотите изменить напечатанный текст, вы можете использовать буферизацию вывода:
ob_start();
/*
* Lots of php code
*/
$maintext = ob_get_clean(); // now you capture the content in $maintext
// than you modify the output
$maintext = preg_replace("#\[%(.{1,20})%\]#", "display_products($1)", $maintext);
echo $maintext;
ob_start принимает функцию обратного вызова, вы можете прочитать больше в этом разделе: Перед выводом всех файлов PHP пройти через "файл фильтра"