【问题标题】:How can I catch a parse error in php eval()?如何在 php eval() 中捕获解析错误?
【发布时间】:2020-08-10 18:12:40
【问题描述】:

我想使用 php eval() 来识别潜在的解析错误。我知道 eval 的危险,但这是一个非常有限的用途,需要事先进行充分验证。

我相信在 php 7 中我们应该能够捕获解析错误,但它不起作用。这是一个例子:

  $one = "hello";
  $two = " world";
  $three = '';
  $cmdstr = '$three = $one . $tw;';

  try {
     $result = eval($cmdstr);
 } catch (ParseError $e) {
     echo 'error: ' . $e;
 }

echo $three;

我试图在此处引起解析错误,看看我是否可以捕获它,但是当我运行它时,错误(未定义的变量 tw)像往常一样出现。它没有被抓住。

任何想法如何从 eval 中捕获解析错误?

【问题讨论】:

  • 我建议使用github.com/nikic/PHP-Parser 之类的东西,这将是一种更可控的方式(我认为)。
  • 需要指出的一点是,未定义的变量不是解析错误,而是运行时错误。这取决于 PHP 能够以各种奇怪的方式创建变量,在编译时不可能知道变量是否存在。解析错误就像缺少 = - $three $one . $tw;

标签: php


【解决方案1】:

您的代码无法按预期工作,因为在 PHP 中,未定义的变量不会触发解析错误,而是会触发通知。感谢set_error_handler 原生函数,您可以将通知转换为错误,然后使用以下 PHP 7 代码捕获它:

<?php

set_error_handler(function($_errno, $errstr) {
    // Convert notice, warning, etc. to error.
    throw new Error($errstr);
});

$one = "hello";
$two = " world";
$three = '';
$cmdstr = '$three = $one . $tw;';

try {
    $result = eval($cmdstr);
} catch (Throwable $e) {
    echo $e; // Error: Undefined variable: tw...
}

echo $three;

【讨论】:

  • 我相信将错误“转换”为异常的正确方法是使用throw new ErrorException(...),因为ErrorException 异常类型具有用于遗留错误的各种组件的字段。
【解决方案2】:

您的 PHP 代码会抛出“通知”类型的错误,并且这些错误无法由 try..catch 块处理。您必须使用 PHP 的 set_error_handler 方法使用自己的错误处理程序。阅读文档,您将了解该怎么做。如果你想要一个如何做的样本,那么:

<?php

function myErrorHandler($errno, $errstr)
{
    switch ($errno) {
        case E_USER_ERROR:
            die("User Error");
            break;
        default:
            die("Your own error");
            break;
    }

    /* Don't execute PHP internal error handler */
    return true;
}

$err = set_error_handler("myErrorhandler");

$one = "hello";
$two = " world";
$three = '';
$cmdstr = '$three = $one . $tw;';

$result = eval($cmdstr);

echo $three;

?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 2011-07-28
    • 2013-05-19
    • 2019-02-05
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多