1.函数作用域
- php中函数的作用域有两个,一个函数作用域,一个是全局作用域.
- 在函数作用域中不能访问函数的父级变量.
例:
/**
* 1.php中,函数作用域只用两种,一种是函数作用域,一种是全局作用域.
* 2.在函数中不能访问父级变量(外层变量), 见例1
*/
// 例1:
$name = '张三';
function func (){
echo "你好, {$name}";
}
func(); // 你好,
- 要想访问外部变量,有两种方法:
// 例1:1️⃣.在函数内使用global关键字
2️⃣.在函数内部使用超全局标量$GLOBALS:例2
$name1 = '张三';
$name2 = '李四';
function func1 (){
global $name1;
echo "你好, {$name1},{$GLOBALS['name2']}";
}
func1(); // 你好,
2. 闭包:匿名函数(需要保存到变量中)
想要声明一个闭包函数,只要在函数中添加一个use()就行.
使用方式:$func = function (variable) use (外部变量){};
例子:
$func2 = function (string $str) use ($name) : string {
return $str . $name . '<br>';
};
echo $func2($name2);
echo $func2('王二麻子');
//
闭包函数多用于函数返回:
// 闭包函数多用于函数返回
function func4 (string $name) : object {
return function ($password) use ($name){
return sprintf("亲爱的玩家: %s, 欢迎回来!您的登录密码为: %s!<br>", $name,$password);
};
}
// 调用1
$fm= func4('admin');
echo $fm('123456');
// 调用2
echo func4('main')('123456');
3. 回调的使用场景
php是单线程同步执行的,但是有些情况下如果一个函数出现了阻塞情况,会导致程序暂时性的停止,直到这个函数执行成功才会继续向下执行,这样会浪费大量的时间.
这个时候就需要把这个会发生阻塞的函数改为回调执行.
回调执行的方法:
/**
* php是单线程同步执行的,但是有些情况下如果一个函数出现了阻塞情况,会导致程序暂时性的停止,直到这个函数执行成功才会继续向下执行,
* 这样会浪费大量的时间.这个时候就需要把这个会发生阻塞的函数改为回调执行.回调执行的方法:
* 1. call_user_func(函数, 函数参数); // 单参数的情况下时使用
* 2. call_user_func_array(函数, [函数参数]); // 通用
* 如果调用的是对象实例方法的话,需要把第一个参数修改一下:call_user_func_array([new 类名, 方法名], [函数参数]);
* 如果调用的是静态对象实例方法的话,需要把第一个参数修改一下:call_user_func_array([类名, 静态方法名], [函数参数])
* 或者call_user_func_array('类名::静态方法名', [函数参数])
*/
例:
class callbackFunctionTest {
public function test1($name, $age) {
echo "姓名: {$name}, 性别: {$age}<br>";
}
public static function test2($name, $age) {
call_user_func_array((new callbackFunctionTest())->test1, ['张三','18']); // 方法回调
echo "姓名: {$name}, 性别: {$age}<br>";
}
}
call_user_func_array([new callbackFunctionTest(), 'test1'], ['张三','18']);
call_user_func_array(['callbackFunctionTest', 'test2'],['李四','19']);
call_user_func_array('callbackFunctionTest::test2',['李四','19']);
4. 参数调用
4.1 必须参数
/**
* 必选参数
*/
function demo1($name) {
echo $name . '<br>';
}
demo1('必选参数');
4.2 可须参数
/**
* 可选参数
* 在函数中,可以设置接收参数的默认值
* 注意: 可选参数必须放在接收参数的为后面.原因: 函数中,参数的传递是按照顺序传递的,并不是相应的key对应value的形式.如果不放到最后,传参时
* 就要预留一个或者多个空参,如这样:demo('admin','','18'); function(name, sex = '男', age){}.
*/
function demo2($name = '张三123') {
echo $name . '<br>';
}
demo2();
demo2('李四');
4.3 不定参数
//1,使用函数内部的函数获取参数
function demo31() {
// 获取传递了几个参数
$num = func_num_args();
echo "传递了{$num}个参数<br>";
// 获取所有参数数组
$arrs = '[' . implode(',', func_get_args()) . ']<br>'; //print_r(func_get_args());
echo "所有的参数分别是: {$arrs}<br>";
// 获取单个参数
$arr1 = func_get_args()[0]; // 获取第一个参数
$arr2 = func_get_arg(1); // 获取第二个参数
echo "第一个参数是: {$arr1},第二个参数是: {$arr2}<br>";
}
demo31('1', '2', '3', '4', '5');
//2,使用...rest语法,剩余参数
function demo32(...$age) {
print_r($age);
echo '<br>';
}
demo32('1', '2', '3', '4', '5');
4.4 引用参数
php中参数传递费为两种一种是”值传递”(默认),一种是”引用传递”.想要是想引用传递很简单,只要在参数前面加一个&(取地址符)就好了.例子:
$name = '张三';
function demo(string &$name) : string {
$name = '李四';
return "你好, {$name}";
}
$name = '张三';
function demo(string &$name) : string {
$name = '李四';
return "你好, {$name}";
}
echo "改变前: {$name}<br>";
demo($name); // $name的值会改变.
echo "改变后: {$name}<br>";
5. 多值返回类型方式
5.1 数组形式
function returnManner() {
$a = [];
for ($i = 0; $i<10; $i++){
$a[$i] = $i;
}
return $a;
}
print_r(returnManner());
echo '<br>';
5.2 对象形式:匿名类
function returnManner1(){
return new class {
public $name = 'admin';
public $age = 18;
function qwer(){
echo "我是方法<br>";
}
};
}
5.3 序列化返回: 多用于网络请求或者是本地化(保存到本地文件或者数据表(数据库))保存
// php内部使用:序列化:serialize(),反序列化: unserialize()
function returnManner2() {
$a = [];
for ($i = 0; $i<10; $i++){
$a[$i] = (string)$i;
}
return serialize($a);
}
echo returnManner2() . "<br>";
print_r(unserialize(returnManner2()));
echo "<br>";
// 通用: 序列化json_encode(),反序列化json_decode()
function returnManner3() {
$a = [];
for ($i = 0; $i<10; $i++){
$a[$i] = (string)$i;
}
return json_encode($a);
}
echo returnManner3() . "<br>";
print_r(json_decode(returnManner3()));
echo "<br>";