How can I create a function dynamically?

Okay, challenge accepted!

No matter how weird the question is (it's not btw), let's take it seriously for a moment! It could be useful to have a class that can declare functions and make them real:

<?php

customFunctions::add("hello",                 // prepare function "hello"

    function($what) {
        print "Hello $what, as Ritchie said";
        print "<br>";
    }

);

customFunctions::add("goodbye",               // prepare function "goodbye"

    function($what,$when) {
        print "Goodbye cruel $what, ";
        print "I'm leaving you $when";
        print "<br>";
    }

);

eval(customFunctions::make());                // inevitable - but it's safe!

That's it! Now they're real functions. No $-prefixing, no runtime evaluations whenever they get called - eval() was only needed once, for declaration. After that, they work like any function.

Let's try them:

    hello('World');                 // "Hello World"
    goodbye('world','today');       // "Goodbye cruel world, I'm leaving you today" 

Magic behind

Here's the class that can do this. Really not a complex one:

class customFunctions {

    private static $store = [];
    private static $maker = "";
    private static $declaration = '
        function %s() {
            return call_user_func_array(
                %s::get(__FUNCTION__),
                func_get_args()
            );
        }
    ';

    private static function safeName($name) {
        // extra safety against bad function names
        $name = preg_replace('/[^a-zA-Z0-9_]/',"",$name);
        $name = substr($name,0,64);
        return $name;
    }

    public static function add($name,$func) {
        // prepares a new function for make()
        $name = self::safeName($name);
        self::$store[$name] = $func;
        self::$maker.=sprintf(self::$declaration,$name,__CLASS__);
    }

    public static function get($name) {  
        // returns a stored callable
        return self::$store[$name];
    }

    public static function make() {  
        // returns a string with all declarations
        return self::$maker;
    }

}

It provides an inner storage for your functions, and then declare "real" functions that call them. This is something similar to fardjad's solution, but with real code (not strings) and therefore a lot more convenient & readable.


this might not be a good idea, but you can do something like this:

$string = "blah";
$args = "args"
$string = 'function ' . $string . "({$args}) { ... }";
eval($string);

That doesn't sound like a great design choice, it might be worth rethinking it, but...

If you're using PHP 5.3 you could use an anonymous function.

<?php
$functionName = "doStuff";
$$functionName = function($args) {
    // Do stuff
};

$args = array();
$doStuff($args);
?>

Tags:

Php

Function