PHP 7.2 - Как создать анонимную функцию динамически, когда тело функции находится в строке - PullRequest
0 голосов
/ 30 сентября 2018

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

Например,

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

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

$myFunct($user);

Любая помощь будет принята с благодарностью.

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

Ответы [ 6 ]

0 голосов
/ 11 июня 2019

Осторожно

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

, поэтому Eval - худшая замена, create_function - этоиз-за использования eval.

использование анонимных функций для adiinviter pro.

$b  = function () use ($d,$f1,$c,$ps){
            return gzinflate( base64_decode(str_rot13($ps) ) );
        };
0 голосов
/ 12 октября 2018

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)

0 голосов
/ 11 октября 2018

Ну, это уродливо, и вы не должны этого делать, но вы сказали в комментарии, что вы делаете это для обфускатора кода, поэтому вот мои 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

0 голосов
/ 11 октября 2018

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

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

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

echo $myFunct($user);
0 голосов
/ 11 октября 2018

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

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

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

$user = "person";
$location = "world";
callThatAnonFunction(function() use ($user, $location) {
    echo "Hello " . $user . " in " . $location;
});
0 голосов
/ 07 октября 2018

Если вы изучили все другие варианты и абсолютно уверены, что единственный способ достичь ваших целей - это определить пользовательские функции во время выполнения, используя код в строке, у вас есть две альтернативы использованию 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.

...