Как обрабатывать ошибочные ошибки внутри preg-replace-callback - PullRequest
0 голосов
/ 04 октября 2019

У меня есть HTML-строка , смешанная с PHP-кодами . поэтому я хочу просто оценить возможные коды и заменить их там. Моя идея примерно такая:

$html='Hi it <b>PAPION</b>. Now timestamp is <?php echo time(); ?>. have a good time.';
$html = preg_replace_callback('/(<\?php)(.*?)(\?>)/ims',function($matches){
    try {
        ob_start();
        eval($matches[2]); 
        return ob_get_clean();
    } catch(Exception $e) {
        return "";
    }
}, $html);

, и она отлично работает.

Но если в моем коде есть ошибка, например:

$html='Hi it <b>PAPION</b>. Now timestamp is <?php echo xxtime(); ?>. have a good time.';
$html = preg_replace_callback('/(<\?php)(.*?)(\?>)/ims',function($matches){
    try {
        ob_start();
        eval($matches[2]); 
        return ob_get_clean();
    } catch(Exception $e) {
        return "";
    }
}, $html);

вместо простоесли оставить место пустым, строка $ html останется пустой.

PHP> 5,4

любым способом справиться с этим?

С наилучшими пожеланиями!

Ответы [ 2 ]

0 голосов
/ 05 октября 2019

Как сказал @ user122293, проблема заключается в разнице между фатальными ошибками и другими ошибками.

В PHP <7 фатальные ошибки не поддаются отлову. </strong>

Кроме того, нет никаких исключений для фатальных ошибок даже в PHP> = 7

Теперь у нас есть несколько способов (от лучших к худшим):

  • A) Убедитесь, что мы используем PHP 7 или выше и изменим код на что-то вроде этого:
$html='Hi it is <b>PAPION</b>. Now timestamp is <?php echo time(); ?>. have a good time. a can be: <?php a=b*2 ?>. and wrong timestamp is <?php xxxxtime(); ?>.';
      $html = preg_replace_callback('/(<\?php)(.*?)(\?>)/ims',function($matches){
        try {
            ob_start();
            eval($matches[2]); 
            return ob_get_clean();
        } catch(Throwable $e) {
            return "";
        }
    }, $html);
    echo $html;

для вывода будет:

Привет, это PAPION . Теперь отметка времени 1570282086. хорошо провести время. может быть:и неправильная метка времени.

важной частью в моем случае было использование Throwable / Ошибка в перехвате. как объяснение здесь: https://stackoverflow.com/a/48381661/7514010

  • B) & C) Если у нас есть доступ к функции exec ,сначала мы пробуем код, а затем используем его. или даже временно сохранить файл и выполнить его для проверки. (Выглядит сумасшедшим!)

или

Отправьте код в качестве запроса тестеру и получите результат, а затем запустите его. (Это может не работать, потому что некоторые теги кода PHP могут зависеть друг от друга и должны оцениваться в одном и том же скрипте.) Оба объяснены здесь: https://stackoverflow.com/a/33531067/7514010

  • D) Использование register_shutdown_function + сумасшедший способ заставить PHP 5 наконец получить html снова или даже запустить следующие строки. Как в этом примере: https://3v4l.org/0R7dq

    • + E) Создать функцию для синтаксического анализа вручную перед eval или включить с помощью regex синтаксический анализ и function_exists или method_exists или т. Д. ... или любая библиотека.
0 голосов
/ 04 октября 2019

вы устанавливаете $ html на "" в catch. Вы должны изменить свой код следующим образом:

$html='Hi it <b>PAPION</b>. Now timestamp is <?php echo xxtime(); ?>. have a good time.';

preg_match('/(<\?php)(.*?)(\?>)/ims', $html, $matches);

$html = str_replace($matches[2], getEvalOutput($matches[2]), html);

echo "html is ".$html;

function getEvalOutput($matche){
    try {
        ob_start();
        eval($matche); 
        return ob_get_clean();
    } catch(Exception $e) {
        return " ERROR happened";
    }
}

вы получаете фатальную ошибку, и вы должны как-то ее обработать;это просто тестовый код для вас, чтобы понять путь:

<?php 

$phpCode = "
<?php
set_error_handler('myErrorHandler');
register_shutdown_function('fatalErrorShutdownHandler');
function myErrorHandler(\$code, \$message, \$file, \$line) {
    echo \$message;
}
function fatalErrorShutdownHandler()
{
  \$last_error = error_get_last();
  if (\$last_error['type'] === E_ERROR) {
    // fatal error
    myErrorHandler(E_ERROR, \$last_error['message'], \$last_error['file'], \$last_error['line']);
  }
}
\$html='Hi it <b>PAPION</b>. Now timestamp is <?php echo xxtime(); ?>. have a good time.';
\$html = preg_replace_callback('/(<\?php)(.*?)(\?>)/ims',function(\$matches){
    try {
        ob_start();
        eval(\$matches[2]); 
        return ob_get_clean();
    } catch(Exception \$e) {
    }
}, \$html);
echo \$html;";

file_put_contents('a.php', $phpCode);
$x = exec( 'php a.php');
echo $x;
/* delete the file */
unlink('a.php');
...