php函数作用域与闭包|回调与参数-函数多值返回类型
- 实例演示函数作用域与闭包,回调的使用场景与参数调用;
- 实例演示函数的多值返回类型方式,重点是json
一、 php函数作用域与闭包
1.1函数作用域
作用域在函数中调用外部的变量
<?php
$name = '风萧萧兮易水寒';
$email = 'fxx@php.org';
$age = '18岁';
$school='燕京大学';
function demo1(): string
{
// 函数作用域: 只有调用它的时候才会创建
$res = '';
// 如果想在函数内部访问全局/外部的成员
// $res .= 'name = ' . $name . '<br>';
// 有二种方式可以在函数内部访问外部成员
// 1. global
global $name;
$res .= 'name = ' . $name . '<br>';
// 2. $GLOBALS,超全局数组不受作用域限制
$res .= 'email = ' . $GLOBALS['email'] . '<br>';
$res .= 'age = ' . $GLOBALS['age'] . '<br>';
$res .='$school='. $GLOBALS['school'] . '<br>';
// 私有变量: 外部不可见
$grade = 98;
$res .= 'grade = ' . $grade . '<br>';
return $res;
}
echo demo1();
echo '<hr>';
图示:
1.2闭包
<?php
$name = '风萧萧兮易水寒';
$email = 'fxx@php.org';
$age = '18岁';
$school='燕京大学';
// 闭包: 匿名函数
// 闭包: 可以访问函数外部的自由变量/父作用域中的变量
$use1= function () use ($name, $email,$age, $school) {
return sprintf('name = %s<br>email = %s<br>age = %s<br>school = %s<br>', $name, $email, $age, $school);
};
echo $use1(), '<hr>';
图示:
1.4 闭包支持引用传参: 参数前加 &
<?php
$name = '风萧萧兮易水寒';
$email = 'fxx@php.org';
$age = '18岁';
$school='燕京大学';
echo '当前: name = ' . $name . '<br>';
$demo = function ($myname) use (&$name) {
// 闭包中将引用参数更新后,会实时的映射
$name = $myname;
};
$demo('碧血书香梦');
echo '现在: name = ' . $name . '<br>';
图示:
use禁止使用以下三种参数
- 超全局不让用: $_GET
- $this
- 与当前参数重名不让用
1.5闭包经常用作函数的返回值
function demo2($a)
{
// 返回一个函数,闭包最佳使用场景
return function ($color) use ($a) {
return sprintf('<h1 style="color:%s">%s</h1>', $color, $a);
};
}
echo demo2('新时期最可爱的人!')('red');
二、回调函数
1.call_user_func(“函数名”,函数参数);
2.call_user_func_array(“函数名”,函数参数列表);
<?php
// 回调执行
function demo(string $name): string
{
return "welcome $name !";
}
echo demo('风萧萧兮易水寒'), '<hr>';
// php单线程,同步执行,如果遇到耗时函数会发生阻塞,应该将它改为异步回调执行
// call_user_func(函数,参数列表)
echo call_user_func('demo', '书香蓝郡'), '<hr>';
// call_user_func_array(函数,[参数数组])
echo call_user_func_array('demo', ['书香蓝郡']), '<hr>';
图示:
三、参数调用
1.必选参数:在函数调用时,必须传参
2.默认参数:参数有默认值,函数调用可以不传参
3.可选参数:参数数量不定;函数调用时传几个用几个,类似JS种的剩余参数
4.引用参数:参数前面加&引用符,引用参数,可以不用return直接实时改变函数外部的变量
3.1必选参数
<?php
// 1. 必选参数
function demo1(string $name): string
{
return "welcome $name !";
}
echo demo1('百度总裁李彦宏'), '<br>';
// 将标量(单值)会自动转为字符串
echo demo1(996), '<br>';
echo demo1(true), '<br>';
图示:
3.2 不定参数
<?php
// 不定参数
function user()
{
// 通过函数中内置的三个函数获取到参数的全部信息
// 1. 参数有几个?
$n = func_num_args();
//2. 参数组成的数组
$args = '[ ' . implode(', ', func_get_args()) . ' ]';
// 3. 获取某一个参数
// $arg = func_get_args()[3];
$arg = func_get_arg(3); // func_get_args()[3]
printf('参数数量: %d<br>参数数组: %s<br>第1个参数: %s<br>', $n, $args, $arg);
// 求和
// $res = 0;
// for ($i = 0; $i < func_num_args(); $i++) {
// $res += func_get_args()[$i];
// }
// echo '和'. $res;
echo '参数之和: ' . array_sum(func_get_args());
}
user(2, 3, 4, 5, 6, 7, 8);
图示:
//
3.3可选参数
<?php
// 可选参数
function user(string $name = 'www.baidu.com'):string
{
return "welcome $name !";
}
echo user(), '<br>';
echo user('百度总裁李彦宏');
图示:
3.4引用参数:
引用参数
js函数参数只支持值传递
php支持“值传递”和“引用传递”
默认就是值传递,上面全是
引用传参: 在函数内部对参数的任何更新都会实现映射到外部的参数中
<?php
$name = '红高粱';
// 引用传参在参数前使用: &
function user(string &$name)
{
$name = '战狼2';
}
echo "\$name = $name<br>";
user($name);
echo "\$name = $name<br>";
图示:
四、函数多值返回类型
函数的返回值
函数只允许有一个返回值
原则: “单值返回”
返回多值怎么办? 只能在返回值的类型上打主意
4.1函数数组返回值-数组
<?php
// 1. 数组
function user(): array
{
return ['namae' => '天蓬老师', 'age' => '18','mail'=>'tp@php.cn'];
}
var_dump(user());
图示:
4.2函数对象返回值-对象
<?php
//函数返回值-对象
function user(): object
{
//创建一个匿名类返回
return new class()
{
public $name = '天蓬老师';
public $age = 18;
public $mail ='tp@php.cn';
};
}
//把函数赋给一个变量
$user = user();
//使用变量调用
var_dump($user);
//调用对象中的一个元素
echo $user->mail;
图示:
4.3函数对象返回值-序列化的字符串
1.php内置的序列化函数
如果有一些数据需要进行网络传输或保存到文件或数据表中的时候要用到它
如果这个序列化的数据只在php程序中使用,应该使用php内置的方法就可以了
<?php
// 内置的序列化函数
function user(): string
{
return serialize(['status' => 1, 'message' => '验证成功']);
}
$str = user();
echo $str;
// file_put_contents('file.txt', $str);
// 在php中使用时要还原成原来的类型
$arr = unserialize($str);
var_dump($arr);
echo '<hr>';
图示:
2.转为通用的json格式的字符串
这样就可以与其它编程语言进行数据交换,例如与前端js,java,python…
<?php
function user1(): string
{
return json_encode(['status' => 1, 'message' => '验证成功'], JSON_UNESCAPED_UNICODE);
}
$str = user1();
echo $str;
// 如果当前脚本接收到一个前端或其它接口发送过来的json格式的数据,可以进行解析
// 解析的目的是将外部的json还原成php能够处理的数据类型
$res=json_decode($str);
var_dump($res);
echo '<br>';
// 默认将外部的json解析成object对象类型
printf('status = %d, message = %s<hr>',$res->status, $res->message);
3.转为通用的json格式的字符串也可用数组方式
<?php
// 给 json_decode()传入第二个参数 : true
$res=json_decode($str, true);
var_dump($res);
echo '<br>';
printf('status = %d, message = %s<hr>',$res['status'], $res['message']);
图示:
五、静态变量
// 静态变量
function demo1()
{
// 函数中的静态变量不会随函数调用结束而消失
// 他会自动进入到下一次的函数调用中
// 可以实现在函数的多次调用过程中:共享数据 / 数据通信
static $i = 1;
echo $i,'<br>';
$i++;
}
// echo $i;
echo demo1();
echo demo1();
echo demo1();
echo demo1();
echo demo1();