zoukankan      html  css  js  c++  java
  • PHP 闭包(匿名函数)

    PHP 在 5.3引入了匿名函数closure的概念,这个也就是俗称的闭包,指的是包含有未绑定到特定对象的变量(自由变量)的代码块

    创建closure对象:

    $foo = function(){
    };//因为相当于将一个closure对象赋值给对象,要遵循对象赋值语法,语句结束需要添加分号
    $foo();

     闭包声明参数以及调用外部变量:

    $value = 'hello';
    $foo = function($bar) use ($value){
        echo $value . $bar;
    };
    $foo('world');//输出helloworld
    /*PHP版本5.4以上$this才可用于匿名函数*/

    使用引用和不使用引用,根据官方文档:

    <?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)
    ?>

    不使用引用时,在闭包内部的$result实际是声明时候对外部变量$result的复制,因此闭包内部对$result的处理不会影响到外部变量result,而使用引用则闭包内$result直接指向外部变量$result的内存地址,因此会对外部$result造成影响:

    <?php 
    $x = 0;
    $foo = function() use ($x){
        $x++;
        echo $x;
    };
    
    $bar = function() use (&$x){
        $x++;
        echo $x;
    };
    $foo();
    $foo();
    $bar();
    $bar();
    //输出 11 12
    ?>

    因为闭包的存在,我们便可以在不需要在外部声明回调函数的情况下使用一些类似于array_walk的方法,比如官方手册中提供的购物车的方法:

    <?php
    // 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。
    // 其中有一个方法用来计算购物车中所有商品的总价格,该方法使
    // 用了一个 closure 作为回调函数。
    class Cart
    {
        const PRICE_BUTTER  = 1.00;
        const PRICE_MILK    = 3.00;
        const PRICE_EGGS    = 6.95;
    
        protected   $products = array();
        
        public function add($product, $quantity)
        {
            $this->products[$product] = $quantity;
        }
        
        public function getQuantity($product)
        {
            return isset($this->products[$product]) ? $this->products[$product] :
                   FALSE;
        }
        
        public function getTotal($tax)
        {
            $total = 0.00;
            
            $callback =
                function ($quantity, $product) use ($tax, &$total)
                {
                    $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                        strtoupper($product));
                    $total += ($pricePerItem * $quantity) * ($tax + 1.0);
                };
            
            array_walk($this->products, $callback);
            return round($total, 2);;
        }
    }
    
    $my_cart = new Cart;
    
    // 往购物车里添加条目
    $my_cart->add('butter', 1);
    $my_cart->add('milk', 3);
    $my_cart->add('eggs', 6);
    
    // 打出出总价格,其中有 5% 的销售税.
    print $my_cart->getTotal(0.05) . "
    ";
    // 最后结果是 54.29
    ?>
  • 相关阅读:
    HDU4289 Control 最大流
    POJ3281 Dining 最大流
    HDU4738 Caocao's Bridges 无向图的桥
    HDU4865 Prince and Princess 强连通分量+二分图判定
    POJ 1904 King's Quest 强连通分量+二分图增广判定
    HDU 4635 Strongly connected 强连通分量
    HDU 4280Island Transport(Dinc非STL 模板)
    POJ 2752Seek the Name, Seek the Fame(next数组妙用 + 既是前缀也是后缀)
    Codeforces Round #346 (Div. 2)E
    POJ2318TOYS(叉积判断点与直线位置)
  • 原文地址:https://www.cnblogs.com/jackiebao/p/5445297.html
Copyright © 2011-2022 走看看