批改状态:合格
老师批语:函数如此的重要, 以至于有一个重要的编程分支: 面得过程编程, 与面得对象编程平分天下
//函数声明function 函数名称(类型: 参数列表): 返回值类型{// 函数体return 返回值;//隐式:结束大括号的时候自动返回//return不是必须的}//函数调用,按照函数名称调用(调用需要echo)
| 序号 | 名称 | 描述 |
|---|---|---|
| 1 | function |
声明函数 |
| 2 | 函数名称 |
符合 PHP 标识符命名规范,不区分大小写 |
| 2 | 参数列表 |
零个或多个接收外部传入到函数的变量 |
| 2 | {... |
创建出一个封闭的函数作用域 |
| 2 | 函数体 |
由零个可多个合法的 PHP 语句组成 |
| 2 | return 值 |
将执行结果返回函数调用者[可选] |
| 2 | ...} |
函数执行结束,如果没有return,则返回null |
| 序号 | 类型 | 语法 | 描述 |
|---|---|---|---|
| 1 | 自定义函数 | function getName(){...} |
用户根据业务需求创建 |
| 2 | 系统函数 | substr(), count()... |
也叫预定义函数,不必声明直接调用 |
| 3 | 可变函数 | $funcName(); |
函数名使用变量表示 |
| 4 | 匿名函数 | $f = function (){...} |
也叫”闭包”或”函数表达式”,常用做回调处理 |
<?phpfunction myPrice(int $num, int $price): int{$myPrice = $num * $price;return $myPrice;}echo myPrice(20, 30);
<?php$str = '我爱php中文网';echo mb_substr($str, 0, 3);//系统函数,自带的,不需自定义
<?phpfunction myPrice(int $num, int $price): int{$myPrice = $num * $price;return $myPrice;}echo myPrice(20, 30);echo '<hr>';//可变函数// 函数名储存在变量中$funcName = 'myPrice';echo $funcName(20, 30);//通过变量调用函数
<?php// 4.匿名函数:闭包$discount = 0.6;$num = 100; //全局变量//闭包就是匿名函数,被赋值给一个变量了,闭包可以访问父作用域$getPrice = function (float $num, float $price) use ($discount): float {// global $discount;$myprice = $num + $price;return $myprice > 100 ? $myprice * $discount : $myprice;};echo $getPrice(100, 20);
<?php// 如果父作用域又是一个函数$discount = 0.6;$a = function ($discount) {//子函数$getPrice = function (float $num, float $price) use ($discount): float {$myprice = $num + $price;return $myprice > 100 ? $myprice * $discount : $myprice;};return $getPrice;};echo $a(0.6)(200, 20);// echo gettype($a);
返回多值需要处理:1.字符串拼装,2.数组,3.jason 字符串,4.序列化:字符串
| 序号 | 场景 | 描述 |
| —— | ————— | ————————————————- |
| 1 | return | 可以返回任何类型的值,包括函数类型 |
| 2 | 无return | 遇到}也会返回, 默认返回null |
如果需要返回多个值,可以通过以下手段
| 序号 | 返回值类型 | 描述 |
|---|---|---|
| 1 | string |
字符串拼接 |
| 2 | array |
数组 |
| 3 | json |
JSON 字符串 |
| 4 | serialize |
序列化字符串 |
json 和序列化,使用时需要进行解码操作
java 等多个地方使用
<?phpfunction demo1(): string{$status = '1';$message = '登陆成功';return $status . '状态为:' . $message;}echo demo1();//适合处理大量php+html代码混合//返回格式为用户自定义,前端处理非常麻烦
<?php// 返回值通过数组//函数是全局的function demo2(): array{// $status = '1';// $message = '登陆成功';return ['status' => 1, 'message' => '成功'];}// echo print_r(demo2(), true);// echo '<pre>' . print_r(demo2(), true) . '</pre>';printf('<pre> %s </pre>', print_r(demo2(), true));// echo demo2()['status'] == 1 ? demo2()['message'] : '验证失败';echo demo2()['status'] == 1 ? '<span style="color:red">' . demo2()['message'] . '</span> ' : '验证失败';
<?phpfunction demo3(): string{//json_encode():将php数据编码为json格式来返回return json_encode(['status' => 1, 'message' => '登陆成功']);}$data = demo3();echo $data;
// - 将 json 格式的字符串还原/解析为 php 对象或者数组$var = json_decode($data, true);print_r($var);
<?php//4.通过序列化返回多个值function demo4(): string{return serialize(['status' => 1, 'message' => '登陆成功']);//a:2:{s:6:"status";i:1;s:7:"message";s:12:"登陆成功";}//a数组//2两个元素//s字符串//6个字符//i值为证书//1是他的值//s字符串//7个字符//utf8一个汉字3个字节}echo demo4();
//反序列化unserialize(demo4());$arr = unserialize(demo4());printf('<pre>%s<pre>', print_r($arr, true));
参数类型
| 序号 | 类型 | 描述 |
|---|---|---|
| 1 | 值参数 | 默认传参方式 |
| 2 | 引用参数 | 改变原始调用参数值 |
| 3 | 默认参数 | 调用时允许省略的参数 |
| 4 | 剩余参数 | 调用参数数量不确定 |
-在函数中改变了调用参数的值,但是原始调用参数并没有发生变化
//1.值参数,值传递function demo1(float $arg): float{return $arg * 2;}$value = 1000;echo demo1($value), '<br>';//在函数中改变了调用参数的值,但是原始调用参数并没有发生变化echo $value;
&取地址符
//2.引用参数,引用传递function demo1(float &$arg): float{return $arg *= 2;}$value = 1000;echo demo1($value), '<br>';//如果在参数前面使用了取地址符,则会改变原始调用参数的值echo $value;echo '<hr>';
<?phpfunction demo1(float $a, float $b, string $opt = '+')//默认参数不能出现在必选参数前面{$res = 0;switch ($opt) {case '+':$res = "$a+$b=" . ($a + $b);break;case '-':$res = "$a-$b=" . ($a - $b);break;case '*':$res = "$a*$b=" . ($a * $b);break;case '/':$res = "$a/$b=" . ($a / $b);break;default:$res = '非法操作符号';}return $res;}echo demo1(10, 20);echo demo1(10, 20, '*');
return func_num_args();返回参数的数量return func_get_arg();根据索引返回指定的调用参数return func_get_args();返回一个数据,分别是索引对应的值
<?phpfunction demo1(){// return func_num_args();// return func_get_arg(1);// return func_get_args();$sum = 0;for ($i = 0; $i < func_num_args(); $i++) {$sum += func_get_arg($i);}return $sum;}print_r(demo1(3, 4, 6, 7, 8, 52, 4,));
<?phpfunction demo1(){$sum = 0;// 第二种办法foreach (func_get_args() as $value) {$sum += $value;}return $sum;}print_r(demo1(3, 4, 6, 7, 8, 52, 4,));
...参数归纳,使用在参数列表中,表示收集,将多个离散的参数打包到一个数组中处理...调用参数,表示展开/还原一个数组为离散值
//剩余参数// ...:参数归纳,使用在参数列表中,表示收集,将多个离散的参数打包到一个数组中处理function demo2(...$args): float{// return $args;return array_sum($args);// return array_product($args);}// ...:调用参数,表示展开/还原一个数组为离散值$arr = [3, 4, 6, 7];print_r(demo2(...$arr));
| 语法 | 类型 | 执行方式 | 应用场景 |
|---|---|---|---|
| 匿名函数 | 闭包Closure |
异步 | 函数参数 |
异步执行,是指当前函数的执行并不会中断当前程序的执行流程
<?php# 回调函数:用在函数的回调参数中//回调:在将来某一时刻,或者某个事件发生时再执行//生成一个1-100共100个整数的数组// $data=[1,2,3,4,5,6,7,8,9,...,100];// $data = range(0, 99, 5);// // range(起始数字,结束数字,步长)// print_r($data);// 只返回当前数据中偶数$data = range(0, 99);// print_r($data);//只返回偶数var_dump(4 % 2);echo ((4 % 2) == 0) ? '偶数' : '奇数';$res = array_map(function (int $item) {if ($item % 2 === 0) return $item;}, $data);// array_map(回调函数,数组)echo $res;printf('<pre?>%s</pre>', print_r($res, true));
// 过滤空值/假值// array_filter仅返回结果为trus的数据$res = array_filter($res, function ($item) {return $item;});$res = array_values($res);printf('<pre>%s</pre>', print_r($res, true));
目的是为了方式全局成员的命名冲突(全局成员:函数,常量,类,接口)
<?php# 命名空间(相当于在不同的目录下)// 防止命名冲突// 全局成员:函数,常量,类,接口namespace ns1 {function demo1(): string{return __FUNCTION__;}}namespace ns2 {function demo1(): string{return __FUNCTION__;}}
// 全局空间不需要名称namespace {echo \ns1\demo1();echo '<hr>';echo \ns2\demo1();}
本节课结束了函数的学习,用一句最经典的话来概括就是:函数是为了代码的共享,和变量的目的是为了数据的共享一致,与此同时函数是一个全局变量,可以在页面的任何位置调用函数,发现 PHP 的真正威力源自于它的函数。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号