函数与命名空间
function、use namespace、autoload 概念。
30 分钟
函数与命名空间
这一课你将能做到
- 写出带类型声明、默认参数、可变参数的现代 PHP 函数,并会匿名函数与箭头函数
- 用 namespace 组织代码,避免全局命名冲突
- 理解 PSR-4 规则,手写 spl_autoload_register 实现自动加载,告别满屏 require
为什么要学
把代码写进函数是复用的第一步,而把函数和类放进命名空间、再用自动加载按需引入,是 PHP 从「脚本」进化到「工程」的分水岭。Laravel、Symfony 这类框架的每一个类都遵循 命名空间 ↔ 目录路径 的 PSR-4 映射——看不懂这个映射,框架源码和 composer.json 就像天书。
人话:函数是「把一段活儿打包」,命名空间是「给代码分小区,防止撞名」,自动加载是「用到哪个文件才去读哪个文件」。三者合起来,就是 PHP 版的 package + import + classloader。
先建立图像
PSR-4 自动加载的核心映射:
composer.json 声明:
"App\\": "src/"
那么:
App\Controllers\UserController
│
▼ 把 \ 换成 / ,加前缀目录
src/Controllers/UserController.php
│
▼ 第一次 new / 调用时自动 require
加载完成,运行
命名空间是逻辑名,目录是物理位置,PSR-4 就是两者之间那张「翻译表」。
跟着做
步骤 1:现代函数写法
新建 fn.php:
<?php
declare(strict_types=1);
// 类型声明 + 默认值 + 可变参数
function discount(float $price, float $rate = 0.9, ...$extra): float {
return round($price * $rate, 2);
}
echo discount(100.0), PHP_EOL; // 90(用默认折扣)
echo discount(100.0, 0.8), PHP_EOL; // 80(覆盖默认值)
echo discount(price: 100.0, rate: 0.85), PHP_EOL; // 85(命名参数,PHP 8+)
// 可变参数收进数组
function sum(int ...$nums): int {
return array_sum($nums);
}
echo sum(1, 2, 3, 4), PHP_EOL; // 10
步骤 2:匿名函数与箭头函数
<?php
declare(strict_types=1);
$users = [
['name' => '张三', 'age' => 28],
['name' => '李四', 'age' => 35],
['name' => '王五', 'age' => 22],
];
// 匿名函数:多行逻辑用 use 捕获外部变量
$minAge = 25;
$adults = array_filter($users, function (array $u) use ($minAge): bool {
return $u['age'] >= $minAge;
});
// 箭头函数:单表达式,自动捕获外部变量(值捕获)
$names = array_map(fn(array $u) => $u['name'], $users);
print_r($names); // 张三、李四、王五
print_r(array_keys($adults)); // 只有张三、李四满足条件
箭头函数 fn() => 是 PHP 7.4+ 语法,等价于自动 use 的单行匿名函数,数组操作场景下是绝对主力。
步骤 3:命名空间解决撞名
建两个文件,故意让类同名:
// src/Alibaba/User.php
namespace Alibaba;
class User {
public function who(): string { return '阿里巴巴的用户'; }
}
// src/Tencent/User.php
namespace Tencent;
class User {
public function who(): string { return '腾讯的用户'; }
}