PHP - 在不运行代码的情况下检查PHP代码的语法错误

时间:2012-08-14 01:28:24

标签: php eval syntax-error

我知道通过使用eval($code_to_check);,我们可以检查此值是否等于FALSE,如果是,我们可以停止执行脚本。但是,我面临的问题是我无法定义一个函数,因为它被调用了两次......它通过eval()检查进行处理,以确保没有语法错误,并且再次处理该函数,但是显示一个错误,表明它不能REDECLARE这个函数,因为它已经在eval'd函数中声明了。我怎样才能这样做,以便我们不在EVAL'd函数中声明事物,或者,我们可以在我们实际调用它之前取消声明在eval()函数中声明的所有内容...

无论如何,到目前为止,这是我正在使用的...可以使用一些帮助,因为当$ content(这是php代码)中有一个函数时,我得到一个“无法重写功能”。< / p>

// PHP Syntax errors?
if (!@eval('return true;' . $content))
{
    // Error found in PHP somewhere.  Call error function and return out of here!
    call_user_func_array($code_error['function'], $code_error['params']);
    return;
}
else
{
    ob_start();

    eval($content);
    $code = ob_get_contents();
    ob_end_clean();
}

有人可以帮我吗?谢谢你们,你们在这里非常有帮助!你们都应得到一个金牌,但我相信奥运会现在结束了,这还不是一项运动......


好的,我在这里尝试自己的答案,并想知道这是否仍会捕获错误并允许同时创建函数而不调用这些函数两次。这是一个正确的方法吗?谁能在这段代码中看到任何可能的问题?如果没有检测到语法错误,我正在回显$ eval_code ...这样可以吗?

$eval_code = @eval($content);
// PHP Syntax errors?
if ($eval_code === FALSE)
{
    call_user_func_array($code_error['function'], $code_error['params']);
    return;
}
else
{
    ob_start();
    echo $eval_code;
    $code = ob_get_contents();
    ob_end_clean();
}

4 个答案:

答案 0 :(得分:4)

$checkResult = exec('echo \'<?php ' . escapeshellarg($code_to_check) . '\' | php -l >/dev/null 2>&1; echo $?');
if ($checkResult != 0) {
    throw new \RuntimeException("Invalid php");
} else {
   $result = eval($code_to_check);
}

答案 1 :(得分:1)

您还可以使用新的但非常受欢迎且稳定的工具PHPStan进行此类检查。

在这里,您可以阅读a short and simple tutorial, how to use it

答案 2 :(得分:0)

如果您查看eval()的PHP文档,则为以下描述:

  

eval - 将字符串评估为PHP代码

但是,PHP文档本身表示eval是一个危险的构造: 注意

  

eval()语言结构非常危险,因为它允许   执行任意PHP代码。因此不鼓励使用它。如果你   仔细确认除了使用它之外别无选择   构建时,要特别注意不要传递任何用户提供的数据   没有事先正确验证它就进入它。

所以,使用eval时要小心,非常小心。现在回到你的问题。

我认为您需要的是一个可以帮助您进行语法检查以检测违反已定义编码标准的工具。我使用ESLint来检查Javascript代码中的违规行为。对于PHP,我使用PHPStorm和Sublime Text,我使用PHP Lint和PHPCS。而不是做eval,我建议你使用这些工具中的一个或这些工具的组合来实现你的目标。

如果您使用的是Jetbrains PHPStorm,可以在这里找到这些插件:

如果您更喜欢使用Sublime,可以使用以下插件:

我的观点是,这些工具的良好组合应足以确保您的代码的健全性。

-Thanks

答案 3 :(得分:0)

我找到了一种在自动化测试中一次检查所有PHP文件语法的方法。如果您的php文件仅包含函数和数据,则可以使用它(如果不包含参数,则不执行任何不需要的操作)。

我得到了我的php文件的列表,并生成了一个html页面,其中每个php文件一个iframe 。我有自定义PHP错误处理程序,将所有错误放入数据库,因此足以将文件包含在IFrame中。如果有错误(包括语法错误),它将被记录。

main.php<br/>
<iframe id='frm_main.php' src='test_automation.php?CMD=CheckSyntaxPHP&PHP_FILE=main.php'>main.php</iframe><br/><br/>
second.php<br/>
<iframe id='frm_second.php' src='test_automation.php?CMD=CheckSyntaxPHP&PHP_FILE=second.php'>second.php</iframe><br/><br/>

在命令CMD = CheckSyntaxPHP上的test_automation.php只是检查文件的扩展名和存在性,并包括所请求的php文件。

我使用相同的原理检查我所有 javascript文件的语法-每个JS文件的 IFrame 。 CMD = CheckSyntaxJS创建一个带有两个JavaScript块的html文件:

javascript的第一块仅定义了一个javascript错误处理程序,将所有错误发送到我的网站,这会将它们记录到数据库中。 (必须在单独的块中,以便JS中的语法错误不会阻止错误处理程序调用。)

javascript的第二个块包含从当前检查的JS文件加载的文本。

<html>
<head>
<script type='text/javascript'>
function MyOwn_OnError(msg, url, lineNo, columnNo, error)
{ // do your error handling here, show or log the error
  var sError="Error: "+error+" in "+url; // build your own error message
  sError=encodeURIComponent(sError);
  var oReq = new XMLHttpRequest();
  if (bShowToUser) // define the handlers showing success if necessary
    { oReq.addEventListener("load", MyOwn_OnError_TransferComplete);
      oReq.addEventListener("error", MyOwn_OnError_TransferFailed);
      oReq.addEventListener("abort", MyOwn_OnError_TransferCanceled);
    }
  oReq.open("GET", "https://www.yourwebpage.com/ErrorHandlerJS?ErrMsg="+sError);
  oReq.send();
// and show something about sending the error to the user in the html page if needed
}
window.onerror=MyOwn_OnError;
</script>
<script type='text/javascript'>
// and here is the content of your javascript file
</script>
</head>
<body>
</body>
</html>