标签:this dna ref method manual private name meta 动态
bind为类的属性值赋值,无论是public或者protect,private。格式如下:
public static Closure::bind ( Closure $closure
, object $newthis
[, mixed $newscope
= ‘static‘ ] )
第一个参数为调用的匿名函数
第二个参数为绑定的类,就是指匿名函数中的$this
第三个参数为想要绑定给闭包的类作用域,或者 ‘static‘ 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。(关于这个参数没太搞懂,尝试了几次,传值就可以为私有变量赋值,不传就不可以。默认是static)
下面的例子是为一个实例的私有变量赋值:
1 class test { 2 private $a = 1; 3 } 4 5 $f = \Closure::bind(function () { 6 $this->a = 2; 7 return $this; 8 }, new test, test::class); 9 10 $o = $f(); 11 $o->w();
另外一种赋值形式(composer里这么写的),类似与灌入一下变量。因为不需要this,所以第二个变量设置为null就行了。
1 class test { 2 private $a = 1; 3 } 4 function b(test $o) { 5 return \Closure::bind(function () use ($o) { 6 $o->a = 2; 7 }, null, test::class); 8 } 9 10 $o = new test(); 11 call_user_func(b($o));
下面例子是官网中例子,动态加载function
1 With this class and method, it‘s possible to do nice things, like add methods on the fly to an object. 2 3 MetaTrait.php 4 <?php 5 trait MetaTrait 6 { 7 8 private $methods = array(); 9 10 public function addMethod($methodName, $methodCallable) 11 { 12 if (!is_callable($methodCallable)) { 13 throw new InvalidArgumentException(‘Second param must be callable‘); 14 } 15 $this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class()); 16 } 17 18 public function __call($methodName, array $args) 19 { 20 if (isset($this->methods[$methodName])) { 21 return call_user_func_array($this->methods[$methodName], $args); 22 } 23 24 throw RunTimeException(‘There is no method with the given name to call‘); 25 } 26 27 } 28 ?> 29 30 test.php 31 <?php 32 require ‘MetaTrait.php‘; 33 34 class HackThursday { 35 use MetaTrait; 36 37 private $dayOfWeek = ‘Thursday‘; 38 39 } 40 41 $test = new HackThursday(); 42 $test->addMethod(‘when‘, function () { 43 return $this->dayOfWeek; 44 }); 45 46 echo $test->when();
根据反射判断是否可绑定
<?php /** * @param \Closure $callable * * @return bool */ function isBindable(\Closure $callable) { $bindable = false; $reflectionFunction = new \ReflectionFunction($callable); if ( $reflectionFunction->getClosureScopeClass() === null || $reflectionFunction->getClosureThis() !== null ) { $bindable = true; } return $bindable; }
标签:this dna ref method manual private name meta 动态
原文地址:https://www.cnblogs.com/wangjianheng/p/12825001.html