【问题标题】:PHP - Check PHP Code for Syntax Errors without running the codePHP - 在不运行代码的情况下检查 PHP 代码的语法错误
【发布时间】:2012-08-14 01:28:23
【问题描述】:

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

无论如何,这就是我目前正在使用的......可以使用一些帮助,因为当 $content(这是 php 代码)中有一个函数时,我得到一个“不能重新定义函数”。

// 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();
}

【问题讨论】:

  • 您可以在“lint”模式下运行命令行php 解释器,以便在将 sn-p 存储在临时文件中后检查语法。例如exec("php -l checkfile.php.txt"); 可以返回No syntax errors detected in ...
  • 不,我正在通过 PHP 将代码输入文本区域,并希望它影响我网站上的页面。有时,我创建了一个函数:function doSomething($blah),但在执行此操作时它会执行两次......真的只需要在这里运行一次 eval......也许如果我为 eval() 函数设置了一个 php 变量???
  • eval 不仅仅用于代码检查。它立即运行。那么您不妨跳过该验证步骤。安全方面,无论如何它都是多余的。但是,如果您想在执行用户提供的代码之前断言代码正确性,那么有用户态 PHP 解析器。 (后者是有问题的部分。)
  • 你试过token_get_all()吗?这应该警告任何语法错误。
  • @ Jack - 如何使用 token_get_all() 检查语法错误?迷茫...

标签: php eval syntax-error


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:
    $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);
    }
    

    【讨论】:

    • 为什么你写\RuntimeException前面有一个`\`?这看起来像一个错误......
    • 感谢您的好回答。你应该在 $code_to_check 上使用 escapeshellarg,否则如果 php 中有任何单引号要检查,代码将失败。
    • ps:你知道 PHP 曾经有一个函数 php_check_syntax() 吗?它在 5.0.5 中被删除,因为它有错误 github.com/php/php-src/commit/…
    【解决方案3】:

    如果您查看 eval() 的 PHP 文档,这是描述:

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

    然而,PHP 文档本身说eval 是一个危险 构造: 小心

    eval() 语言结构非常危险,因为它允许 执行任意 PHP 代码。因此不鼓励使用它。如果你 已经仔细验证除了使用这个没有其他选择 构造,特别注意不要传递任何用户提供的数据 在没有事先正确验证的情况下进入它。

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

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

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

    如果你更喜欢使用 Sublime,这里有适合你的插件:

    我的观点是,这些工具的良好组合应该足以确保代码的完整性。

    -谢谢

    【讨论】:

      【解决方案4】:

      我在我的测试自动化中找到了一种一次检查所有 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>
      

      【讨论】:

        猜你喜欢
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        • 2011-07-13
        • 1970-01-01
        • 2010-09-17
        • 2016-08-11
        • 2013-01-11
        • 2022-10-07
        相关资源
        最近更新 更多