有收获的话请加颗小星星,没有收获的话能够 反对 没有帮助 举报三连php
匿名函数(Anonymous functions),也叫闭包函数(closures),容许 临时建立一个没有指定名称的函数。最常常用做回调函数(callback)参数的值。固然,也有其它应用的状况。git
匿名函数目前是经过 Closure 类来实现的。github
$rs = preg_replace_callback('/-([a-z])/', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
dump($rs); // "helloWorld"
复制代码
$greet = function ($name) {
dump($name);
};
dump($greet instanceof Closure); // true
$greet('PHP'); // "PHP"
复制代码
$message = 'hello';
$example = function () use ($message) {
dump($message);
};
dump($example instanceof Closure); // true
$example(); // "hello"
复制代码
call_user_func_array()
和call_user_func()
方法function call_user_func (parameter) {}数组
该方法接收多个参数,第一个就是回调函数,能够是普通函数
,也能够是闭包函数
,后面的多个参数
都是做为函数回调使用闭包
$rs = call_user_func(function (...$params) {
return func_get_args();
}, 1, 2, 3);
dump($rs); // [1,2,3]
复制代码
function call_user_func_array (param_arr) {}函数
该方法接收2个参数,第一个就是回调函数,能够是普通函数
,也能够是闭包函数
,后面的数组参数
都是做为函数回调使用测试
$rs = call_user_func_array(function (array $params) {
return func_get_args();
}, [1, 2, 3]);
dump($rs); // [1,2,3]
复制代码
楼主看法是将方法绑定到指定类上,使得方法也可使用类的属性和方法,很是适合配合__call()
魔术方法和call_user_func_array
方法一块儿使用ui
function bindTo(newscope = 'static') { }this
<?php
namespace PHP\Demo\Closure;
class ClosureBindTo {
public function __call($name, $arguments) {
if (count($arguments) > 1 && $arguments[0] instanceof \Closure) {
return call_user_func_array($arguments[0]->bindTo($this), array_slice($arguments, 1));
}
throw new \InvalidArgumentException("没有这个方法");
}
}
// 测试
public function testClosureBindTo() {
$obj = new ClosureBindTo();
$this->assertEquals(2, $obj->add(function (array $params) {
return ++$params[0];
}, [1]));
// 测试同一个实例
$newObj = $obj->test(function (array $params){
return $this;
}, [1]);
$this->assertTrue($newObj instanceof $obj);
}
复制代码
static function bind(Closure newthis, $newscope = 'static') { }spa
bind函数是bindTo的静态表示
<?php
namespace PHP\Demo\Closure;
class ClosureBind {
private $methods = [];
public function addMethod(string $name, \Closure $callback) {
if (!is_callable($callback)) {
throw new \InvalidArgumentException("第二个参数有误");
}
$this->methods[$name] = \Closure::bind($callback, $this, get_class());
}
public function __call(string $name, array $arguments) {
if (isset($this->methods[$name])) {
return call_user_func_array($this->methods[$name], $arguments);
}
throw new \RuntimeException("不存在方法[{$name}]");
}
}
// 测试
public function testClosureBind() {
$obj = new ClosureBind();
$obj->addMethod('add', function (array $params) {
return ++$params[0];
});
$this->assertEquals(2, $obj->add([1]));
// 测试同一个实例
$obj->addMethod('test', function (array $params) {
return $this;
});
$this->assertTrue($obj->test([1]) instanceof $obj);
}
复制代码