PHP调试preg-replace回调函数

时间:2012-04-03 13:12:53

标签: php eclipse callback preg-replace xdebug

我正在使用Exlipse和Xdebug来调试我的php代码,效果很好。但是有一种我无法调试的代码:回调函数

我正在使用preg_replace:

$pc = preg_replace('#\[div(=(.*))?\](.*?)\[/div\]#iuUe', "\bbcode_div('\$2', '\$3')", $_POST["data"]);

它可以调用该函数,但是在调试时,即使有一个断点,eclipse也不会进入函数内部。

如何让调试器进入该函数?

编辑:我需要使用preg_replace。

2 个答案:

答案 0 :(得分:4)

确保您使用preg_replace_callback()

preg_replace_callback('/ /', 'replace', 'this is not a complicated matter');

function replace($t)
{
   var_dump($t);    // <-- set breakpoint here
}

在拨打var_dump()之前,这会制动五次。


编辑: preg_replace()e修饰符一起使用时,需要一些hackery。在这种情况下,设置断点是不够的。你必须明确告诉XDebug打破:

function replace($t)
{
   // Production systems might (should) not have this function
   if (function_exists('xdebug_break'))
   {
      xdebug_break();
   }

   // Rest of the code...
}

答案 1 :(得分:2)

首先,我想提一下使用preg_replace_callback。我知道您提到必须使用preg_replace(没有给出任何理由),但我会先告诉您,您应该做什么并解释为什么preg_replace是不好的选择。

您的代码如下所示:

$pc = preg_replace('#\[div(=(.*))?\](.*?)\[/div\]#iuUe', "\bbcode_div('\$2', '\$3')", $_POST["data"]);

可以改写成以下内容:

<?php
$regex = '{\[div(?:=(.*?))?\](.*??)\[/div\]}iu';
$pc = preg_replace_callback($regex, function ($matches) {
    return bbcode_div($matches[1], $matches[2]);
});

如果您仍然使用PHP 5.2或更早版本(严重更新),请关注以下内容。

<?php
$regex = '{\[div(?:=(.*?))?\](.*??)\[/div\]}iu';
$pc = preg_replace_callback($regex, create_function('$matches', '
    return bbcode_div($matches[1], $matches[2]);
'));

现在,我将解释为什么/e是不好的选择。它给人一种虚假的安全感。当使用双引号代替时,您的安全性几乎被打破。

<?php
$_POST['code'] = 'echo "broken";';
$_POST['data'] = '[div]{${eval($_POST[code])}}[/div]';
$pc = preg_replace('#\[div(=(.*))?\](.*?)\[/div\]#iuUe', 'bbcode_div("$2", "$3")', $_POST["data"]);

使用'个字符时,addslashes()会在不应该/e内部使用addslashes的情况下进行转义!因此,如果用户输入"字符,则在进行调用时会更改为\"(在单引号中,\只能转义\'或者它是字面插入)。这可能不是你想要的东西。 /e修饰符已损坏。好吧,至少在PHP中。 Perl一个很好......

某些项目受其影响,例如使用/e修饰符的roundcube。它导致changes in codebase。如果您可以通过不使用/e修饰符来保护它们,为什么还要为黑客攻击而烦恼。

另外,阅读https://wiki.php.net/rfc/remove_preg_replace_eval_modifier(它已被接受,下一个PHP主要版本(PHP 5.5或PHP 6.0)将弃用此修饰符)。