而在PHP 5.3发布的时候, 其中有一条new feature就是支持闭包/Lambda Function, 我第一反应是以为zval新增了一个IS_FUNCTION, 但实际上是构造了一个PHP 5.3引入的Closure”类”的实例, Closure类的构造函数是私有的, 所以不能被直接实例化, 另外Closure类是Final类, 所以也不能做为基类派生子类.

  1. //php-5.3.0
  2. $class = new ReflectionClass("Closure");
  3. var_dump($class->isInternal());
  4. var_dump($class->isAbstract() );
  5. var_dump($class->isFinal());
  6. var_dump($class->isInterface());
  7. //输出:
  8. bool(true)
  9. bool(false)
  10. bool(true)
  11. bool(false)
  12. ?>

  而PHP 5.3中对闭包的支持, 也仅仅是把要保持的外部变量, 做为Closure对象的”Static属性”(并不是普通意义上的可遍历/访问的属性).

  1. //php-5.3.0
  2. $b = "laruence";
  3. $func = function($a) use($b) {};
  4. var_dump($func);
  5. /* 输出:
  6. object(Closure)#1 (2) {
  7. ["static"]=>
  8. array(1) {
  9. ["b"]=> string(8) "laruence"
  10. }
  11. ["parameter"]=>
  12. array(1) {
  13. ["$a"]=> string(10) "<required>"
  14. }
  15. }
  16. */

闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号:

<?php
$greet = function($name)
{
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');
?>

仔细看下面的例子...看看作用域的不同

<?php
$result = 0;

$one = function()
{ var_dump($result); };

$two = function() use ($result)
{ var_dump($result); };

$three = function() use (&$result)
{ var_dump($result); };

$result++;

$one();    // outputs NULL: $result is not in scope
$two();    // outputs int(0): $result was copied
$three();    // outputs int(1)
?>

<?php
//set up variable in advance
$myInstance = null;

$broken = function() uses ($myInstance)
{
    if(!empty($myInstance)) $myInstance->doSomething();
};

$working = function() uses (&$myInstance)
{
    if(!empty($myInstance)) $myInstance->doSomething();
}

//$myInstance might be instantiated, might not be
if(SomeBusinessLogic::worked() == true)
{
    $myInstance = new myClass();
}

$broken();    // will never do anything: $myInstance will ALWAYS be null inside this closure.
$working();    // will call doSomething if $myInstance is instantiated

?>

深入理解php 匿名函数和 Closure的更多相关文章

  1. 深入理解javascript 匿名函数和闭包

    代码如下: (function(){ //这里忽略jQuery所有实现 })(); (function(){ //这里忽略jQuery所有实现 })();  半年前初次接触jQuery的时候,我也像其 ...

  2. python之匿名函数以及在内置函数中的使用

    一. 匿名函数 Python使用 lambda 来创建匿名函数.所谓匿名函数,它与用 def 关键字定义的函数相比,没有函数名称. 1.1 匿名函数定义及特点 语法: lambda [para1, p ...

  3. node.js中的匿名函数, 回调函数和嵌套函数

    定义一个函数相信大家已经很熟悉了, 在javascript里的函数也是非常重要的, 使用率非常高, 有几种函数不是很好理解 一, 匿名函数 var remove = function(num1) { ...

  4. PHP Closure创建匿名函数

    Closure 类 用于代表匿名函数的类. 匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象.在过去,这个类被认为是一个实现细节,但现在可以依赖它做一些事情.自 PHP 5.4 起, 这个 ...

  5. php匿名函数和闭包函数及use关键字传参及Closure匿名函数类

    php闭包函数用use传参有什么意义?答:use引用外层变量,比如全局变量 Closure,匿名函数,是php5.3的时候引入的,又称为Anonymous functions.字面意思也就是没有定义名 ...

  6. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  7. JS匿名函数的理解

    js匿名函数的代码如下:(function(){ // 这里忽略jQuery 所有实现 })(); 半年前初次接触jQuery 的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的 ...

  8. [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)【转】

    (function(){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的第一眼,我就迷糊了.为什么只有 ...

  9. javascript 匿名函数的理解,js括号中括function 如(function(){})

    代码如下: (function(){  //这里忽略jQuery所有实现  })();  (function(){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也 ...

随机推荐

  1. 设计模式——门面模式(Facade)

    要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1.概念 门面模式是 ...

  2. JAVA 爬虫Gecco

    主要代码: Gecco(matchUrl="https://github.com/{user}/{project}", pipelines="consolePipelin ...

  3. 解压版MySQL安装后初始化root密码

    1: C:\Users\gechong>mysql

  4. 【Linux】war包的解压与压缩

    现在存在一个war包test.war(以下是在Linux上操作) 1.解压war包 jar –xvf test.war 说明:直接解压到当前文件夹,如果需要解压到指定的文件夹下,需要将test.war ...

  5. 指定spring中bean启动的顺序

    参考链接: https://www.jb51.net/article/125846.htm 使用DependsOn Spring 中的 DependsOn 注解可以保证被依赖的bean先于当前bean ...

  6. 16、java包装类

    一.包装类的由来: JAVA是面向对象的编程语言,但它也包含了8种基本数据类型,这8个基本数据类型不支持面向对象的编程机制,基本数据类型的数据也不具备“对象”的特性:没有属性,方法可以被调用.JAVA ...

  7. 文本挖掘之文本聚类(DBSCAN)

    刘 勇   Email:lyssym@sina.com 简介 鉴于基于划分的文本聚类方法只能识别球形的聚类,因此本文对基于密度的文本聚类算法展开研究.DBSCAN(Density-Based Spat ...

  8. 【redis】常用命令

    三.常用命令    1)连接操作命令    quit:关闭连接(connection)    auth:简单密码认证    help cmd: 查看cmd帮助,例如:help quit         ...

  9. HDUOJ Children’s Queue

    Children’s Queue Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  10. Java中的平衡树

    leetcode 729 给定一堆线段,每个线段都有一个起点.一个终点,用数组[(beg1,end1),(beg2,end2),(beg3,end3)......]来表示.可以提出以下问题: 这些线段 ...