深入理解PHP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包
2017-05-26 00:02
597 查看
深入理解P
4000
HP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包
2017-05-25 20:25 by 吃饱了才能撑着, 1 阅读, 0 评论, 收藏,编辑
匿名函数是一类不需要指定标示符,而又可以被调用的函,匿名函数可以方便的作为参数传递给其它函数,最常见应用为回调函数。
闭包(Closure)
说到匿名函数,就不得不提到闭包了,闭包是词法闭包的简称,是引用了自由变量的函数,这个被应用的自由变量将和这个函数一同存在,即使离开了创建它的环境一个一样,所以闭包也可以任务是有函数和其它相关引用组合而成的实体。
使用create_function()创建“匿名”函数
<?php $array = array(1,2,3,4); array_walk($array,create('$value','echo $value'));
1
2
3
1
2
3
关于另外一个create_function函数的应用
$func = create_function('','echo "Function created dynmic";'); echo $func;// lambda_1 $func();// Function created dynmic $my_func = 'lambda_1 ’ $my_func();// 不存在这个函数 lambda_1();//不存在这个函数
1
2
3
4
5
6
7
1
2
3
4
5
6
7
为什么会出现上面的情况呢?
$func = create_function('', 'echo "Hello";'); $my_func_name = 'lambda_1'; debug_zval_dump($func); // string(9) "lambda_1" refcount(2) debug_zval_dump($my_func_name); // string(8) "lambda_1" refcount(2)
1
2
3
4
5
1
2
3
4
5
显示结果,居然长度都不一样,当然就不一样了。因为系统定义的,函数第一个其实是 \0 也就是空字符。这样因为用户无法定义这样的字符,所以,就不会重名了,聪明吧!!!
这样函数的缺点:
1 函数的定义是通过资产动态eval的,这样就无法进行基本的语法检查
2 这类函数和普通函数没有本质区别,无法实现闭包的效果。
__invoke磨合方法
这个魔术方法被调用的时机是,当一个对象当作函数调用的时候,如果对象定义了__invoke魔术方法则这个函数会被调用.使用方法:<?php class Callme{ public function __invoke($phone_num){ echo "Hello $phone_num"; } } $call = new Callme(); $call(13880425377);
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
匿名函数的实现
$func = function(){ echo "Hello function"; } echo gettype($func);//object echo get_class($func);//closure
1
2
3
4
5
1
2
3
4
5
原来匿名函数也只是一个普通的类而已。
JS中的匿名函数,可以如下定义:
var a = {}; a.call = function () {alert("called");} a.call();// alert called
1
2
3
1
2
3
闭包的使用
PHP使用闭包(Closure)来实现匿名函数,匿名函数最强大的功能也就在匿名函数所提供的一些动态特征以及闭包效果,匿名函数在定义的时候如果需要使用作用域外的变量,需要如下的语法实现:<?php $name = "jingshan"; $func = function()use($name){ echo "hello $name"; } $func();
1
2
3
4
5
6
1
2
3
4
5
6
并且匿名函数在每次执行的时候都能访问到上层作用域内的变量,这些变量在匿名函数被销毁之前始终保持这自己的状态,例如如下的例子:
<?php function getCounter(){ $i = 0; return function() use($i){ echo ++$i; } } $counter = getCounter(); $counter();//1 $counter();//1
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
闭包的实现
前面提到匿名函数是通过闭包类实现的,现在我们开始看闭包(类)是怎么实现的。匿名函数和普通函数处理是否有变量名以外并没有区别。<?php $i = 100; $counter = function() use($i){ debug_zval_dump($i); }; $counter();
1
2
3
4
5
6
1
2
3
4
5
6
生成的 opcode代码:
然后通过内部函数的调用,实现传参。
更多信息请参考千锋php,千锋论坛
相关文章推荐
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的参数
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --简介
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的定义
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的调用和执行
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数间的转换
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的参数-1
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的返回值
- [李景山php] 深入理解PHP内核[读书笔记]--第五章:类和面向对象 --类的结构和实现
- [李景山php] 深入理解PHP内核[读书笔记]--第五章:类和面向对象 --访问控制的实现
- [李景山php] 深入理解PHP内核[读书笔记]--第三章:变量及数据类型--变量的结构和类型--PHP的哈希实现
- [李景山php] 深入理解PHP内核[读书笔记]--第二章:用户代码执行--opcode处理函数查找
- 第四节 匿名函数及闭包_深入理解PHP内核
- [李景山php] 深入理解PHP内核[读书笔记]--第三章:变量及数据类型--变量的结构和类型--类型提示的实现
- [李景山php] 深入理解PHP内核[读书笔记]--第二章:用户代码执行--SAPI概述-PHP中的CGI实现
- [李景山php] 20170504深入理解PHP内核[读书笔记]--第一章准备工作和背景知识--1
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- [李景山php] 20170504深入理解PHP内核[读书笔记]--第一章准备工作和背景知识--2
- Js函数深入理解-闭包中的this