:-: 一、函数是什么


:-: 二、函数的分类

根据函数的提供者(编写者),分为二类


:-: 三、函数的基本语法

function func_name(参数列表)
{
    //函数体: 由一条或多条语句组成,可以为空
}

:-: 四、函数作用域


:-: 五、PHP中的函数知识,实例

1、函数的常规声明与调用

// 使用关键字function 声明函数
// 函数名称必须符合php关于标识符的约定
// 函数需要接收的参数写到函数名后的一对括号内
function sum(){
	// 函数可以有return 语句,将执行结果返回给调用者
	return 1+1;
	// 如果不有 return 返回 null
}
echo sum();

2、函数的参数

// 括号内的参数列表, 是形式参数,通常与实参一一对应
// 实参必须被初始化, 可以被实参, 也可以用默认值
function sum($a, $b){
	// $c 是函数自已的私有变量, 也叫局部变量,对外不可见
	$c = $a + $b;
	return $c;
}

// 调用
// 按名称调用,必须在函数名后面添加一对圆括号
// 将调用参数写到括号内
// 括号内的参数叫实际参数, 简称: 实参
echo sum(10, 20);

// 函数内的私有变量,外部不可访问
// echo $c;
// echo '<hr>';

3、函数参数的默认值

function sum($a = 20, $b = 30){
	$c = $a + $b;
	return $c;
}

echo '<per>';
// 全部赋值,使用自定义的值
echo sum(10, 15), '<br>';
// 只给$a赋值,$b取默认值
echo sum(10), '<br>';
// 全部取默认值
echo sum(), '<br>';
echo '<hr>';

4、函数不固定参数数量

// 一、形参列表只是占位符,可以在函数中获取调用的实参
function sum1(){
	// 获取实参的数量
	$argNum = func_num_args(); // 无参数
	echo $argNum;

	// 获取实参组成的数组
	$argArr = func_get_args(); // 无参数
	print_r($argArr);

	// 获取每一个参数
	echo func_get_arg(0); // 第一个实参
	echo func_get_arg(1); // 第二个实参

	// 1,计算二个数的和
	$a = func_get_arg(0);
	$b = func_get_arg(1);
	return $a + $b;

	// 2,使用实参数组来简化,计算二个数的和
	$total = 0;
	foreach ($argArr as $value) {
		$total += $value;
	}
	return $total;

	// 3,以上数组求和,可以使用数组函数arrya_sum()简化,计算二个数的和
	return array_sum($argArr);
}

echo sum1(10, 20);
echo '<br>';

// 函数内部使用参数循环时可以计算任意数量的数据之和
echo sum1(10, 20, 30, 40, 50);
echo '<hr>';

// 二、php7, 提供了一种可变长参数, 可以替代func_get_args()函数
function sum2(...$params){
	// 变长参数的标示 ...
	// 将实参全部打包到形参变量$params中
	print_r($params);

	// 实现上例的累加操作
	$total = 0;
	foreach ($params as $value) {
		$total += $value;
	}
	return $total;
}

echo sum2(1,2,3,4,5);
echo '<hr>';

// 三、变长参数的一个应用场景
function sum3($a, $b, ...$c){
	// $a=1, $b=2, 剩下参数全部打包到数组$c中, $c=[3,4,5,6]
	return '$a='.$a.', $b='.$b .'<br>'. print_r($c, true);
}

echo sum3(1,2,3,4,5,6);
echo '<hr>';

// 四、变长的实参
function sum4($a,$b,$c,$d){
	return $a+$b+$c+$d;
}

$arr = [6,7,8];
echo sum4(2,...$arr);
echo '<br>';

// $arr 会用... 自动展开, 等价于这样调用
echo sum4(2,6,7,8);
echo '<hr>';

// 五、php7, 可以对参数类型进行限制
function sum5(int $a,...$arr){
	// 限制了参数整数类型, 2.5转为2, '5' 被强制转换成整数5
	return $a + array_sum($arr);
}

echo sum5(2.5, 3, 4, '5');

5、函数的返回值

// 1、return 返回值
function demo1(){
	// 可以使用返回语句: return 返回执行结果
	return 'Hello PHP';
}
echo demo1();
echo '<hr>';

// 2、如果没有return , 默认返回 null
function demo2(){

}
// 检测返回值的类型
echo is_null(demo2()) ? '返回NULL' : '没有返回NULL';
echo '<hr>';

// 3、函数不允许返回多个值
function demo3(){
	$a = 10;
	$b = 20;
	// return 返回多个值报错
	return $a,$b;
}
echo demo3();

// 4、函数返回多个值,用数组返回
function demo4(){
	$a = 10;
	$b = 20;
	return [$a, $b];
}
echo '<pre>' . print_r(demo4(),true);

// 5、php7中, 可以限定函数的返回类型
function demo5($a, $b) :int{
	return $a + $b;
}
// 不限定返回类型,输出: 4.7, 限定后返回: 4
echo demo5(1.4, 3.3);

6、函数中的变量访问

// 1、函数中的变量访问
$site = 'www.php.cn';
function demo1(){
	// 函数中不能直接访问外部变量
	return $site;
}
echo demo1();
echo '<hr>';

// 2、函数中的全局变量访问
$site = 'www.php.cn';
function demo2(){
	// 在函数中使用global关键字声明一下$site是一个全局变量
	// 这样, 函数中就可识别出这个$site变量
	global $site;
	// 函数中不能直接访问外部变量
	return $site;
}
echo '<per>';
echo demo2();
echo '<hr>';

// 3、函数外部声明的变量,会自动成为超全局变量数组$GLOBALS的成员
$site = 'www.php.cn';
echo $GLOBALS['site'];
echo '<hr>';
function demo3(){
	// 超全局变量不受作用域限制,可以在脚本的任何地方使用,当然也包括函数内
	return $GLOBALS['site'];
}
echo demo3();

// 4、常量也不受作用域的限制,可以在脚本的任何地方使用
// 所谓常量,可以理解为只读变量, 一经定义不允许更新或删除
define('SITE_NAME', 'PHP中文网');
function demo4(){
	return SITE_NAME;
}
echo demo4();

// 5、外部如何访问函数的私有变量
function demo5(){
	$email = 'ouyangke@php.cn';
	// 通过return 返回私有变量到外部调用者
	return $email;
}
echo demo5();

7、匿名函数与闭包

// 1、匿名函数, 做为值来使用
$sum = function ($a, $b) {
	return $a + $b;
};
echo $sum(5,6);

// 2、匿名函数: 做为回调参数来使用
$arr = [3,1,6,2,9];
usort($arr, function ($a, $b){
	// >0, 由小到大
	// =0, 相等
	// <0, 由大到小
	return $a - $b; // asc
	// return $b - $a; // desc
});
print_r($arr);

// 3、php7中, 对于这类比较运算, 有一个更简洁的语法:太空船操作符
$arr = [3,1,6,2,9];
usort($arr, function ($a, $b){
	return $a <=> $b;
	return $b <=> $a;
});
print_r($arr);

// 4、获取父作用域中的变量
$name = '欧阳克';
$f1 = function (){
	// 直接获取外部变量,是取不到的
	return $name;
};
echo $f1();

// 5、获取父作用域中的变量
$name = '欧阳克';
$f2 = function() use ($email) {
	return $email;
};
echo $f2();

// 6、大多数情况下, 我们会在闭包函数中对外部变量进行更新
// 这时可以将外部变量以引用的方式传入
// 默认情况下,参数是以值的方式传到函数中,所谓引用, 就是内外部实际访问的是同一个变量
// 只需要在参数前添加一个取地址符: & 即可
$name = '欧阳克';
$f3 = function() use (&$name) {
	return $name = '黄蓉';
};
echo $f3();

// 7、在子函数中的使用
function demo(){
	$name = '欧阳克';
	return function () use ($name) {
		return $name;
	};
}
//demo()返回结果是函数, 所以需要再次调用
echo demo()();

[danger] 备:将一个函数的返回值,设置为一个闭包函数, 在实际开发中非常有用的, 等后面遇到具体应用场景时再细说