php _invoke 闭包,PHP新特性之闭包、匿名函数

闭包

闭包是什么?

1).闭包和匿名函数在PHP5.3中被引入。

2).闭包是指在创建时封装函数周围状态的函数,即使闭包所在的环境不存在了,闭包封装的状态依然存在,这一点和Javascript的闭包特性很相似。

3).匿名函数就是没有名称的函数,匿名函数可以赋值给变量,还可以像其他任何PHP对象一样传递。可以将匿名函数和闭包视作相同的概念。

4).需要注意的是闭包使用的语法和普通函数相同,但是他其实是伪装成函数的对象,是Closure类的实例。闭包和字符串或整数一样,是一等值类型。

创建闭包

$closure = function ($name){

return sprintf('hello %s', $name);

};

echo $closure('Josh');复制代码

我们之所以可以调用$closure变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()魔术方法,只要后面跟着(),PHP就会查找__invoke()方法。这里简单解释下这个魔术方法:

class testClass{

public function __invoke{

print "hello world";

}

}

$n = new testClass;

$n();复制代码

PHP自从5.3版以来就新增了一个叫做__invoke()的魔术方法,使用该方法就可以在创建实例后,直接调用对象。

何时使用?

我们通常把PHP闭包当做函数和方法的回调使用。很多PHP函数都会用到回调函数,例如array_map()和preg_replace_callback()。

$numbersPlusOne = array_map(function($number){

return $number + 1;

}, [1, 2, 3]);复制代码

如何理解附加状态?

1).注意PHP闭包不会真的像JS一样自动封装应用的状态,在PHP中必须调用闭包对象的bindTo方法或者使用use关键字,把状态附加到PHP闭包上。来看一个例子

function enclosePerson($name){

return function ($doCommand) use ($name){

return sprintf('%s , %s', $name, $doCommand);

};

}

//把字符串“Clay”封装在闭包中

$clay = enclosePerson('Clay');

//传入参数,调用闭包

echo $clay('get me sweat tea!'); // Clay, get me sweat tea!复制代码

在这个例子中,函数enclosePerson()有一个$name参数,这个函数返回一个闭包对象,这个闭包封装了$name参数,即便返回的对象跳出了enclosePerson()函数的作用域,它也会记住$name参数的值,因为$name变量仍然在闭包中。

2).使用use关键字可以把多个关键字传入闭包,此时要想像PHP函数或方法的参数一样,使用逗号分割多个参数。

3).PHP闭包仍然是对象,可以使用$this关键字获取闭包的内部状态。闭包的默认状态里面有一个__invoke()魔术方法和bindTo()方法。

4).bindTo()方法为闭包增加了一些有趣的东西。我们可以使用这个方法把Closure对象内部状态绑定到其他对象上。bindTo()方法的第二个参数可以指定绑定闭包的那个对象所属的PHP类,这样我们就可以访问这个类的受保护和私有的成员变量。看下面的代码示例:

class App{

protected $route = array();

protected $responseStatus = '200 OK';

protected $responseContentType = 'text/html';

protected $responseBody = 'Hello world';

public function addRoute($routePath, $routeCallback){

$this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);

}

public function dispatch($currentPath){

foreach($this->routes as $routePath => $callback) {

if ($routePath === $currentPath) {

$callback();

}

}

header('HTTP/1.1' . $this->responseStatus);

header('Content-type: ' . $this->responseContentType);

header('Content-length: ' . mb_strlen($this->responseBody));

echo $this->responseBody;

}

}复制代码

我们把路由回调绑定到了当前的App实例上,这样就可以在回调函数中处理App实例的状态了。

$app = new App();

$app->addRoute('/users/xiaoxiao', function (){

$this->responseContentType = 'application/json;charset=utf8';

$this->responseBody = '{"name" : "xiaoxiao"}';

});

$app->dispatch('/users/xiaoxiao');复制代码

专题系列

PHP专题系列目录地址:github.com/xx19941215/…

PHP专题系列预计写二十篇左右,主要总结我们日常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特点的深入研究。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

*【UVA - 10382】Watering Grass(贪心,区间覆盖问题,思维)

题干: 题目大意: 有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆。求出最少需要的喷水装置个数,如果无论如何…

oracle如何把字符集改回默认,更改oracle字符集

在安装oracle时,选了默认字符集是utf8,后来发现与plsql developer工具联合使用时,会出现各种乱码问题。再加上我的项目也是gbk的,因此,将字符集改成gbk试试。步骤如下:1.查看当前的字符集和语言select * fr…

【HDU - 2570】迷瘴 (贪心,水题,排序,卡精度有坑)

题干: 通过悬崖的yifenfei,又面临着幽谷的考验—— 幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。 幸好…

oracle 1天后,Oracle Code One - 第1天 精彩亮点回顾

原标题:Oracle Code One - 第1天 精彩亮点回顾原文作者:Padmini Murthy 产品营销总监2018年Oracle CodOracle CodeOne大会实况 – 第1天2018年Oracle CodeOne大会开幕第一天,精彩纷呈,乐趣繁多。从Developers Exchange活动的欢畅交…

【牛客 - 303D第十五届浙江大学宁波理工学院程序设计大赛(同步赛)】Campaign(二进制枚举,位运算,暴力,思维)

题干: 星际争霸(StarCraft)单人战役模式中有很多供人游玩的任务关卡。 tokitsukaze新开始了一关单人战役模式下的任务。在这场战役中,你要作为指挥官指挥克鲁普星区的艾伦人类(Terran)来防御人类的敌人——邪恶异虫(Zerg)的袭击。 这一次,…

oracle mssql 实例,oracle,mysql,SqlServer三种数据库的分页查询的实例

MySql:MySQL数据库实现分页比较简单,提供了 LIMIT函数。一般只需要直接写到sql语句后面就行了。LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它有一个或两个参数,如果给出两个参数, 第一个参数指定返回的第…

【牛客 - 303H第十五届浙江大学宁波理工学院程序设计大赛(同步赛)】Protoss and Zerg(快速幂取模,组合数学)

题干: 1v1,是星际争霸(StarCraft)中最常见的竞技模式。 tokitsukaze进行了n场1v1。在每一场的1v1中,她都有星灵(Protoss)和异虫(Zerg)两个种族可以选择,分别有a个单位和b个单位。因为tokitsukaze不太擅长玩人类(Terran)&#x…

oracle 控制文件冗余,Oracle 添加冗余控制文件 for RAC On Linux

萌哒萌哒的分割线注:添加冗余控制文件期间需要有关库操作,需注意!!!备份控制文件SQL> alter session set tracefile_identifier‘backupctrl‘;Session altered.SQL> alter database backup controlfile to trac…

【牛客 - 303B第十五届浙江大学宁波理工学院程序设计大赛(同步赛)】Fibonacci and Counting(Fib数性质,gcd辗转相除法性质)

题干: 我们这样定义斐波那契数列,F[1]1,F[2]1,当n>2时F[n]F[n-1]F[n-2]。 斐波那契数列的前10项为:1,1,2,3,5,8,13,21,34,55。 欧几里得算法求解两个数的最大公约数。我们记gcd(a,b)为整数a与b的最大公约数。 当b0时&…

【牛客 - 303K第十五届浙江大学宁波理工学院程序设计大赛(同步赛)】Technology Tree(树形dp,tricks)

题干: 在星际争霸(StarCraft)中,有3个种族。对于任意一个种族,他们的建筑建造都是有一个顺序的。这个顺序正好是一个树形结构,我们称之为"科技树"(Technology tree)。 在科技树中,只有一个建筑是不需要前…

oracle基表恢复,查找V$PARAMETER 基表 – 专业Oracle数据库恢复,或许是您恢复数据的最后机会@phone:13429648788 - 专业Oracle数据库恢复技术支持...

1、使用trace查找show parameter执行语句alter session set events 10046 trace name context forever,level 12;show parameter process;alter session set events 10046 trace name context off;2、查找trace文件SELECT d.VALUE|| /|| LOWER (RTRIM (i.INSTANCE, CHR (0)))||…

【HDU - 1599】find the mincost route (Floyd最小环,最短路问题)

题干: 杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条旅游路线,这个路线从A点出发并且最后回到A点,假设经过的路线为V1,V2,....VK,V1,那么必须满足K>2,就是说至除了出发点以外至少要经过2个其他不同…

linux中创建目录树,如何在C++/Linux中创建目录树?

Jonathan Lef..58这是一个可以用C编译器编译的C函数./*(#)File: $RCSfile: mkpath.c,v $(#)Version: $Revision: 1.13 $(#)Last changed: $Date: 2012/07/15 00:40:37 $(#)Purpose: Create all directories in path(#)Author: J Leffler(#)Copyright: (C) JLSS 1990-91,1997-98…

linux socket bind 内核详解,Socket与系统调用深度分析(示例代码)

1、 什么是系统调用操作系统通过系统调用为运行于其上的进程提供服务。当用户态进程发起一个系统调用, CPU 将切换到 内核态 并开始执行一个 内核函数 。 内核函数负责响应应用程序的要求,例如操作文件、进行网络通讯或者申请内存资源等。在Linux中系统调…

【UVA - 11729】Commando War (贪心,时间调度问题)

题干:(Uva不放题干了) 题目大意:(实在是自己懒得写网上找了一个) 解题报告: 调度问题,直接贪心出完成任务需要的时间最长的那个人排序,就行了。 方法正确性的证明以前也…

【UVA - 1335】Beijing Guards (贪心,二分)

题干: 题目大意: 有n个人为成一个圈,其中第i个人想要r[i]种不同的礼物,相邻的两个人可以聊天,炫耀自己的礼物。如果两个相邻的人拥有同一种礼物,则双方都会很不高兴,问最少需要多少种不同的礼…

linux两个命令一起,paste命令 – 合并两个文件

paste命令会把每个文件以列对列的方式,一列列地加以合并 ,他就是相当于把两个不同的文件内容粘贴在一起,形成新的文件。注意:paste默认粘贴方式以列的方式粘贴,但是并不是不能以行的方式粘贴,加上-s选项就可…

【UVA - 11292】Dragon of Loowater (贪心,水题,模拟,twopointer双指针)

题干: 题目大意: n条恶龙,m个勇士,用勇士来杀恶龙。一个勇士只能杀一个恶龙。而且勇士只能杀直径不超过自己能力值的恶龙。每个勇士需要支付能力值一样的金币。问杀掉所有恶龙需要花费的最少金币。 解题报告: twopo…

linux 命令pg,linux下操作PostgreSQL的常用命令

一般性:\copyright 显示PostgreSQL的使用和发行许可条款\g [文件] or; 执行查询 (并把结果写入文件或 |管道)\h [名称] SQL命令语法上的说明,用*显示全部命令的语法说明\q 退出 psql查询缓存区\e [FILE] [LINE] 使用外部编辑器编辑查询缓存区(或文件)\ef…

【UVA - 10037】Bridge(过河问题,经典贪心)

题干: 题目大意: 有N个人要过桥,每个人速度不同,只有一个手电筒,每次最多只能过去两个人,问所有人最短的过桥时间为多少 解题报告: 首先让最快的两个人最后过,然后我们分奇偶考虑…