php的匿名函数和闭包函数-阿里云开发者社区

开发者社区> 相思叶> 正文

php的匿名函数和闭包函数

简介: php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因为大家习惯上写了函数就是用来调用的,匿名函数和闭包函数做什么用的? 匿名函数 php官方解释如下: 匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。
+关注继续查看

php的匿名函数和闭包函数

tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use


引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因为大家习惯上写了函数就是用来调用的,匿名函数和闭包函数做什么用的?

匿名函数

php官方解释如下:
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。

这里说的很简单,可以用做回调函数,下面例子就是作为回调函数

<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);
}, 'hello-world');
// 输出 helloWorld
?>

上述例子中,preg_replace_callback 函数需要三个参数,第一个参数是一个正则表达式用来匹配数据,第二个参数是一个函数,第三个参数是需要匹配的字符串,也可以像下面这样写

<?php
$testFunc = function ($match) {
        return strtoupper($match[1]);
    };

echo preg_replace_callback('~-([a-z])~', $testFunc, 'hello-world');
// 输出 helloWorld
?>

但是我们看到这个方法显然我们只需要用一次,所以没有必要再给他去命名,也没有多大的必要再去把他赋值给一个变量(赋值给变量的过程:PHP 会自动把此种表达式转换成内置类 Closure 的对象实例赋值给变量)

闭包函数

php中匿名函数也叫闭包函数,所以没什么区别。但是一般意义上的闭包的概念不是这样的,我们先说一下传统意义上的闭包,并提供一篇文章中js中的闭包用来和php中的闭包(匿名函数)进行对比。
学习Javascript闭包(Closure)---阮一峰

php中其实没有传统意义上的闭包函数,因为php中的函数不能调用夫作用域中的变量。如下

<?php
    function a(){
        $a = 11;
        function b(){
            $b = 22;
            echo $a;
            echo $b;
        }
        b();
    }
    a();
//报Notice:Undefined variable: a in index.php on line 6
//22
?>

而看上面文章中得知,js中是可以的。所以php中匿名函数也叫闭包函数,也可以传递父作用域的变量进闭包函数(达到了类似js获取父作用域变量的效果),php中使用的是use关键字,具体如下

<?php
$count = 0;

$a = function()
{ var_dump($count); };

$b = function() use ($count)
{ var_dump($count); };

$count++;

$c = function() use (&$count)
{ var_dump($count); };

$count++;

$a();    // null   Notice: Undefined variable: count in
$b();    // int 0
$c();    // int 2
$count++;
$b();    // int 0

?>

上述例子的输出和你认为的是不是不同呢。

解析:闭包函数(匿名函数)使用use获取函数定义时的副作用域变量,不管在何时调用。如果要获取调用时的变量值,需要用引用传递。具体怎么使用就要看什么使用场景了。

列举了几种常用的场景

  1. 作为回调函数
//一个我们使用过的例子
<?php
    /*
     * 菜谱拆分食物后的拼接
     * 参数均不能为空
     * */
    public function mergeFoodsStr($str,array $mapping){
//        $str = '白菜半棵、__2__鲍菇两只、__0__一根,__1__两根,三者比例为100:100:15,酱油5克,香油2克,盐1克。';
//        $mapping = array(
//            0 =>array('name' => '胡萝卜','id' =>  '81' ),
//            1 =>array ( 'name' => '萝卜', 'id' =>  '72'),
//            2 =>array ( 'name' =>  '杏', 'id' => '1841')
//        );
        if(empty($str) || empty($mapping)){
            return false;
        }
        $strNew = preg_replace_callback('"|__(\d)__|" ',function ($matches) use ($mapping){
            return $mapping[$matches[1]]['name'];
        },$str);
        $this->log('拼接后的食材字符串',$strNew);
        return $strNew;
    }
?>
   

2.如果是一次性使用的函数,不能被重用,可以使用闭包函数

  1. 使用array_work()函数配合匿名函数来减少foreach层数
  2. 等等
希望大家多评论交流,互相学习

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[实变函数]5.6 Lebesgue 积分的几何意义 $\bullet$ Fubini 定理
1 本节推广数学分析中的 Fubini 定理. 为此, 先引入 (1)(从低到高) 对 $A\subset \bbR^p, B\subset\bbR^q$, $$\bex A\times B=\sed{(x,y);x\in A, y\in B} \eex$$ 称为 $A$ 与 $B$ 的直积 (direct product).
1037 0
14.Linux shell编程(函数)
(创建于2018/2/1) 1.简单的一个函数 1 #!/bin/bash 2 3...
704 0
7.4 匿名函数和高阶函数
1、匿名函数:没有名字的函数 def sum(s, y):     return x * y m = lambda x, y: x * y print(m) print(m(4, 5)) 2、sorted() 高阶函数 对字典进行排序 mm=dict(a=1,c=10,b=4,d=9) for i in mm:     print(i) for j in mm.
659 0
函数 - PHP手册笔记
原文:函数 - PHP手册笔记 用户自定义函数 函数无需在调用前被定义,除非是有条件定义的。 PHP中的所有函数和类都具有全局作用域。PHP不支持函数重载,也不可能取消定义或者重定义已声明的函数。 特意试了下,我的电脑上的PHP递归栈的最大深度为100。
732 0
lambda匿名函数使用
#!/usr/bin/pythonfun=lambda x:x*x-xprint fun(3)
435 0
+关注
14
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载