Как создать анонимную функцию динамически, когда у меня есть тело функции в строке.
Например,
$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 (), где мы можем передать тело функции в виде строки, я бы хотел определить тело анонимной функции из строковой переменной.
Если вы изучили все другие варианты и абсолютно уверены, что единственный способ достичь ваших целей — это определить пользовательские функции во время выполнения, используя код в строке, у вас есть две альтернативы использованию 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.
Вы можете использовать подсказку вызываемого типа. Вот пример
function callThatAnonFunction(callable $callback) {
return $callback();
}
Может принимать анонимную функцию с любыми параметрами arg:
$user = "person";
$location = "world";
callThatAnonFunction(function() use ($user, $location) {
echo "Hello " . $user . " in " . $location;
});
Вы можете попробовать это:
$user = "John Doe";
$body = "echo 'Hello' . $user;";
$myFunct = function($user) {
return $body;
};
echo $myFunct($user);
Ну, это уродливо, и вы не должны этого делать, но вы сказали в комментарии, что вы делаете это для обфускатора кода, так что вот мои 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
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)