博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过几个栗子认识 PHP 闭包
阅读量:6372 次
发布时间:2019-06-23

本文共 2819 字,大约阅读时间需要 9 分钟。

<!-- TOC -->

<!-- /TOC -->

有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连

  • 本人能力有限,如遇到什么不对的地方还望指出修正,谢谢
  • 所有栗子的输出都使用symfony/var-dumpe美化了

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。

匿名函数目前是通过 Closure 类来实现的。

一、栗子1 用作于回调

$rs = preg_replace_callback('/-([a-z])/', function ($match) {    return strtoupper($match[1]);}, 'hello-world');dump($rs); // "helloWorld"

二、栗子2 用作于变量赋值

$greet = function ($name) {    dump($name);};dump($greet instanceof Closure); // true$greet('PHP'); // "PHP"

三、栗子3 从父作用域继承变量

$message = 'hello';$example = function () use ($message) {    dump($message);};dump($example instanceof Closure); // true$example(); // "hello"

四、栗子4的前提条件,简单理解call_user_func_array()call_user_func()方法

1. call_user_func — 把第一个参数作为回调函数调用

function call_user_func ($function, ...$parameter) {}

该方法接收多个参数,第一个就是回调函数,可以是普通函数,也可以是闭包函数,后面的多个参数都是作为函数回调使用

$rs = call_user_func(function (...$params) {    return func_get_args();}, 1, 2, 3);dump($rs); // [1,2,3]

2. call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数

function call_user_func_array ($function, array $param_arr) {}

该方法接收2个参数,第一个就是回调函数,可以是普通函数,也可以是闭包函数,后面的数组参数都是作为函数回调使用

$rs = call_user_func_array(function (array $params) {    return func_get_args();}, [1, 2, 3]);dump($rs); // [1,2,3]

五、栗子4 绑定闭包在指定对象

楼主见解是将方法绑定到指定类上,使得方法也可以使用类的属性和方法,非常适合配合__call()魔术方法和call_user_func_array方法一起使用

1. Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。

function bindTo($newthis, $newscope = 'static') { }

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);}

2. Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。

static function bind(Closure $closure, $newthis, $newscope = 'static') { }

bind函数是bindTo的静态表示

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);}

六、参考资料

转载地址:http://wiyqa.baihongyu.com/

你可能感兴趣的文章
springboot 没有跳转到指定页面
查看>>
NSNumber 与NSValue
查看>>
php中urlencode和urldecode的用法
查看>>
Flutter & Dart 安装在window系统
查看>>
uwp - 上滑隐藏导航栏下滑显示
查看>>
sitecore系列教程之如何以编程方式将访客数据关联到联系人卡片
查看>>
如何修改DEDECMS文章标题长度
查看>>
工控随笔_14_西门子_Step7项目:打开项目不可用解决方法
查看>>
Python-定时爬取指定城市天气(一)-发送给关心的微信好友
查看>>
请不要怪罪流程
查看>>
csharp: Socket
查看>>
转 码农提高工作效率
查看>>
Maven实战(七)——常用Maven插件介绍(上)
查看>>
Web优化 页面性能优化 自定义函数延迟触发 jquery插件
查看>>
STL中map用法详解 (转)
查看>>
xampp中apache不能启动解决方法 (share)
查看>>
Visual Studio Xamarin编译Android项目出错的解决办法
查看>>
CP,SCP 命令(包括windows与linux用xshell互传)
查看>>
[转]TypeScript Quick start
查看>>
[转]Global exception handling in Web API 2.1 and NLog
查看>>