1. 函数的声明与调用
<?php
// 函数是代码复用的重要手段
// 复习:变量是数据复用的重要手段
// 函数是通过调用函数来执行的,其规范要求:
// 1. 函数的名称要提示出它的功能
// 2. 函数名称以数字或下划线开头(不能以数字开头)
// 声明一个函数如下:
function name(){
// 执行代码
}
// 调用一个函数如下:
name();
// 示例:对两个整数求积
function multiplication( int $x, int $y):int
{
return $x*$y;
}
echo multiplication(5,5);
2. 函数的类型
按照其功能和结构可将函数划分以下几类:
自定义函数
系统函数
可变函数
匿名函数
示例如下:
<?php
// 1. 自定义函数:由用户自定义函数,用户自己取函数名
function show(string $str):string
{
return $str;
}
echo show('hello world'),'<hr>';
// 2. 系统函数:php内置的函数,拿来就用
$num = rand(1,10); // 产生一个1-10的随机整数
echo $num,'<br>';
echo rand(50,60),'<hr>';
// 3. 可变函数,与可变变量一样,它是把函数名变为另一个变量的值
function password(int $num):int
{
return $num;
}
$var = 'password';
// 用函数名调用函数
echo password(123456),'<br>';
// 用变量调用
echo $var(666666),'<hr>';
// 4. 匿名函数:没有定义名字的函数,比如把整个函数赋值给一个变量
$avg = function(float $score1, float $score2):float
{
return ($score1 + $score2)/2;
};
echo '平均分是:'.$avg(80,65),'<hr>';
// 注:匿名函数可以访问父作用域中的变量,在php中也称为闭包
// 示例一:当父作用域是全局时
$standard = 85; // 这是一个全局变量
$compare = function(float $score1, float $score2, float $score3) use($standard):string
{
$avg = ($score1 + $score2 + $score3)/3;
return $avg >= $standard ? '成绩合格' : '成绩不合格';
};
echo $compare(88,88,90),'<hr>';
// 示例二:当父作用域是父函数时
//父函数定义一个标准成绩分数
$st = function($stand){
// 子函数定义一个用平均分和标准分比较的函数
$compare = function(float $score1, float $score2, float $score3) use($stand):string
{
$avg = ($score1 + $score2 + $score3)/3;
return $avg >= $stand ? '成绩合格' : '成绩不合格';
};
return $compare; // 这一步一定要有,把函数以返回值的形式返回给调用者
};
echo $st(90)(80,60,56);
// 注:使用匿名函数访问父作用域中的变量时,一定要在匿名函数后面加上"use(父作用域中的变量)"
3. 函数的返回值
示例如下:
<?php
// 函数是必须有返回值的,示例如下:
function name(){}
var_dump(name()); // NULL,说明函数是有返回值的,只不过没有定义内容,为空
echo '<hr>';
// 函数是只能返回单一值的,如果要实现多值返回,有以下几种方法
// 方法一:通过字符串拼接的方式
function change1():string
{
$str1 = 'hello';
$str2 = 'world';
return $str1.' '.'<span style="color:red;">'.$str2.'</span>';
}
echo change1(),'<hr>';
// 方法二:通过数组的方式
function change2():array
{
$str1 = 'hello';
$str2 = 'world';
return ['str1' => $str1,'str2' => $str2];
}
print_r(change2());
echo '<br>',(change2()['str2']),'<hr>';
// 方式三:通过json对象字面量字符串的方式
function change3():string
{
$str1 = 'hello';
$str2 = 'world';
return json_encode(['str1' => $str1,'str2' => $str2]);
}
echo change3(),'<br>';
// 还原后变为json对象
print_r(json_decode(change3()));
echo '<hr>';
// 方式四:序列化方式
function change4():string
{
$str1 = 'hello';
$str2 = 'world';
return serialize(['str1' => $str1,'str2' => $str2]);
}
echo change4(),'<br>';
// 反序列化后还原为数组
print_r(unserialize(change4()));
4. 函数的参数
示例如下:
<?php
// 函数中的参数有几下几种
// 1. 值参数,默认方式,不会改变变量的值
// 示例:求长方形的周长
function girth(float $width, float $hight):float
{
return ($width + $hight)*2;
}
$width = 1.5;
$hight = 2.8;
echo girth($width,$hight),'<br>';
echo $width,'<br>',$hight,'<hr>';
// 2.引用参数,在参数前面加上取地址符&
function square(float &$s):float
{
return $s /= 2; //加上取地址符后的参数,它的值变化也会使函数外部的值产生变化
}
$square = 40;
echo square($square),'<br>';
echo $square,'<hr>'; //这里的输出结果变为了20
// 3. 默认参数:就是在传参数的时候给定参数一个默认取值
function user(string $username = 'root'):string
{
return $username;
}
// 调用时不传参数会输出默认参数值
echo user(),'<br>';
// 调用时传入参数则会取代默认参数值
echo user('alice'),'<hr>';
// 注:在传入多个参数时,必须将有参数值的放在最后面,如下:
// function user(string $usename1, string $username2, string $username3 = 'root'):string {}
// 4. 剩余参数:就是当传入函数的参数数量和调用时的参数数量不一致时
$get = function ($count)
{
$avg = function (int $num1, int $num2, int $num3) use($count) :float
{
return ($num1 + $num2 + $num3) / $count;
};
return $avg;
};
echo $get(3)(10,16,18),'<br>';
// 以上是一个求平均数的例子,调用时传入3个参数,但是当我们要传入更多的参数时呢,如下:
echo $get(6)(10,10,10,20,60,30);
echo '<br>';
// 这时后面的参数并没有输出,只运算了(10+10+10)/6=5,所以,当传入参数不确定时,可以采用下面这种方法:
$get1 = function (int $count)
{
$avg1 = function (...$args) use($count) :float
{
return array_sum($args) / $count;
};
return $avg1;
};
echo $get1(6)(10,10,10,20,60,30),'<br>';
// 因为是以数组的方式,所以可以用count()函数来计算数组的长度,来达到自动计算输入参数的个数,
// 上面案例可简化如下:
function avg (...$args) :float
{
return array_sum($args) / count($args);
};
echo avg(10,10,10,20,60,30);
5. 异步编程中函数的参数
示例如下:
<?php
// 异步编程中的函数参数
// 异步编程:当函数的执行的时间和顺序无法预测时,通过事件或者回调来执行函数
// 它的执行由父函数决定何时调用
// 示例:将数组中的每个数值增大1倍
$arr1 = [2,3,4,5,6];
// 创建一个新的数组来接收新的数值
// 使用array_map()返回一个新的数组,此例将一个匿名函数作为一个参数传到array_map()函数中使用
// 当父函数执行的时候,才会执行内部的回调函数
$arr2 = array_map(function($num){
return $num*$num;
},$arr1);
echo '<pre>'.print_r($arr2,true).'</pre>';
6. 函数的命名空间
函数的命名空间用法和变量的命名空间是相似的,示例如下:
<?php
// 函数的命名空间
// 1. 命名空间
namespace ns1{
function sum(int $a, int $b):int
{
return $a + $b;
}
}
// 2. 全局空间中访问
namespace{
echo ns1\sum(10,5);
}
6. 总结
知道函数如何声明与调用,它是代码复用的重要手段
函数分为四大类型:自定义函数,系统函数,可变函数,匿名函数,掌握好每种类型的应用场景
函数的返回值虽然是单一值,但是可以通过其他途径实现多值返回,如:字符串拼接,数组,json字符串和序列化
函数的参数如何使用,传参有哪些方式:值参数、引用参数、默认参数、剩余参数
函数命名空间与访问