php 闭包函数的使用

其实闭包函数听起来很高大上,其实没什么,只是将函数作为参数传入函数或方法里边,再在函数或方法里边调用。我写了一个函数叫calculate($num1, $num2, $op),calculate函数的前面两个参数参数分别为两个数字,第三个参数$op是操作(如加减乘除),相信你已经想到了,如果如果calculate()的第三个参数我写成匿名函数会怎样,即

calculate($num1, $num2, function($n1, $n2) {
    echo "$n1 + $n2 = " . $n1 + $n2;    
}); 

那么我们就可以实现将$num1,$num2传入这个匿名函数中,结果就不用我说了。那么,问题来了,我们怎么传入参数呢?这就要用到一个比较有意思的函数了,叫func_get_args(),获取传入该函数的参数,如果这还听不懂就去看手册,获取到的结果是一个数组,有趣的是,敲黑板了,他获取到的是你传入的参数,而不是对应的形参,也就是说你传多了几个,它也会获取到,利用这一点,我们就可以写成如下样子:

calculate($num1, $num2) {
    $args = func_get_args();
    $args[2]($num1, $num2);
}

这样的写法也跟php传入的参数多于形参也不会报错的特性有关,这样我们便实现了所谓的闭包的功能。

下面是我模仿laravel里边的chunk方法写的一个例子,里边还用到了递归,顺便可以学习一下递归 。如下:

<?php

/**
 * Class FnCloseBag
 * 时间:2018年02月18日16:24:40
 * 目的:学习如何操作闭包函数
 */
class FnCloseBag
{
    public function chunk()
    {
        //获取输入的参数,因为php就算定义没有要求输入参数,你输入参数也不会报错的,这就让你既可以输入参数也可以不输入参数
        //不过你直接定义参数,默认为空也是可以的,一切都是为了逼格
        $argv = func_get_args();

        if (empty($argv)) {
            echo 'hello?';
        }

        /****************要测试的话修改下数据库名,用户名,密码******************/
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'password');

        /**
         * @param $pdo 传入一个pdo对象,如果是框架直接调用框架里边的model就行了,我这里为了防止在递归里边多次创建对象
         * @param $argv 将chunk方法获取到的参数传入,因为函数作用域的原因,所以要传进去
         * @param int $next 游标的作用
         * @return bool
         */
        function re($pdo, $argv, $next = 0) {

            //这里使用sprintf是为了方便书写sql语句,拼接容易出错
            $sql = sprintf('select id, username from user limit %d, %d', $next, $argv[0]);
            $resource = $pdo -> query($sql);
            $data = $resource -> fetchAll(PDO::FETCH_ASSOC);

            //所有数据取完后,就退出这个递归
            if (!$data) {
                return false;
            }

            //这里起到游标的作用,每次取完一次数据后,向后移动指定的条数
            $next += $argv[0];

            //这里将数据传入用户传进来的函数
            $bool = $argv[1]($data);

            //如果在用户传进来的函数中执行结果返回false,那么就终止递归
            if ($bool === false) {
                return false;
            }

            //调用自己,形成递归,运行前确保有退出条件
            re($pdo, $argv, $next);
        }

        //开始递归调用函数
        re($pdo, $argv);
    }
}

//初始化对象
$fn = new FnCloseBag();

//调用方法
$fn -> chunk(2, function($data) {
    var_dump($data);

    //打印分割线是为了直观看出数据是分次取出的
    echo '<br>----------------------<br>';
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值