Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 7.2 - How to create anonymous function dynamically when having function body in a string

How do I create an anonymous function dynamically when I have function body in a string.

For e.g.

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

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

$myFunct($user);

Any help would be much appreciated.

P.S. I'm looking for a replacement for create_function() functionality which was there in prior versions of PHP. Just like in create_function() where we could pass the function body as a string, I would like to define anonymous function's body off the string variable.

like image 701
Aditya Hajare Avatar asked Sep 30 '18 15:09

Aditya Hajare


3 Answers

If you have explored all other options and are absolutely sure the only way to accomplish your goals is to define custom functions at runtime using code that's in a string, you have two alternatives to using create_function.

The quick solution is to just use 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

However, eval() can be disabled. If you need this sort of functionality even on servers where eval is not available, you can use the poor man's eval: write the function to a temporary file and then include it:

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

In all honesty though, I strongly recommend against these approaches and suggest you find some other way to accomplish your goal. If you're building a custom code obfuscator, you're probably better off creating a php extension where the code is de-obfuscated prior to execution, similar to how ionCube Loader and Zend Guard Loader work.

like image 89
rickdenhaan Avatar answered Oct 29 '22 23:10

rickdenhaan


You can use the callable type hint. Here is an example

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

It can take an anonymous function with any arg params:

$user = "person";
$location = "world";
callThatAnonFunction(function() use ($user, $location) {
    echo "Hello " . $user . " in " . $location;
});
like image 2
Alaa Awad Avatar answered Oct 29 '22 23:10

Alaa Awad


You can try this:

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

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

echo $myFunct($user);
like image 2
gauri Avatar answered Oct 30 '22 00:10

gauri