2

我想要做:

$str = "<? echo 'abcd'; ?>";
if (is_valid_php($str)){
   echo "{$str} is valid";
} else {
   echo "{$str} is not valid PHP code";
}

有没有简单的is_valid_php检查方法?

我能找到的只是在线 php 语法检查器和检查语法的命令行方法,或者php_check_syntax仅适用于文件,我不想写入文件来检查字符串是否有效。

我宁愿不使用system()/exec()eval()

相关问题- 它很旧,所以我希望有新的东西

其他相关问题- 所有选项(据我所知)要么不再受支持,要么使用命令行,要么必须检查文件(不是字符串)

我不需要成熟的编译器或任何东西。我实际上只需要知道字符串是否是有效的 PHP 代码。

编辑:通过有效的 php 代码,我的意思是它可以被执行,没有编译器/语法错误,并且应该只包含 PHP 代码。它可能有运行时错误并且仍然有效,例如$y = 33/0;. 并且它应该只包含 PHP... 例如,<div>stuff</div><? echo "str"; ?>将是无效的,但<? echo "str"; ?>echo "$str";是有效的

4

3 回答 3

7

您可以将字符串通过管道传输到 php -l 并使用 shell_exec 调用它:

$str1 = "<?php echo 'hello world';";
$str2 = "<?php echo 'hello world'";
echo isValidPHP($str1) ? "Valid" : "Invalid"; //Valid
echo isValidPHP($str2) ? "Valid" : "Invalid"; //Inalid

function isValidPHP($str) {
    return trim(shell_exec("echo " . escapeshellarg($str) . " | php -l")) == "No syntax errors detected in -";
}

刚刚有了另一个想法......这次使用eval但安全:

test_code.php

$code = "return; " . $_GET['code'];
//eval is safe here because it won't do anything
//since the first thing we do is return
//but we still get parse errors if it's not valid
//If that happens, it will crash the whole script, 
//so we need it to be in a separate request
eval($code); 
return "1";

代码中的其他地方:

echo isValidPHP("<?php echo \"It works!\";");

function isValidPHP($code) {
    $valid = file_get_contents("http://www.yoursite.com/test_code.php?" . http_build_query(['code' => $code]));
    return !!$valid;
}
于 2015-11-04T20:08:38.753 回答
1

编辑:刚刚看到您想避免使用 exec()。我认为如果没有它,这将非常困难,php 删除了 check_syntax 函数是有原因的。也许(当涉及到你想要投入的努力时,我真的只是在这里猜测)在容器中运行 php -l(这些天几乎是 docker )并通过 http 调用将代码传递给 docker 守护进程(只是一个针对标准 php cli 运行命令会在这里执行)。然后你可以不用担心使用下面的代码示例(前提是你没有给你的容器 obv 任何权限)。

您可以像这样使用 exec 和 php 命令行:

$ret = exec( 'echo "<?php echo \"bla\";" | php -l 2> /dev/null' );

echo strpos( $ret, 'Errors parsing' ) !== false ? "\nerror" : "\nno error";

$ret = exec( 'echo "<?php eccho \"bla\";" | php -l 2> /dev/null' );

echo strpos( $ret, 'Errors parsing' ) !== false ? "\nerror" : "\nno error";

返回:

no error
error

由于管道输出,不需要文件。同样使用重定向到 dev null 我们在其他地方没有不需要的输出。仍然肯定有点脏,但我能想到的最短。

于 2015-11-04T20:18:50.103 回答
1

在我看来,这是最简单的。

$str = "<? echo 'abcd'; ?>";
file_put_contents("/some/temp/path", $str);
exec("php -l /some/temp/path", $output, $result);
if ($result == 0){
   echo "{$str} is valid";
} else {
   echo "{$str} is not valid PHP code";
}
unlink("/some/temp/path");

我没有使用的原因php_check_syntax是:

  1. 它已被弃用
  2. 它实际上执行代码
于 2015-11-04T20:09:48.923 回答