php的匿名函数和闭包函数
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获取函数定义时的副作用域变量,不管在何时调用。如果要获取调用时的变量值,需要用引用传递。具体怎么使用就要看什么使用场景了。
列举了几种常用的场景
- 作为回调函数
//一个我们使用过的例子
<?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.如果是一次性使用的函数,不能被重用,可以使用闭包函数
- 使用array_work()函数配合匿名函数来减少foreach层数
- 等等

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Linux信号专题FAQ
信号: 基本概念 可重入、线程安全以及异步信号安全的区别? 参考可重入、线程安全和异步信号安全,需要强调的是异步信号安全,这个概念知道的人不多,平常大家在编写代码的时候也很少考虑这个因素,也不清楚哪些函数是异步信号安全的,哪些不是,典型的像printf就不是异步信号安全的,内部会加锁,但是平时很多人都喜欢在信号处理函数中调用。大多数情况下都不会出现问题的,所以让使用者错误的认为这是正确的写法。第二个需要注意的是可重入的概念,Linux有很不少系统调用的实现都是不可重入的,会将结果保存在内部的静态数据存储中,同时这类系统调用也提供了可重入版本的实现,其函数名就是尾部添加_r来标识。 信号的内部实现是怎么样的? 如上图所示一个进程/线程就是一个task_struct结构,该结构包含了属于这个进程/线程的阻塞信号集、pendi
-
下一篇
JavaScript学习之旅-8(原创)
在上一篇文章中,花了很大的篇幅主要是学习了JavaScript中变量的作用域与解构赋值,这一篇主要学习JavaScript的this关键字。 说到this关键字,我们首先回顾下,在Java中,this关键字主要有以下三个作用。 (1)this调用本类中的属性,也就是指向类中的声明成员变量;比如 this.name= name;(伪代码)在方法中将形式参数name的值赋值给成员变量name (2)this调用本类中的其他方法 (3)this调用本类中的其他构造方法,调用时要放在构造方法的首行 简单说完了Java中的this,我们在说说JavaScript中的this,先写一个关于this的小demo this - 1 首先,我们定义了一个 objec的对象,然后定义 age字段的时候,我们使用的是 当前日期对象的 年 字段减去 this.birth,最后打印的结果是 2018 — 1992 = 26。 概念一: 在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是objec这个变量。所以,this.birth可以拿到objec的birth属性。 我们换一种写法, this ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL数据库在高并发下的优化方案
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Docker容器配置,解决镜像无法拉取问题
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker快速安装Oracle11G,搭建oracle11g学习环境