开发者学堂课程【PHP 基础入门课程(下):匿名函数闭包】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/710/detail/12643
匿名函数闭包
内容介绍:
一、匿名函数闭包概念
二、小结
一、概念
1、概念
闭包:闭包( closure )是一个定义在函数内,能够读取其他函数内部变量的函数(闭包函数)
(1)函数定义在某个函数内部(内部函数)
(2)内部函数是匿名函数
(3)内部函数访问外部函数的局部变量
·不能直接访问
·访问使用 use
2、示例
1、简单闭包函数
function outer(){
$inner = function outer(){
echo ‘hello world’;
};
inner();
}
outer();
#输出 hello world
<? php
#闭包函数
function outer (){
#定义内部函数(闭包函数)
$inner = function (){
echo _ FUNCTION _;
};
$inner ();
}
outer();
如下图,进行外部调用,若语法无问题,调用 outer 后可成功输出,但输出的不是函数名,而是 closure(闭包),因此使用 function 关键字无法实现操作,无对应的函数名只能判定为闭包,以上操作是闭包的简单运用。
通常不会如此使用,无任何含义,闭包函数是函数内部的函数,若仅自己工作无大的价值,一般会使用到外部的参数。
2、闭包函数访问内部变量
1 function outer1(
$ str ){
echo $str ;
#定义内部函数(闭包函数
$inner =function (){
echo ‘inner ’,$ str ;
};
$inner ();
}
outer1(' hello ');
执行操作后输出的结果如下:
Inner 成功输出,$str 没有输出,说明 $str 使用失败,其原因是:无论是匿名函数还是有名函数,都有自己的作用域,函数的作用域是局部作用域(花括号以内),
因此会发现,以下 inner 使用的是花括号内的变量(也称为局部变量),包括自己传输进来的参数,但是对于以下函数以外的都属于外部变量,外部变量不能访问,且此变量非全局变量而是局部变量,在其中不能使用 logo ,所以只能使用闭包自己的形式。
$inner =function (){
echo ‘inner ’,$str ;
};
必须使用 use 关键字后面跟一个括号,将外面函数的变量传输进去,内部函数才能访问。
#错误示例
function outer ( $str ){
$inner = function {
echo $str ;
}
$inner();
}
outer (' hello world ');
#报错:提示未定义变量 $str
原理:
· outer 是一个函数, $str 是 outer 的一个形参,也就是局部变量,只能在函数内部访问
· $inner 是一个函数,函数内部只能访问局部变量,而 $str 对于匿名函数 $inner 来说是外部的,所以不可访问
#正确示例
function outer ( $str ){
$inner = function() use ( $str ){
echo $str ;
};
$inner() ;
}
outer (' hello world ');
#输出 hello world
内部定义了一个闭包函数,可以给外部使用。
3、闭包函数可以返回给外部函数调用出,这样可以使得闭包所占用的外部函数资源不会被释放
如下操作:
function outer2($str){
$inner = function() use ($str){
echo $str;
};
#返回匿名函数
return $inner;
}
$res = outer2(‘world’);
Var_dump($res)
结果是超纲的对象,明确是闭包
再执行 $res()
;结果是 world 被输出了,
当运行 $res
时,代表 $res = outer2(‘world’);
此行运行完成,意味着函数结束了,函数结束会释放自己的所有资源,$res
是一个局部变量,一旦 $res
被释放了,$res
再使用时,world 是存放在 $res
已经被释放掉了,此时是闭包资源占有的问题。
#正确示例
function outer ( $str ){
$inner = function ( $s ) use ( $str ){
echo $str . $s ;
};
return $inner ;
$res = outer ('he1lo');
$res (wor1d');
#输出 helloworld
原理:
·函数 outer 调用结束,本要释放所有内存
·outer 返向了一个内部闭包函数的引用,所以函数不会释放到该函数,此时系统检测并运用到了外部函数变量
·$inner 内部闭包函数引用了一个外部函数的局部变量,所以 outer 也不能释放 $str
·$res (‘ world ’)
找到函数执行,并且应用了之前函数的局部变量 $str ,所以组合输出 hello world
二、小结
1、匿名闭包函数是在函数内部定义的匿名函数
2、虽然闭包函数在函数内部,但是也不能直接访问外部函数的局部变量,需要使用 use 来引用外部函数变量
3、闭包函数一旦引用了外部函数的局部变量,那么外部函数执行完之后,被引用的局部变量也不会被释放。
4、闭包函数可以被返回给外部函数调用出,然后在其他时候直接调用内部闭包函数。