PHP调试preg-replace回调函数

I'm using Exlipse with Xdebug to debug my php codes, which works well. But there is one type of codes I can't debug: callback functions

I'm using preg_replace:

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

which calls the function all right, but the eclipse wont get inside the function while debugging, even with a break point.

How can I make the debugger to get inside that function?

EDIT: I need to use preg_replace.

Make sure you're using preg_replace_callback():

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

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

This brakes five times before calling var_dump().


EDIT: Some hackery is required when preg_replace() is used with the e modifier. In this case, setting a breakpoint is not sufficient. You'd have to explicitly tell XDebug to break:

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

   // Rest of the code...
}

First, I wanted to mention to use preg_replace_callback. I know that you mention that you must use preg_replace (without giving any reasons), but I will tell you first, what you should do and explain why preg_replace is bad choice.

Your code looks like this:

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

It could be rewritten into following:

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

Or following if you still use PHP 5.2 or older (update, seriously).

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

Now, I'm going to explain why /e is bad choice. It gives false feeling of security. When using double-quotes in replacement, your security is practically broken.

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

When using ' characters, addslashes() escapes when it shouldn't (/e uses addslashes internally!). So if user would type " character, it would be changed into \" when doing call (in single-quotes, \ can only escape \ and ' or else it's inserted literally). It's probably not something you want. /e modifier is broken. Well, at least that in PHP. The Perl one is fine...

Certain projects were affected by it, for example roundcube, which used /e modifier. It caused changes in codebase. Why bother with hacker attacks if you can protect against them simply by not using /e modifier.

Also, read https://wiki.php.net/rfc/remove_preg_replace_eval_modifier (it's already accepted, and next PHP major version (PHP 5.5 or PHP 6.0) will deprecate this modifier).