第 4 课:函数基础
一、学习目标
- 掌握 PHP 函数的声明、调用与参数传递规则
- 熟练运用 PHP7 返回值类型声明与 PHP8 命名参数特性
- 理解变量作用域及匿名函数的使用场景
- 能够编写高可读性、高兼容性的函数代码
二、核心知识点
(一)函数的基本结构
-
函数声明语法(PHP7/8 延续基础结构,新增类型增强)
<?php // 基础函数结构:关键字+函数名+参数列表+函数体 function 函数名(参数1, 参数2, ...): 返回值类型 { // 函数体代码 return 返回值; // 与返回值类型匹配 } // 无参数、无返回值示例 function showWelcome(): void { // void表示无返回值(PHP7+支持) echo "欢迎学习PHP函数!<br>"; } // 调用函数 showWelcome(); ?> -
函数命名规范
- 以字母或下划线开头,可包含字母、数字、下划线
- 区分大小写(但推荐统一用小写 + 下划线命名法,如
get_user_info) - 避免使用 PHP 内置函数名(如
echo、array等)
-
函数的优势
- 代码复用:避免重复编写相同逻辑
- 模块化:将复杂功能拆分为独立函数,便于维护
- 可读性:通过函数名直观理解功能,降低代码复杂度
(二)函数参数进阶
-
参数默认值(PHP7/8 无变化,需注意默认参数位置)
- 默认参数必须放在非默认参数之后
- 默认值只能是常量(不能是变量、函数调用等)
示例:
<?php // 正确:默认参数在最后 function getMessage(string $name, string $type = "info"): string { return "[{$type}] 欢迎您,{$name}!"; } // 调用函数 echo getMessage("张三"); // 使用默认值"info",输出:[info] 欢迎您,张三! echo getMessage("李四", "warning"); // 自定义类型,输出:[warning] 欢迎您,李四! // 错误:默认参数不能在非默认参数之前 // function getMessage(string $type = "info", string $name): string { ... } ?> -
PHP7 标量类型声明(参数类型约束)
- 支持标量类型:
int、string、float、bool - 配合
declare(strict_types=1)实现严格类型检查
示例:
<?php declare(strict_types=1); // 严格模式(必须放在文件第一行) // 参数指定为int类型,返回值也指定为int类型 function add(int $a, int $b): int { return $a + $b; } echo add(2, 3); // 正确:输出5 // echo add(2.5, 3.5); // 错误:严格模式下不允许float转int // echo add("2", "3"); // 错误:严格模式下不允许string转int ?> - 支持标量类型:
-
PHP8 命名参数(革命性特性,简化参数传递)
- 调用函数时可通过 “参数名 = 值” 的方式传递参数,无需按顺序
- 适合参数较多且有默认值的场景,提升代码可读性
示例:
<?php // 多参数函数(含默认值) function createUser( string $name, string $email, int $age = 18, string $role = "user" ): array { return [ "name" => $name, "email" => $email, "age" => $age, "role" => $role ]; } // 传统调用(必须按顺序,如需跳过默认参数需传null) $user1 = createUser("张三", "zhangsan@example.com", 20, "admin"); // PHP8命名参数(可打乱顺序,跳过默认参数) $user2 = createUser( name: "李四", email: "lisi@example.com", role: "admin" // 跳过age,使用默认值18 ); print_r($user2); // 输出:Array ( [name] => 李四 [email] => lisi@example.com [age] => 18 [role] => admin ) ?> -
可变参数(不定长参数)
- 用
...表示,接收任意数量的参数,自动转为数组 - PHP7/8 支持在函数参数和调用时使用
示例:
<?php // 计算任意数量数字的总和 function sum(int ...$numbers): int { $total = 0; foreach ($numbers as $num) { $total += $num; } return $total; } echo sum(1, 2, 3); // 输出6 echo sum(10, 20, 30, 40); // 输出100 // 调用时展开数组(PHP7+) $arr = [5, 6, 7]; echo sum(...$arr); // 等价于sum(5,6,7),输出18 ?> - 用
(三)变量作用域与闭包
-
变量作用域分类
- 局部变量:函数内部定义,仅在函数内有效
- 全局变量:函数外部定义,需通过
global关键字或$GLOBALS数组在函数内访问 - 超全局变量:PHP 预定义的全局变量(如
$_GET、$_POST),可在任何作用域直接访问
示例:
<?php $global_var = "全局变量"; // 全局变量 function testScope() { $local_var = "局部变量"; // 局部变量 // 方法1:通过global关键字访问全局变量 global $global_var; echo "通过global访问:{$global_var}<br>"; // 方法2:通过$GLOBALS数组访问全局变量(PHP7/8推荐) echo "通过\$GLOBALS访问:{$GLOBALS['global_var']}<br>"; echo "局部变量:{$local_var}<br>"; } testScope(); // echo $local_var; // 错误:局部变量在函数外不可访问 // 超全局变量(无需声明,直接访问) echo "当前脚本文件名:{$_SERVER['PHP_SELF']}"; ?> -
静态变量(static)
- 函数内用
static声明,函数执行后值不丢失(保留上次执行结果) - 常用于计数、缓存等场景
示例:
<?php function countVisit(): int { static $count = 0; // 静态变量,仅初始化一次 $count++; return $count; } echo "第" . countVisit() . "次访问<br>"; // 输出:第1次访问 echo "第" . countVisit() . "次访问<br>"; // 输出:第2次访问 echo "第" . countVisit() . "次访问<br>"; // 输出:第3次访问 ?> - 函数内用
-
匿名函数(闭包)
- 没有名称的函数,可作为变量赋值或函数参数
- PHP7/8 支持
use关键字引入外部变量(解决作用域问题)
示例:
<?php // 1. 匿名函数作为变量赋值 $greet = function(string $name): string { return "Hello, {$name}!"; }; echo $greet("PHP8"); // 输出:Hello, PHP8! // 2. 匿名函数作为函数参数(配合array_map等函数) $numbers = [1, 2, 3, 4]; // 将数组中每个元素乘以2(用匿名函数作为回调) $doubled = array_map(function(int $num): int { return $num * 2; }, $numbers); print_r($doubled); // 输出:Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 ) // 3. 用use引入外部变量 $factor = 3; $tripled = array_map(function(int $num) use ($factor): int { return $num * $factor; // 使用外部变量$factor }, $numbers); print_r($tripled); // 输出:Array ( [0] => 3 [1] => 6 [2] => 9 [3] => 12 ) ?>
(四)函数高级特性
-
返回值类型声明(PHP7+)
- 函数声明时用
:指定返回值类型,强制函数返回对应类型的值 - 支持
void(无返回值)、self(返回当前类实例)等特殊类型
示例:
<?php declare(strict_types=1); // 返回值为string类型 function getUserName(int $user_id): string { $users = [1 => "张三", 2 => "李四"]; return $users[$user_id] ?? "未知用户"; } // 返回值为array类型 function getUserList(): array { return [ ["id" => 1, "name" => "张三"], ["id" => 2, "name" => "李四"] ]; } // 无返回值(void) function logMessage(string $message): void { file_put_contents("log.txt", $message . "\n", FILE_APPEND); } ?> - 函数声明时用
-
PHP8 属性提升(构造函数简化)
- 虽然属于类特性,但常与类的成员函数结合使用
- 可在构造函数参数前加访问修饰符(
public/private等),自动生成类属性
示例:
<?php class User { // PHP8构造函数属性提升:参数自动转为类属性 public function __construct( public int $id, public string $name, public string $email ) { // 无需额外赋值,PHP自动处理 } // 类的成员函数 public function getInfo(): string { return "ID: {$this->id}, 姓名: {$this->name}, 邮箱: {$this->email}"; } } $user = new User(1, "张三", "zhangsan@example.com"); echo $user->getInfo(); // 输出:ID: 1, 姓名: 张三, 邮箱: zhangsan@example.com ?>
三、注意事项
-
参数传递陷阱
- 基本类型(int、string 等)默认按值传递(函数内修改不影响外部变量)
- 复合类型(array、object 等)默认按引用传递(函数内修改会影响外部变量)
- 如需按引用传递基本类型,需在参数前加
&(如function modify(&$num) { ... })
-
函数嵌套问题
- 避免过度嵌套函数(函数内定义函数),会导致代码可读性差
- 如需复用嵌套逻辑,建议拆分为独立函数或使用匿名函数
-
版本兼容性
- 命名参数仅 PHP8 + 支持,低版本需按顺序传递参数
void返回值类型仅 PHP7.1 + 支持,低版本可省略返回值声明- 构造函数属性提升仅 PHP8 + 支持,低版本需手动定义类属性并赋值
四、实战练习
-
创建
day4文件夹,新建math_utils.php文件:- 定义一个
MathUtils类,包含以下静态函数:sum(int ...$numbers): int:计算任意数量整数的总和average(float ...$numbers): float:计算任意数量浮点数的平均值(保留 2 位小数)maxValue(array $arr): int|float:返回数组中的最大值(支持整数和浮点数混合)
- 使用 PHP7 类型声明和返回值类型,PHP8 命名参数调用函数
- 编写测试代码,验证每个函数的正确性
- 定义一个
-
新建
user_service.php文件:- 定义一个
UserService类,包含以下方法:getUserById(int $id): array:根据 ID 获取用户信息(模拟数据:ID 为 1 返回张三,2 返回李四,其他返回空数组)filterUsers(array $users, callable $callback): array:接收用户数组和匿名函数,返回符合条件的用户
- 调用
filterUsers方法,用匿名函数筛选出年龄≥20 的用户(模拟用户数据包含age字段) - 使用
static变量实现用户查询缓存(同一 ID 多次查询仅返回一次数据)
- 定义一个
PHP 函数基础详解与实战
1481

被折叠的 条评论
为什么被折叠?



