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.如果是一次性使用的函数,不能被重用,可以使用闭包函数
3. 使用array_work()函数配合匿名函数来减少foreach层数
4. 等等
php的匿名函数和闭包函数的更多相关文章
- Golang函数-匿名函数与闭包函数
Golang函数-匿名函数与闭包函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- swift1.2语言函数和闭包函数介绍
swift1.2语言函数和闭包函数介绍 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护. swift1.2语言函 ...
- python函数之闭包函数与无参装饰器
一.global与nonlocal #global x = 1 def f1(): global x # 声明此处是全部变量x x = 2 print(x) f1() # 调用f1后,修改了全局变量x ...
- php函数总结(闭包函数,匿名函数)
php函数总结 1.普通函数 2.变量函数 function myfun($a) { echo $a; } $b = "myfun"; $b("test"); ...
- php匿名函数和闭包函数及use关键字传参及Closure匿名函数类
php闭包函数用use传参有什么意义?答:use引用外层变量,比如全局变量 Closure,匿名函数,是php5.3的时候引入的,又称为Anonymous functions.字面意思也就是没有定义名 ...
- php匿名函数与闭包函数
匿名函数:没有名字的函数:并没有牵扯到应用其他函数的变量问题.仅仅是没有名字 $f=function($param){} 闭包:A函数中嵌套着B函数,B程序中有用到A的变量,当外部函数C调用函数A时, ...
- Python入门之函数的嵌套/名称空间/作用域/函数对象/闭包函数
本篇目录: 一.函数嵌套 二.函数名称空间与作用域 三.函数对象 四.闭包函数 ============================================================ ...
- 箭头函数,闭包函数中的this指向
在javscript中,this 是在函数运行时自动生成的一个内部指针,它指向函数的调用者. 箭头函数有些不同,它的this是继承而来, 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象. ...
- 小甲鱼零基础python课后题 P21 020函数:内嵌函数和闭包函数
测试题 0.如果希望在函数中修改全局变量的值,应该使用什么关键字? 答:globe 1.在嵌套函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字? 答:nonlocal 2.pyth ...
随机推荐
- async、await正确姿势
摘要 async.await是在C# 5.0之后引入的一种简化异步操作的方式.使用它们之后,可以使我们的编写异步操作更加方便快捷,维护以及阅读起来更方便. 一个例子 async.await虽然简化了我 ...
- 转载 HashSet用法
NET 3.5在System.Collections.Generic命名空间中包含一个新的集合类:HashSet<T>.这个集合类包含不重复项的无序列表.这种集合称为“集(set)”.集是 ...
- Java JDBC的基础知识(二)
在我的上一篇Java JDBC的基础知识(一)中,最后演示的代码在关闭资源的时候,仅仅用了try/catch语句,这里是有很大的隐患的.在程序创建连接之后,如果不进行关闭,会消耗更多的资源.创建连接之 ...
- 深入理解Java虚拟机--阅读笔记二
垃圾收集器与内存分配策略 一.判断对象是否已死 1.垃圾收集器在对堆进行回收前,要先判断对象是否已死.而判断的算法有引用计数算法和可达性分析算法: 2.引用计数算法是给对象添加引用计数器,有地方引用就 ...
- Docker入门及基本指令
Docker概念 Docker就相当于一个Github账号,不过最开始的工程不能自己建立,要从DockerHub这个中央仓库pull过来,这个工程Docker称之为image,这个image竟然是个l ...
- .net防止SQL注入的一种方式
首先也要明白一点,什么是SQL注入 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将 ...
- C#进行数据筛选(一)
这里介绍数据筛选的第一种方式,不用过滤器,给新手看得 public DataTable SourceList(string Wmain, string OrderNo, string Process) ...
- 理解Java异常
一.Java异常的简介 Java异常是Java提供的一种识别及响应错误的一致性机制.具体来说,异常机制提供了程序退出的安全通道.当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器.Ja ...
- C++11 使用 std::async创建异步程序
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...
- JavaScript--DOM操作表格及样式(21)
一 操作表格 // <table>标签是HTML中结构最为复杂的一个,我们可以通过DOM来创建生成它,或者HTMLDOM来操作它; // 使用DOM来创建表格; var table = d ...