回调函数/递归函数
[toc] //md 内容表
1. 回调函数(主次分明类似游戏的主线任务/支线任务,做主线时又突然去做支线,支线做完又回来做主线)
- 将一个用户自定的”执行过程”当做参数传递给到函数中,大大滴增大了对该函数功能的扩展
- 调用函数时不传递标准的变量作为参数,而是将另一个函数作为参数传递到调用的函数中
- 匿名函数作为回调函数的参数
$func = function($a,$b)
{
return $a+$b;
};
function test(Closure $callback)
{
$a = 10;
$b= 20;
echo $callback($a,$b);
}
test($func);
耗时函数
function demo(string $name):string
{
return ‘你好’.$name; //实际上是大量代码
}demo('灭绝老师');
//传统调用方法
- 回调一个全局函数
echo call_user_func(‘demo’,’灭绝老师’);
echo call_user_func_array(‘demo’,[‘朱老师’]);
- 回调匿名函数
$sql = “SELECT
name
,phone
FROMoyk_school
“;
$demo1 = function($dsn,$username,$password) use ($sql)
{
$pdo = new PDO($dsn,$username,$password);
// 准备预处理语句
$stmt = $pdo->prepare($sql);
// 执行 sql 语句
$stmt->execute();
// 取结果集返回
return $stmt->fetchALL(PDO::FETCH_ASSOC);
};
$res = call_user_func_array($demo1,[‘mysql:dbname=chloe’,’root’,’zhoujielun521’]);
print_r($res);
- 回调对象/类中的方法
2. 递归函数
- 函数自身调用自身,但必须在调用自身前有条件判断,否则无限无限调用下去
- 处理树形结构的程序
// 声明缓存目录
function delete_dir_file($dir)
{
//声明一个初始状态 默认情况下缓存未被删除
$flag = false;
if(is_dir($dir))
{
//成功打开目录流
if($handle = opendir($dir))
{ //readdir打开目录句柄
while (($file = readdir($handle)) !== false){
if($file != ‘.’ && $file != ‘..’ )
{
if(is_dir($dir.’\‘.$file)){
//递归处理文件夹/目录
delete_dir_file($dir.’\‘.$file);
}else{
//unlink只能删除一个文件
unlink($dir.’\‘.$file);
}
}
}
}
//关闭目录句柄
closedir($handle);
//目录只有为空的情况下才能被直接删除 rmdir()
if(rmdir($dir))
{
$flag = true;
}
}
return $flag;
}
$app_path = DIR ;
if(delete_dir_file($app_path))
{
return json_encode(‘删除成功’);
}
笔记
- 带临时变量的耗时短,因为他会被用后释放掉
- echo call_user_func_array(‘demo’,[‘朱老师’]);相当于开了后门
- array_walk array_map 处理数组的元素,属于回调函数主次分明,foreach 是直接去遍历,相当于主线程(效率更高)
- php 脚本是单线程, 脚本是同步执行的,如果遇到耗时函数将会发生线程的阻塞,应该将它改为异步回调执行
- 回调匿名函数时是$demo1,回调全局函数是’demo’!!!
- return $stmt->fetchALL(PDO::FETCH_ASSOC); 返回的是关联数组
- `return $stmt->fetchALL(); 返回的是索引数组加关联数组
- 递归函数时是$demo1,回调全局函数是’demo’!!!
__DIR__
魔术常量,定位当前文件盘【的绝对路径__DIR__
魔术常量,定位当前文件的绝对路径<meta http-equiv="Refresh" content="2;URL=https://www.php.cn/">
//2 秒后会跳转到 php 中文网,Refresh 是自动刷新