网上查了一下给 PHP 类动态添加方法需要类中自带__call 魔术方法
如果类 class A{}
就这样 那怎么动态添加方法呢
支持这样:
$a=new A;
$a->test=function(){};
$a->test();
1
Jakesoft 2016-12-01 17:47:00 +08:00
call_user_func($m->test);
|
2
ParallelMao 2016-12-01 17:59:30 +08:00 1
|
3
RH 2016-12-01 19:08:47 +08:00
|
4
greatonce 2016-12-01 19:57:56 +08:00
class Test{
public $_methodContainer = []; public function __call($method,$value) { if(isset($this->_methodContainer[$method])) { return call_user_func_array($this->_methodContainer[$method], $value); } throw new Exception("The specify method cannot be found", 1); } } // define a new method. function newMethod($s) {return $s.'hello world';} $test = new Test; $test->_methodContainer['test'] = 'newMethod'; echo $t->test('你好 '); |
5
feiyuanqiu 2016-12-01 20:27:05 +08:00
class Test
{ private $dynamicMethods = []; public function __get($name) { return isset($this->dynamicMethods[ $name ]) ? $this->dynamicMethods[ $name ] : null; } public function __set($name, $value) { if ($this->isClosure($value)) { $this->dynamicMethods[ $name ] = Closure::bind($value, $this, self::class);; } } private function isClosure($value) { return is_callable($value) && get_class($value) === \Closure::class; } public function __isset($name) { return isset($this->dynamicMethods[ $name ]); } public function __call($name, $arguments) { if (!isset($this->dynamicMethods[ $name ])) { trigger_error('Call to undefined method ' . self::class . "::{$name}", E_USER_ERROR); } return call_user_func($this->dynamicMethods[ $name ], $arguments); } } $a = new Test(); $a->test = function () { var_dump($this->dynamicMethods); }; $a->test(); |
6
niuoh OP 找到正解了 我的意思是 class A{} 类里什么都没有也支持动态添加类方法 且支持$a->test();这样调用
方法如下: class merge_objs{ private $classArr = array(); function __construct() { $this -> classArr = func_get_args(); } function __get($s) { foreach($this-> classArr as $c) { if (property_exists($c, $s)) { return $c -> $s; } } } function __call($fn,$args) { foreach($this-> classArr as $c) { if (method_exists($c, $fn)) { return call_user_func_array(array($c,$fn),$args); } } } } class A{} class B{ public function test(){ echo test; } } $a=new merge_objs(new A,new B); $a->test(); |
7
v2song 2016-12-02 11:50:43 +08:00
可以学习一下 Laravel Macroable 的思想
```php class Test { use Macroable; } Test::macro('say', function ($word) { echo $word; }); $test = new Test(); $test->say('hello'); ``` |
8
zhaohehe 2016-12-30 17:12:19 +08:00
$a = new A;
$b = function(){ //... }; $b->call($a); php7 的用法,匿名函数的 call() |