W3docs

eval()

Функция eval() в PHP выполняет строку как PHP-код во время выполнения. Узнайте синтаксис, возвращаемые значения, риски безопасности и альтернативы.

Введение в функцию eval()

Функция eval() выполняет строку как PHP-код во время выполнения — в момент, когда скрипт достигает вызова eval(). Вместо того чтобы писать код, который PHP-парсер компилирует заранее, вы передаёте eval() строку, которая компилируется и выполняется на лету.

Это делает eval() одной из самых мощных — и самых опасных — конструкций языка. На этой странице рассматриваются синтаксис, возвращаемые значения, редкие случаи, когда функция действительно полезна, риски безопасности, делающие её крайней мерой, и более безопасные альтернативы, к которым стоит обратиться в первую очередь.

eval() — это языковая конструкция, а не обычная функция. Её нельзя вызвать косвенно через имя переменной-функции или передать в функции обратного вызова.

Синтаксис

eval(string $code): mixed

Единственный аргумент — строка с PHP-кодом. Важно помнить несколько правил:

  • Не включайте открывающий тег <?php. Строка уже воспринимается как PHP-код, поэтому добавление <?php вернёт интерпретатор в «режим HTML».
  • Код должен быть синтаксически корректным и завершённым. Отсутствующая точка с запятой или несбалансированная скобка приведут к ошибке разбора. Начиная с PHP 7, ошибка разбора внутри eval() генерирует исключение ParseError, которое можно перехватить — в старых версиях возвращалось false.

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

Значение, возвращаемое eval(), зависит от того, что делает выполняемый код:

  • Если код содержит оператор return, eval() возвращает это значение.
  • В противном случае возвращается null.
<?php

$result = eval('return 2 + 3;');
echo $result; // 5

Именно поэтому return внутри eval() завершает выполняемую строку, а не весь скрипт — управление возвращается на строку после eval(). О поведении return в обычных функциях читайте в разделе оператор return.

Базовый пример

Вот простейший пример использования — формирование строки кода и её выполнение:

php— editable, runs on the server

Переменная $code содержит корректный PHP-код, выводящий Hello, world!. eval() компилирует и выполняет эту строку во время выполнения скрипта, отображая сообщение. Обратите внимание, что внутри строки нет тега <?php.

Безопасный перехват ошибок

Поскольку некорректный код генерирует ParseError, оберните недоверенный или сгенерированный код в блок try/catch, чтобы ошибочная строка не привела к краху всего запроса:

<?php

try {
    eval('echo "missing semicolon"'); // no terminating ;
} catch (ParseError $e) {
    echo "Could not evaluate: " . $e->getMessage();
}

Вместо фатальной ошибки будет выведено сообщение «Could not evaluate», и скрипт продолжит работу.

Когда стоит использовать eval()?

В современном PHP — почти никогда, и это честный ответ. Среди редких оправданных случаев:

  • Шаблонные/выражающие движки, которые компилируют пользовательский мини-язык в PHP-код (Twig и Blade делают нечто концептуально похожее, но с серьёзной изоляцией).
  • Кэширование скомпилированной конфигурации в виде PHP-кода для последующего выполнения через eval, хотя запись в реальный .php-файл и использование include — быстрее и безопаснее.
  • Образовательные или отладочные инструменты, например REPL, где входные данные полностью доверенные.

Если вычисляемое значение является данными (числами, JSON, списком параметров), eval() почти наверняка не нужен.

Риски безопасности

eval() выполняет всё, что ему передано. Если любая часть строки может быть подконтрольна пользователю, злоумышленник получит возможность выполнить произвольный код — читать файлы, удалять данные или захватить сервер. Это классическая уязвимость удалённого выполнения кода (RCE).

<?php

// NEVER do this:
$expr = $_GET['expr'];          // attacker-controlled
eval("\$answer = $expr;");      // attacker can inject any PHP

Запрос вида ?expr=1; system('rm -rf /') выполнит внедрённую команду. Любой вызов eval() с пользовательскими данными — это гарантированная уязвимость.

Более безопасные альтернативы

Прежде чем прибегать к eval(), убедитесь, что ни одна из следующих альтернатив не подходит:

ЗадачаИспользуйте вместо eval()
Разбор структурированных данныхjson_decode()
Вызов функции, выбранной во время выполненияCallback / переменные функции
Выполнение кода из файлаinclude / require
Сопоставление строки с поведениемmatch/switch или массив замыканий
Вычисление математических выраженийСпециализированная библиотека-парсер выражений

Заключение

eval() выполняет строку как PHP-код во время выполнения, возвращая результат оператора return внутри неё или null в противном случае. Это действительно мощный инструмент, но при этом один из главных источников уязвимостей — любые пользовательские данные, переданные в него, превращаются в ошибку удалённого выполнения кода. Используйте его только при полном доверии к входным данным и отсутствии подходящих встроенных конструкций, оборачивайте вызов в try/catch для перехвата ParseError и при любой возможности отдавайте предпочтение более безопасным альтернативам, описанным выше.

Практика

Практика
Какова цель функции eval() в PHP?
Какова цель функции eval() в PHP?
Was this page helpful?