简体   繁体   English

PHP调试preg-replace回调函数

[英]PHP debugging a preg-replace callback function

I'm using Exlipse with Xdebug to debug my php codes, which works well. 我使用带有Xdebug的Exlipse调试我的php代码,效果很好。 But there is one type of codes I can't debug: callback functions 但是有一种我无法调试的代码: 回调函数

I'm using preg_replace: 我正在使用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. 可以正确调用该函数,但是在调试时,即使有断点,Eclipse也不会进入该函数。

How can I make the debugger to get inside that function? 如何使调试器进入该函数?

EDIT: I need to use preg_replace. 编辑:我需要使用preg_replace。

Make sure you're using preg_replace_callback() : 确保您使用的是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() . 这将在调用var_dump()之前制动五次。


EDIT: Some hackery is required when preg_replace() is used with the e modifier. 编辑:将 preg_replace()e修饰符一起使用时,需要一些黑客工具。 In this case, setting a breakpoint is not sufficient. 在这种情况下,设置断点是不够的。 You'd have to explicitly tell XDebug to break: 您必须明确告诉XDebug中断:

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 . 首先,我想提到要使用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. 我知道您提到您必须使用preg_replace (不给出任何原因),但是我首先会告诉您应该做什么并解释为什么preg_replace是错误的选择。

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 5.2或更旧版本(认真更新),请按照以下说明进行操作。

<?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. 现在,我将解释为什么/e是错误的选择。 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!). 当使用'字符时, addslashes()在不应该转义时会转义( /e内部使用addslashes !)。 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. /e修饰符已损坏。 Well, at least that in PHP. 好吧,至少在PHP中是如此。 The Perl one is fine... Perl很好...

Certain projects were affected by it, for example roundcube, which used /e modifier. 某些项目受它影响,例如使用/e修饰符的roundcube。 It caused changes in codebase . 它引起了代码库的更改 Why bother with hacker attacks if you can protect against them simply by not using /e modifier. 如果您可以通过不使用/e修饰符来抵御黑客攻击,那又何必打扰他们呢?

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). 另外,请阅读https://wiki.php.net/rfc/remove_preg_replace_eval_modifier (已接受,并且下一个PHP主要版本(PHP 5.5或PHP 6.0)将弃用此修饰符)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM