zoukankan      html  css  js  c++  java
  • 深入理解php 匿名函数和 Closure

    而在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 ", $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

    ?>

  • 相关阅读:
    Django REST framework
    容器平台自动化CI/CD流水线实操
    VUE--webpack
    vue动态路由匹配
    VUE学习---vue基础与vue-router
    MYSQL-创建测试数据
    MYSQL-主键、外键
    MYSQL-数据库、表、数据操作
    MySQL-添加环境变量 及MySQL服务启停
    MYSQL-命令行
  • 原文地址:https://www.cnblogs.com/zhepama/p/3979961.html
Copyright © 2011-2022 走看看