20.php回调、匿名函数、和闭包操作

    现在的php是即支持面向对象的语言由支持面向过程的语言,在开发过程中我们往往会混合使用,回调会让我们容易将两种编码方式做整合,做到优秀的插拔。而闭包操作和回调都是建立在匿名函数基础之上的。

<?php
/* 简单的用于实验的类  */
class Product{
    public $name;
    public $price;
    
    function __construct($name, $price){
        $this->name = $name;
        $this->price = $price;
    }
}

class ProcessSale{
    //用来存放函数
    private $callbacks = array();
    
    //使用is_callable()在存入数组之前对函数的可用性进行检测
    function registerCallback($callback){
        if(!is_callable($callback)){
            throw new Exception("callback not callable!");
        }
        $this->callbacks[] = $callback;
    }
    
    //方便对函数的调用
    function sale(Product $product){
        print "{$product->name}:processing<br/>";
        foreach ($this->callbacks as $callback){
            call_user_func($callback, $product);
        }
    } 
}

//被插入的函数
function say($product){
    echo "{$product->name}";
}

$product = new Product('xin', 100);
$process = new ProcessSale();
$process->registerCallback('say');

$process->sale($product);

    那么匿名函数是什么样的呢?

    使用变量存放的类型,注意虽然有分行但是,最后结束还是要使用“;”,另外调用的时候要使用变量名,而不是函数名的字符串的形式。

//被插入的函数
$say = function ($product){
    echo "{$product->name}";
};
$process->registerCallback($say);

    使用create_function()函数创建的类型。同样要注意上面提到的两点。

$say = create_function('$product', 'echo "{$product->name}";');
$process->registerCallback($say);
   下面来说一说闭包的问题。

    所谓的闭包,是一种对作用域进行封装的方式,使得函数能使用父作用域中的变量。

    有时候我们能将匿名函数直接返回。

class Totalizer{
    static function warnAmount(){
        return function($product){
            echo $product->name;
        };
    }
}
$process->registerCallback(Totalizer::warnAmount());
   现在我们要对商品进行总额计价,并当商品总价格超出某一值时进行提示

   全部代码

<?php
/* 简单的用于实验的类  */
class Product{
    public $name;
    public $price;
    
    function __construct($name, $price){
        $this->name = $name;
        $this->price = $price;
    }
}

class ProcessSale{
    //用来存放函数
    private $callbacks = array();
    
    //使用is_callable()在存入数组之前对函数的可用性进行检测
    function registerCallback($callback){
        if(!is_callable($callback)){
            throw new Exception("callback not callable!");
        }
        $this->callbacks[] = $callback;
    }
    
    //方便对函数的调用
    function sale(Product $product){
        print "{$product->name}:processing<br/>";
        foreach ($this->callbacks as $callback){
            call_user_func($callback, $product);
        }
    } 
}

class Totalizer{
    static function warnAmount($amt){
        $count = 0;
        return function($product) use ($amt, &$count){
            $count += $product->price;
            print "all count: $count<br/><br/>";
            if($count > $amt){
                echo "warring!!!!!!";
            }
        };
    }
}

//被插入的函数
/* $say = function ($product){
    echo "{$product->name}";
}; */
$say = create_function('$product', 'echo "{$product->name}";');

$product = new Product('xin', 10);
$process = new ProcessSale();
$process->registerCallback(Totalizer::warnAmount(30));

$process->sale($product);
$process->sale($product);
$process->sale($product);
$process->sale($product);

    Totalizer的warnAmount方法返回一个匿名函数,匿名函数中明确说明要使用类方法中的$amt和$count两个变量,这就是闭包操作,对父域中的变量的使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值