###序言 最近在看一些面试题时,提到了闭包,回调函数,回调等概念,看的是一脸懵逼,碰巧今天刷知乎时看到了,看完感觉解释的不错,这里梳理一下。 ###理解回调的本质 知乎上最高票回答描述如下:
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。 作者:常溪玲 链接:https://www.zhihu.com/question/19801131/answer/13005983 来源:知乎
这里我们假设购物者是 A ,商店是 B 。我们需要在商店里面买东西,商店要把东西给我们,也就是说 A 需要 B 做些什么事情,反应在我们写程序的过程上就是 A 调用 B 得到一个返回结果,通常在代码里是 A 调用 B 方法, B 会 return
一个值。但是在某一些情况下仅仅凭借 B 本事是无法完成某一过程的,比如上述例子中的没货了,反应在程序中,有时候 B 会需要外界的信息,这里需要注意信息这个词,我们一般在写程序的某一个方法时,方法可以定义参数,这个参数就可以称为信息,同样的,在 PHP 语言中一个函数同样可以称为信息,也就是说在 PHP 中,函数和int
,float
等是一样的地位的,他们是可以统一称为信息被传递的,而函数和其本身所用到的数据,我们称为闭包。
另外有些语言不单可以传递函数,函数里面又用到一些外部信息(包括code, data)。那些语言可以将函数跟函数所用到的信息一起传递存储。这种将函数和它所用的信息作为一个整体,就为闭包。过了这个槛,将代码和数据统一起来,很多难以理解的概念就会清晰很多。 作者:黄兢成 链接:https://www.zhihu.com/question/19801131/answer/17156023 来源:知乎
我们回到上面的例子,在我们向商店购买东西的时候,本身是我们调用商店的服务,但是商店在运行的过程中会给我们打电话,反而成商店调用我们了,这个过程就称为回调。
###Code 下面写一个PHP使用回调的例子。
class Person{ public $name; public $age; public function __construct($name,$age) { $this->name=$name; $this->age=$age; }}class PersonInfo{ private $callbacks; //用于注册回调函数 public function registerCallBack($callback){ if(!is_callable($callback)){ throw new Exception("callback not callable"); } $this->callbacks[]=$callback; } public function getPersonInfo(Person $person){ foreach ($this->callbacks as $callback){ //调用回调函数 call_user_func($callback,$person); } }}//定义一个匿名函数作为回调函数$log=function (Person $person){ echo "Name:{$person->name},Age:{$person->age}";};$personInfo=new PersonInfo();//注册匿名函数$personInfo->registerCallBack($log);//调用回调函数$personInfo->getPersonInfo(new Person('Yang',18));复制代码
运行结果:
从结果看,匿名函数已经被调用了。
###闭包 这里最后再说一下闭包,PHP中闭包有一个使用比较多的技巧就是,在闭包中可以使用父作用域内的变量。
$message='hello';$closure=function ()use ($message){ return $message;};echo $closure();复制代码
输出结果:
我们可以看到在匿名函数作用域中,我们并没有定义$message
变量 ,但是我们通过 use
关键字,我们可以调用外面的作用域中定义的 $message
变量。 另外关于闭包,发现一个比较好的文章。