проверка синтаксиса — Проверьте, является ли строка правильным кодом PHP

Я хочу делать:

$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"; будет действительным

1

Решение

Вы можете передать строку в 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;
}
5

Другие решения

Редактировать: только что увидел, что вы хотите воздержаться от использования 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, мы не получаем нежелательный вывод в другом месте.
Все еще, конечно, немного грязный, но самый короткий, который я могу придумать.

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. это на самом деле выполняет код
1
По вопросам рекламы [email protected]