PHP отладка функции обратного вызова preg-replace - PullRequest
2 голосов
/ 03 апреля 2012

Я использую Exlipse с Xdebug для отладки моих php-кодов, что хорошо работает. Но есть один тип кодов, которые я не могу отладить: функции обратного вызова

Я использую preg_replace:

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

, которая вызывает функцию нормально, но затмение не попадет внутрь функции во время отладки, даже с точкой останова.

Как я могу сделать отладчик, чтобы попасть внутрь этой функции?

РЕДАКТИРОВАТЬ: Мне нужно использовать preg_replace.

Ответы [ 2 ]

4 голосов
/ 03 апреля 2012

Убедитесь, что вы используете 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.В этом случае установка точки останова недостаточна.Вы должны явно указать XDebug прервать:

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

   // Rest of the code...
}
2 голосов
/ 03 апреля 2012

Во-первых, я хотел упомянуть использование 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 один хорошо ...

Это затронуло некоторые проекты, например roundcube, в котором использовался модификатор /e. Это вызвало изменения в кодовой базе . Зачем беспокоиться о хакерских атаках, если вы можете защитить от них, просто не используя модификатор /e.

Кроме того, прочитайте https://wiki.php.net/rfc/remove_preg_replace_eval_modifier (это уже принято, и следующая основная версия PHP (PHP 5.5 или PHP 6.0) не одобрит этот модификатор).

...