Я хочу делать:
$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";
будет действительным
Вы можете передать строку в 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;
}
Редактировать: только что увидел, что вы хотите воздержаться от использования exec ().
Я думаю, что без этого будет очень сложно, php удалил функцию check_syntax по какой-то причине.
Возможно (и я на самом деле просто догадываюсь, когда речь идет об усилиях, которые вы хотите инвестировать), запустить php -l в контейнере (в основном, в docker) и передать код через вызов http демону docker (просто команда run против стандартного php cli сделает это здесь). Тогда вы можете без проблем использовать что-то вроде приведенного ниже примера кода (при условии, что вы не даете никаких разрешений для вашего контейнера).
Вы можете использовать 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, мы не получаем нежелательный вывод в другом месте.
Все еще, конечно, немного грязный, но самый короткий, который я могу придумать.
С моей головы это проще всего.
$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
это потому что: