检查字符串是否是有效的PHP代码

时间:2015-11-04 19:44:56

标签: php syntax-checking

我想这样做:

$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()

Related Question - 它已经老了,所以我希望有新的东西

Other Related Question - 不再支持所有选项(据我所知)或使用命令行或必须检查文件(不是字符串)

我不需要一个完整的编译器或任何东西。我只需要知道字符串是否是有效的PHP代码。

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

3 个答案:

答案 0 :(得分:5)

您可以将字符串传递给php -l并使用shell_exec调用它:

 Iterator<String> keys = jsonObject.keys();
 // get some_name_i_wont_know in str_Name
 String str_Name=keys.next(); 
 // get the value i care about
 String value = json.optString(str_Name);

刚才有了另一个想法......这次使用$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 -"; } ,但是安全:

test_code.php

eval

代码中的其他地方:

$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";

答案 1 :(得分:1)

离我头顶,这是最简单的。

top

我没有使用$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"); 的原因是:

  1. 已被弃用
  2. 它实际执行代码

答案 2 :(得分: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我们在其他地方没有不需要的输出。 肯定有点脏,但我能想出的最短。