Что я могу использовать вместо eval ()? - PullRequest
5 голосов
/ 16 августа 2010

У меня есть строка, в которой хранятся некоторые переменные, которые должны быть выполнены для получения результата, например:

define('RUN_THIS', '\$something.",".$somethingElse');

Что тогда eval() -uated:

$foo = eval("return ".RUN_THIS.";");

Я понимаю, что eval небезопасен, если вычисляемая строка взята из пользовательского ввода. Однако, если, например, я хотел, чтобы все работало на хип-хопе Facebook, который не поддерживает eval (), я бы не смог этого сделать.

Очевидно, я могу использовать call_user_func() - это фактически тот же результат, что и eval()? Как считается безопасным, когда eval() нет, если это действительно так?

Edit: В ответ на комментарии я изначально не дал понять, какова цель. Константа определяется заранее для того, чтобы последующий код, будь то внутри класса, который имеет доступ к константам конфигурации, или процедурный код, мог использовать ее для оценки заданной строки переменных. Переменные, которые должны быть оценены, могут различаться (абсолютно разные имена, порядок, форматирование) в зависимости от ситуации, но они выполняются для той же цели таким же образом, поэтому у меня в настоящее время строка переменных установлена ​​в постоянной путь. Технически, eval() небезопасен, пока config.php, который определяет константы, контролируется, но это не было вопросом вопроса.

Ответы [ 2 ]

2 голосов
/ 17 августа 2010

У Кендалла, кажется, есть простое решение , но я постараюсь ответить на другой ваш вопрос:

Очевидно, я могу использовать call_user_func () - действительно ли это тот же результат, что и eval ()? Как считается безопасным, когда eval () нет, если это действительно так?

call_user_func на самом деле на самом деле безопаснее, чем eval, поскольку call_user_func может вызывать только одну пользовательскую функцию. eval, с другой стороны, выполняет строку как сам код PHP. Вы можете добавить '; (закрыть строку и начать новую «строку» кода) в конце строки, а затем добавить еще немного кода, добавить ;' (завершить строку кода и начать другую строку так, чтобы нет синтаксической ошибки), что позволяет константе RUN_THIS содержать большое количество PHP-кода, который пользователь может запустить на сервере (включая удаление всех важных файлов, получение информации для баз данных и т. д.) НИКОГДА НЕ ДАВАЙТЕ ЭТОГО БЫТЬ .

call_user_func не позволяет его случиться. Когда вы запускаете call_user_func_array($func, $args), пользователь может запускать только ограниченный набор функций, потому что: (a) функция должна быть определена пользователем; (b) вы можете манипулировать $func, чтобы гарантировать, что пользователь не сможет запустить какую-либо функцию, которую он / она хочет, либо проверив, что $func находится в списке «разрешенных функций», либо добавив к имени функции что-то вроде user_ и саму переменную $func (таким образом, пользователь может запускать только функции, начинающиеся с user_.

1 голос
/ 17 августа 2010

Я не вижу причин, по которым вы не можете просто использовать построение строк в двойных кавычках.

$foo = "\$something,$somethingElse";
...