How to add a new method to a php object on the fly?

后端 未结 9 2130
星月不相逢
星月不相逢 2020-11-28 04:03

How do I add a new method to an object \"on the fly\"?

$me= new stdClass;
$me->doSomething=function ()
 {
    echo \'I\\\'ve done something\';
 };
$me->         


        
相关标签:
9条回答
  • 2020-11-28 04:33

    You can harness __call for this:

    class Foo
    {
        public function __call($method, $args)
        {
            if (isset($this->$method)) {
                $func = $this->$method;
                return call_user_func_array($func, $args);
            }
        }
    }
    
    $foo = new Foo();
    $foo->bar = function () { echo "Hello, this function is added at runtime"; };
    $foo->bar();
    
    0 讨论(0)
  • 2020-11-28 04:33

    karim79 answer works however it stores anonymous functions inside method properties and his declarations can overwrite existing properties of same name or does not work if existing property is private causing fatal error object unusable i think storing them in separate array and using setter is cleaner solution. method injector setter can be added to every object automatically using traits.

    P.S. Of course this is hack that should not be used as it violates open closed principle of SOLID.

    class MyClass {
    
        //create array to store all injected methods
        private $anon_methods = array();
    
        //create setter to fill array with injected methods on runtime
        public function inject_method($name, $method) {
            $this->anon_methods[$name] = $method;
        }
    
        //runs when calling non existent or private methods from object instance
        public function __call($name, $args) {
            if ( key_exists($name, $this->anon_methods) ) {
                call_user_func_array($this->anon_methods[$name], $args);
            }
        }
    
    }
    
    
    $MyClass = new MyClass;
    
    //method one
    $print_txt = function ($text) {
        echo $text . PHP_EOL;
    };
    
    $MyClass->inject_method("print_txt", $print_txt);
    
    //method
    $add_numbers = function ($n, $e) {
        echo "$n + $e = " . ($n + $e);
    };
    
    $MyClass->inject_method("add_numbers", $add_numbers);
    
    
    //Use injected methods
    $MyClass->print_txt("Hello World");
    $MyClass->add_numbers(5, 10);
    
    0 讨论(0)
  • 2020-11-28 04:39

    With PHP 7 you can use anonymous classes, which eliminates the stdClass limitation.

    $myObject = new class {
        public function myFunction(){}
    };
    
    $myObject->myFunction();
    

    PHP RFC: Anonymous Classes

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