今天写了一篇文章介绍PHP的闭包。从5.3版本开始,PHP增加了对匿名函数的支持。经过数次迭代,到现在的PHP5.6和PHP7,PHP语言的封闭性已经非常完善。结合Swoole提供的事件驱动支持,PHP的闭包功能非常强大和优雅。匿名函数匿名函数是闭包的核心。在PHP中,匿名函数实际上是Closure类的对象(请注意它们是对象)。与普通的面向对象编程不同,匿名函数的代码直接写在调用的地方,不需要额外写类或方法代码。这样做的好处是比较直接。下面的例子是设置一个定时器,每2秒输出一次helloworld。传统写法functiontimer(){echo"helloworld";}Swoole\Timer::tick(2000,'timer');闭包写法Swoole\Timer::tick(2000,function(){echo"helloworld";});非闭包的传统写法,先声明一个函数,然后传递函数名字符串。两段代码是分开的,不够直观。闭包方法把定时器的声明和定时器要执行的代码写在一起,逻辑非常清晰直观。使用闭包语法编写回调函数非常方便。在事件驱动编程、排序、array_walk等需要用户传入一段执行代码的场景中,闭包写得非常优雅。闭包更强大的地方在于它们可以直接在调用处引入外部变量。PHP中实现的方法是use关键字。使用语法如果刚才的定时器需要传入一个变量,传统的写法只能通过全局变量来实现。与JS不同,PHP的变量引入是显式的。如果要引用外部变量,必须使用use来声明。JS是隐式的,可以在匿名函数内随意操作外部变量,无需声明。这样做的好处是少写一点代码,缺点是有风险和混乱。传统写法$str="helloworld";函数计时器(){全局$str;echo$str;}Swoole\Timer::tick(2000,'定时器');闭包写法$str="helloworld";Swoole\Timer::tick(2000,function()use($str){echo$str;});闭包写法使用use直接引入当前$str变量,不使用global全局变量。另外,如果是swoole的事件驱动编程模式,使用global是无法实现异步并发的,因为global全局变量只有一个。如果同时有多个客户端请求,每个请求都需要查询数据库,输出不同的内容。传统的编程方式不容易实现,需要使用全局变量数组,以客户端ID为KEY来保存各自的数据。传统写法$requestArray=array();$dbResultArray=数组();函数my_request($request,$response){global$dbResultArray,$requestArray;$queryId=$db->query($sql,'get_result');$requestArray[$request->fd]=array($request,$response);$dbResultArray[$queryId]=$request->fd;}functionget_result($queryId,$queryResult){全局$dbResultArray,$requestArray;列表($request,$response)=$requestArray[$dbResultArray[$queryId]];$response->end($queryResult);}$server->on('request','my_request');闭包写法$server->on('request',function($request,$response){$queryId=$db->query($sql,function($queryId,$queryResult)use($request,$response){$response->end($queryResult);});});传统的写法非常复杂,需要反复从全局数组中保存/提取数据。闭包的写法非常简洁优雅,只用几行代码就可以实现同样的功能。闭包写法非常适合写异步非阻塞回调方式的服务端程序。目前流行的编程语言中,只有PHP和JS具备这种能力。闭包的更多特性是在类方法中使用匿名函数。5.4以上的版本就不用use介绍了。可以在匿名函数中直接使用this,也可以在匿名函数中直接使用this调用当前对象的方法。在swoole编程中,可以利用这个特性来减少$serv对象的使用引入传递。classServerextendsSwoole\Server{functiononReceive($serv,$fd,$reactorId,$data){$db->query($sql,function($queryId,$queryResult)use($fd){$this->send($fd,$queryResult);}}}另外,如果要在闭包函数中修改外部变量,可以在使用时给变量加上&引用符号,注意对象类型不需要加上&,因为PHP中的对象默认是引用传递而不是值传递,更多学习内容可以访问【与大厂比较】优质PHP架构师教程目录。只要你会看,就能保证你的薪水更上一层楼(持续更新中)以上内容希望对大家有所帮助,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,写的太多了业务代码,没有方向感,不知道从哪里开始改进。我整理了一些资料,包括但不包括limitedto:、高扩展、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等高级进阶知识点如果你需要干货,可以免费分享给大家,有需要可以点这里进阶PHP月薪30k>>>架构师成长路线【免费获取视频和面试资料】
