How can I create a function dynamically?

后端 未结 5 1424
独厮守ぢ
独厮守ぢ 2020-12-31 05:28

I have a variable like $string = \"blah\";

How can I create a function that has the variable value as name? Is this possible in PHP?

Like

相关标签:
5条回答
  • 2020-12-31 05:40

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

    $string = "blah";
    $args = "args"
    $string = 'function ' . $string . "({$args}) { ... }";
    eval($string);
    
    0 讨论(0)
  • 2020-12-31 05:41

    You can call a function by its name stored in a variable, and you can also assign a function to variables and call it using the variable. If it's not what you want, please explain more.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-31 05:53

    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);
    ?>
    
    0 讨论(0)
  • Try call_user_func_array()

    php.net link

    0 讨论(0)
提交回复
热议问题