匿名函数

匿名函数,也叫闭包函数,说白了就是“没有名字的函数”,和一般函数结构一样,只是少了函数名以及最后需要加上分号;

注:理论上讲闭包和匿名函数是不同的概念,不过PHP将其视作相同的概念。

$func = function()
{echo 'Hello World' . PHP_EOL;
};
$func();

匿名函数和普通函数的区分有:

  • 匿名函数也可以作为变量的值来使用。
  • 匿名函数可以从父作用域继承变量,而这个父作用域是定义该闭包的函数(不一定是调用它的函数)。
$message = 'hello';
$example = function () use ($message) {return $message;
};
$message = 'world';
echo $example();输出:hello

注意:必须使用use关键字将变量传递进去才行,具体见官方文档。

闭包类

定义一个闭包函数,其实就是实例化一个闭包类(Closure)对象:

$func = function()
{echo 'hello world' . PHP_EOL;
};
var_dump($func);输出:
object(Closure)#1 (0) {
}

类摘要:

Closure {__construct ( void )public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )
}

除了以上方法,闭包还实现了一个__invoke()魔术方法,当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

bindTo 方法

接下来我们来看看bindTo方法,通过该方法,我们可以把闭包的内部状态绑定到其他对象上。这里bindTo方法的第二个参数显得尤为重要,其作用是指定绑定闭包的那个对象所属的PHP类,这样,闭包就可以在其他地方访问绑定闭包的对象中受保护和私有的成员变量。

你会发现,PHP框架经常使用bindTo方法把路由URL映射到匿名回调函数上,框架会把匿名回调函数绑定到应用对象上,这样在匿名函数中就可以使用$this关键字引用重要的应用对象:

class App {protected $routes = [];protected $responseStatus = '200 OK';protected $responseContentType = 'text/html';protected $responseBody = 'Hello World';public function addRoute($path, $callback) {$this->routes[$path] = $callback->bindTo($this, __CLASS__);}public function dispatch($path) {foreach ($this->routes as $routePath => $callback) {if( $routePath === $path) {$callback();}}header('HTTP/1.1 ' . $this->responseStatus);header('Content-Type: ' . $this->responseContentType);header('Content-Length: ' . mb_strlen($this->responseBody));echo $this->responseBody;}}

这里我们需要重点关注addRoute方法,这个方法的参数分别是一个路由路径和一个路由回调,dispatch方法的参数是当前HTTP请求的路径,它会调用匹配的路由回调。第9行是重点所在,我们将路由回调绑定到了当前的App实例上。这么做能够在回调函数中处理App实例的状态:

$app = new App();
$app->addRoute(‘/user’, function(){$this->responseContentType = ‘application/json;charset=utf8’;$this->responseBody = '世界你好';
});
$app->dispatch('/user');

IoC 容器

匿名函数可以从父作用域继承变量,而这个父作用域是定义该闭包的函数(不一定是调用它的函数)。

利用这个特性,我们可以实现一个简单的控制反转IoC容器:

class Container
{protected static $bindings;public static function bind($abstract, Closure $concrete){static::$bindings[$abstract] = $concrete;}public static function make($abstract){return call_user_func(static::$bindings[$abstract]);}
}class talk
{public function greet($target){echo 'Hello ' . $target->getName();}
}class A
{public function getName(){return 'World';}
}// 创建一个talk类的实例
$talk = new talk();// 将A类绑定至容器,命名为foo
Container::bind('foo', function() {return new A;
});// 通过容器取出实例
$talk->greet(Container::make('foo')); // Hello World

上述例子中,只有在通过make方法获取实例的时候,实例才被创建,这样使得我们可以实现容器。

Laravel框架底层也大量使用了闭包以及bindTo方法,利用好闭包可以实现更多的高级特性如事件触发等。

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要请戳这里链接 或 者关注咱们下面的知乎专栏

PHP架构师圈子​zhuanlan.zhihu.com

php的闭包函数bingto_PHP 闭包那点事儿相关推荐

  1. JavaScript闭包函数与闭包释放

    作用域链:一般,变量取值是到创建这个变量的函数的作用域中取值,如果没有查到,就会往上查找,直到找到全局作用域,这个查找的形成为作用域链. Javascript闭包函数:闭包就是能够读取其它函数内部变量 ...

  2. PHP闭包函数与闭包函数回调

    PHP闭包函数与闭包函数回调 没有名的函数成为匿名函数 eg: $sum = function($num1,$num2){return $num1+$num2; }; //匿名函数调用 echo $s ...

  3. php的闭包函数bingto_php的闭包

    闭包是指在创建时封装周围状态的函数,即使闭包所在的环境的不存在了,闭包中封装的状态依然存在. 匿名函数其实就是没有名称的函数,匿名函数可以赋值给变量,还能像其他任何PHP函数对象那样传递.不过匿名函数 ...

  4. Go 学习笔记(18)— 函数(04)[闭包定义、闭包修改变量、闭包记忆效应、闭包实现生成器、闭包复制原对象指针]

    1. 闭包定义 Go 语言中闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可以继续使用这个自由变量,因此,简单的说: 函数 + ...

  5. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  6. python教程:闭包函数

    一:大前提 闭包函数 = 名称空间与作用域 + 函数嵌套 + 函数对象 核心点:名字的查找关系是以函数定义阶段为准 二:什么是闭包函数 "闭"函数指的该函数是内嵌函数 " ...

  7. python高阶函数闭包装饰器_5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器...

    一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰 ...

  8. 函数类型:有参函数、无参函数、匿名函数、回调函数、立即执行函数、闭包函数、递归函数...

    1.有参函数:函数定义时,带有参数的函数 设置函数参数的默认值: (1)直接在函数定义位置的小括号内进行赋值 (2)低版本默认值的处理(在函数内部判断该参数是否有默认值,若没有,赋值初始值) 第1种默 ...

  9. python中msg函数_Python 中闭包函数和装饰器

    一.闭包函数的概述 闭包 closure, 是一种代码的组织结构.当一个内嵌函数引用其外部作用域的变量,就形成一个闭包函数.闭包函数有一个内嵌函数,内嵌函数引用外部函数中的变量,外部函数的返回值是内嵌 ...

最新文章

  1. Windows7自动安装驱动功能关闭与开启教程
  2. MySQL 无效数字_ORA-01722: 无效数字的解决方法
  3. Web ReplayType?
  4. 关于人类肉眼识别模式的简单想法
  5. 对协变和逆变的简单理解
  6. C51单片机其他名词英文全称
  7. sqlserver 事务日志 异常增长原因排查_小白入门学习打日志
  8. php 模数 指数 公钥生成_php实现JWT认证
  9. 喜马拉雅 xm文件转m4a_喜马拉雅电台、课程语音如何转成文字?
  10. Vue服务端配置示例
  11. Java基础与数据库对应数据--Java基础2阶段
  12. MSP430之自动增益程控放大main备份
  13. 使用标准测试函数测试全套 MATLAB 优化算法
  14. Netty学习之读netty权威指南(三)
  15. 运行matlab报错 Runtime Error
  16. 正则表达式在线生成网站推荐
  17. 手把手教你写软件1.软件介绍已经心得体会
  18. Modulo Summation——UPC
  19. Kotlin Sealed 是什么?为什么 Google 都用
  20. (离散数学)用谓词逻辑推理的方法证明下面推理的有效性。要求按照推理的格式书写推理过程。

热门文章

  1. 【每日一算法】平衡二叉树
  2. Linux内核网络栈1.2.13-有关tcp/ip协议的基础入门
  3. getElementsByName,实现多选的全选与全不选功能
  4. python如何将列表,字典,元组,集合首字母变成大写 以及其他的大小写转换!
  5. C语言连续指针_只愿与一人十指紧扣_新浪博客
  6. 视觉实战|使用人工神经网络进行图像分类
  7. Ret2Libc(2) (有system、无‘/bin/sh’)绕过NX、ASLR
  8. mysql存储、function、触发器等实例
  9. 如何解构单体前端应用——前端应用的微服务式拆分
  10. 扒一扒.net、.net framework、mono和Unity