PHP 8.3.7 Released!

eval

(PHP 4, PHP 5, PHP 7, PHP 8)

evalРасценивает строку как PHP-код и выполняет его

Описание

eval(string $code): mixed

Выполняет переданную в параметре code строку как код PHP.

Выполняемый код наследует ту же область видимости переменной, что и строка, на которой языковая конструкция eval() была вызвана. Любые доступные на этой строке переменные будут доступны для чтения и изменения в выполняемом коде. Однако все объявленные в этом коде функции и классы получат глобальную область видимости. Говоря по-другому, компилятор расценит выполняемый код так, как если бы это был подключёный файл.

Предостережение

Языковая конструкция eval() может быть очень опасной, поскольку может выполнять произвольный код. Поэтому от работы с ней воздерживаются. Если тщательный поиск других решений показал, что альтернативы нет, внимательно проверяют, чтобы в неё не передавались пользовательские данные без их правильной предварительной проверки.

Список параметров

code

Выполняемая строка кода PHP.

Код не должен быть обёрнут открывающимся и закрывающимся тегами PHP, то есть строка должна быть, например, такой: 'echo "Привет!";', но не такой '<?php echo "Привет!"; >'. Можно переключаться между режимами PHP- и HTML-кода, например: 'echo "Код PHP!"; ?>Код HTML<?php echo "Снова код PHP!";'.

Передаваемый код должен быть верным выполняемым кодом PHP. Это значит, что операторы должны быть разделены точкой с запятой (;). При выполнении строки 'echo "Привет!"' будет сгенерирована ошибка, а строка 'echo "Привет!";' будет успешно выполнена.

Указание в строке кода ключевого слова return прекращает выполнение.

Код из строки будет выполнен в той области видимости, в которой вызвана конструкция eval(). Поэтому переменные, которые определены или изменены в ней, сохранят видимость после завершения вызова конструкции eval().

Возвращаемые значения

Языковая конструкция eval() возвращает значение null, или значение, которое вернул вызванный в выполняемом коде оператор return. Начиная с PHP 7, если в выполняемом коде присутствует ошибка, то конструкция eval() вызывает исключение "ParseError". До PHP 7 в таких случаях возвращалось логическое значение false и продолжалось нормальное выполнение последующего кода. Невозможно поймать ошибку парсера в конструкции eval() функцией set_error_handler().

Примеры

Пример #1 Пример функции eval() — простое слияние текста

<?php
$string
= 'чашка';
$name = 'кофе';
$str = 'Это $string с моим $name.';
echo
$str. "\n";
eval(
"\$str = \"$str\";");
echo
$str. "\n";
?>

Результат выполнения приведённого примера:

Это $string с моим $name.
Это чашка с моим кофе.

Примечания

Замечание: Поскольку это языковая конструкция, а не функция, её нельзя вызывать как переменную функцию или передавать как именованный аргумент.

Подсказка

Как и всё, что выводит результат в браузер, функции контроля вывода можно вызывать, чтобы перехватить выводимые этой функцией данные и сохранять их, например в строку (string).

Замечание:

В случае фатальной ошибки в выполняемом коде прекращается выполнение всего скрипта.

Смотрите также

  • call_user_func() - Вызывает callback-функцию, заданную в первом параметре

add a note

User Contributed Notes 7 notes

up
468
Anonymous
19 years ago
Kepp the following Quote in mind:

If eval() is the answer, you're almost certainly asking the
wrong question. -- Rasmus Lerdorf, BDFL of PHP
up
43
lord dot dracon at gmail dot com
8 years ago
Inception with eval()

<pre>
Inception Start:
<?php
eval("echo 'Inception lvl 1...\n'; eval('echo \"Inception lvl 2...\n\"; eval(\"echo \'Inception lvl 3...\n\'; eval(\'echo \\\"Limbo!\\\";\');\");');");
?>
up
22
Jeremie LEGRAND
6 years ago
At least in PHP 7.1+, eval() terminates the script if the evaluated code generate a fatal error. For example:
<?php
@eval('$content = (100 - );');
?>

(Even if it is in the man, I'm note sure it acted like this in 5.6, but whatever)
To catch it, I had to do:
<?php
try {
eval(
'$content = (100 - );');
} catch (
Throwable $t) {
$content = null;
}
?>

This is the only way I found to catch the error and hide the fact there was one.
up
8
catgirl at charuru dot moe
6 years ago
It should be noted that imported namespaces are not available in eval.
up
24
bohwaz
12 years ago
If you want to allow math input and make sure that the input is proper mathematics and not some hacking code, you can try this:

<?php

$test
= '2+3*pi';

// Remove whitespaces
$test = preg_replace('/\s+/', '', $test);

$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functions = '(?:sinh?|cosh?|tanh?|abs|acosh?|asinh?|atanh?|exp|log10|deg2rad|rad2deg|sqrt|ceil|floor|round)'; // Allowed PHP functions
$operators = '[+\/*\^%-]'; // Allowed math operators
$regexp = '/^(('.$number.'|'.$functions.'\s*\((?1)+\)|\((?1)+\))(?:'.$operators.'(?2))?)+$/'; // Final regexp, heavily using recursive patterns

if (preg_match($regexp, $q))
{
$test = preg_replace('!pi|π!', 'pi()', $test); // Replace pi with pi function
eval('$result = '.$test.';');
}
else
{
$result = false;
}

?>

I can't guarantee you absolutely that this will block every possible malicious code nor that it will block malformed code, but that's better than the matheval function below which will allow malformed code like '2+2+' which will throw an error.
up
3
divinity76 at gmail dot com
6 years ago
imo, this is a better eval replacement:

<?php
function betterEval($code) {
$tmp = tmpfile ();
$tmpf = stream_get_meta_data ( $tmp );
$tmpf = $tmpf ['uri'];
fwrite ( $tmp, $code );
$ret = include ($tmpf);
fclose ( $tmp );
return
$ret;
}
?>

- why? betterEval follows normal php opening and closing tag conventions, there's no need to strip `<?php?>` from the source. and it always throws a ParseError if there was a parse error, instead of returning false (note: this was fixed for normal eval() in php 7.0). - and there's also something about exception backtraces
up
6
darkhogg (foo) gmail (bar) com
14 years ago
The following code

<?php
eval( '?> foo <?php' );
?>

does not throw any error, but prints the opening tag.
Adding a space after the open tag fixes it:

<?php
eval( '?> foo <?php ' );
?>
To Top