PHP 7.2 — Как создать анонимную функцию динамически, когда тело функции находится в строке

Как создать анонимную функцию динамически, когда у меня есть тело функции в строке.

Например,

$user = "John Doe";
$body = "echo 'Hello' . $user;";

$myFunct = function($user) {$body}; // How do I have function body here from string.

$myFunct($user);

Любая помощь приветствуется.

Постскриптум
Я ищу замену для функции create_function (), которая была в предыдущих версиях PHP. Как и в create_function (), где мы можем передать тело функции в виде строки, я бы хотел определить тело анонимной функции из строковой переменной.

9

Решение

Если вы изучили все другие варианты и абсолютно уверены, что единственный способ достичь ваших целей — это определить пользовательские функции во время выполнения, используя код в строке, у вас есть две альтернативы использованию create_function,

Быстрое решение — просто использовать eval:

function create_custom_function($arguments, $body) {
return eval("return function($arguments) { $body };");
}

$myFunct = create_custom_function('$user', 'echo "Hello " . $user;');

$myFunct('John Doe');
// Hello John Doe

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

function create_custom_function($arguments, $body) {
$tmp_file = tempnam(sys_get_temp_dir(), "ccf");
file_put_contents($tmp_file, "<?php return function($arguments) { $body };");
$function = include($tmp_file);
unlink($tmp_file);

return $function;
}

$myFunct = create_custom_function('$user', 'echo "Hello " . $user;');

$myFunct('John Doe');
// Hello John Doe

Честно говоря, я настоятельно рекомендую против этих подходов и предлагаю вам найти другой способ достичь своей цели. Если вы создаете пользовательский обфускатор кода, вам, вероятно, лучше создать расширение php, где код де-обфускацируется перед выполнением, аналогично тому, как работают ionCube Loader и Zend Guard Loader.

15

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

Вы можете использовать подсказку вызываемого типа. Вот пример

function callThatAnonFunction(callable $callback) {
return $callback();
}

Может принимать анонимную функцию с любыми параметрами arg:

$user = "person";
$location = "world";
callThatAnonFunction(function() use ($user, $location) {
echo "Hello " . $user . " in " . $location;
});
2

Вы можете попробовать это:

$user = "John Doe";
$body = "echo 'Hello' . $user;";

$myFunct = function($user) {
return $body;
};

echo $myFunct($user);
2

Ну, это уродливо, и вы не должны этого делать, но вы сказали в комментарии, что вы делаете это для обфускатора кода, так что вот мои 2 цента:

$args = '$user, $number';
$body = 'echo "#$number: Hello $user.\n";';

function _create_function_without_eval($args, $body) {
$func_name = sprintf('temp_func_%s', md5($body));
$code = sprintf("<?php if (!function_exists('%s')) {function %s(%s){%s}}", $func_name, $func_name, $args, $body);
$func_file = tempnam('/tmp', $func_name);
$handle = fopen($func_file, "w+");
fwrite($handle, $code);
fclose($handle);
include $func_file;
unlink($func_file);
return function(...$user_args) use ($func_name) {
return call_user_func_array($func_name, $user_args);
};
}

function _create_function_with_eval($args, $body) {
$func_name = sprintf('temp_func_%s', md5($body));
$code = sprintf("if (!function_exists('%s')) {function %s(%s){%s}}", $func_name, $func_name, $args, $body);
eval($code);
return function(...$user_args) use ($func_name) {
return call_user_func_array($func_name, $user_args);
};
}

$fn_deprecated = create_function($args, $body);
$fn_with_eval = _create_function_with_eval($args, $body);
$fn_without_eval = _create_function_without_eval($args, $body);

echo $fn_deprecated('Old Bob', '1');
echo $fn_without_eval('Bob without eval', 2);
echo $fn_with_eval('Bob with eval', 3);

Смотрите это в прямом эфире здесь: https://3v4l.org/urQ4k

2

PHP разработчики любят тебя, хахаха, посмотри здесь

$user = "John Doe";
$body = 'echo "Hello " . $a;';
$f = create_function('$a', $body);

$f($user);

//out : Hello John Doe

Документация PHP официальная: create_function(string $args,string $code)

-2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector