PHP:在某些地方运行函数(preg_callback?)

时间:2012-07-18 08:27:10

标签: php preg-replace eval preg-replace-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 个答案:

答案 0 :(得分:0)

因为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现在是一种面向对象的语言,但它们是错误的。它仍然从根本上在底层工作,它仍然是一种脚本语言,但现在提供了许多OO功能。
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"

答案 1 :(得分:0)

如果您的脚本多次使用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;

答案 2 :(得分:0)

ob_start接受回调函数,您可以阅读有关此主题的更多信息: Making all PHP file output pass through a "filter file" before being displayed