本文目录导读:

- 命名:让变量和函数自解释
- 函数与方法:一个函数只做一件事
- 控制结构:增加可读空格和括号
- 注释:解释“为什么”,而不是“是什么”
- 现代PHP特性:用对语法糖
- 类型声明:让参数和返回值清晰
- 避免深层嵌套:提前返回
- 使用DTO/ValueObject替代数组
- 保持一致的编码风格
- 实战检查清单
- 额外建议:代码审查与重构
提升PHP代码可读性,本质上是从“能跑就行”转向“让下一个人(包括未来的你)能看懂”,下面21条实战建议,覆盖命名、结构、注释和现代PHP特性,帮你写出更清晰的代码。
命名:让变量和函数自解释
规则:
- 变量/函数:小驼峰
$myVariable或下划线$my_variable,选一个并坚持 - 类名:大驼峰
UserManager - 布尔变量:用
is*、has*、can*开头($isActive、$hasPermission) - 避免缩写:
$usrCnt→$userCount
坏例子:
$d = date('Y-m-d');
$t = $d + 7; // 7天后是哪天??
好例子:
$currentDate = date('Y-m-d');
$expirationDate = date('Y-m-d', strtotime('+7 days'));
函数与方法:一个函数只做一件事
原则: 一个函数长度不超过20-30行,缩进不超过2-3层。
坏例子:
function processOrder($order) {
// 1. 验证订单(10行)
// 2. 检查库存(15行)
// 3. 计算价格(12行)
// 4. 发送邮件(8行)
// 5. 记录日志(5行)
}
好例子:
function processOrder($order) {
$this->validateOrder($order);
$this->checkInventory($order);
$total = $this->calculatePrice($order);
$this->sendConfirmationEmail($order, $total);
$this->logOrderProcessing($order);
}
控制结构:增加可读空格和括号
规则:
- 始终使用花括号 ,即使代码只有一行
- 关键运算符前后加空格(, ,
&&, )
坏例子:
if($a>0&&$b<10)$result=$a+$b;
好例子:
if ($a > 0 && $b < 10) {
$result = $a + $b;
}
注释:解释“为什么”,而不是“是什么”
规则:
- 代码本身能表达“是什么”,注释解释“为什么这么做”
- 使用
// 单行注释或/** 块注释 */ - 非必要不加注释,代码应具备自解释能力
坏例子:
// 加1 $counter = $counter + 1;
好例子:
// 跳过第一条记录(表头) $data = array_slice($rows, 1);
现代PHP特性:用对语法糖
PHP 8+ 提供了大量提升可读性的特性:
a) 命名参数(PHP 8.0)
// 传统方式 - 需记住参数顺序
$result = findUsers('active', 1, 20, 'created_at');
// 命名参数 - 一目了然
$result = findUsers(
status: 'active',
page: 1,
perPage: 20,
orderBy: 'created_at'
);
b) 空安全运算符(PHP 8.0)
// 冗长写法 $city = isset($user['address']) ? $user['address']['city'] ?? null : null; // 可读写法 $city = $user['address']?->city;
c) 匹配表达式(PHP 8.0)
// switch 语句
switch ($status) {
case 'active':
$color = 'green';
break;
case 'pending':
$color = 'yellow';
break;
default:
$color = 'gray';
}
// match 表达式 - 更简洁清晰
$color = match ($status) {
'active' => 'green',
'pending' => 'yellow',
default => 'gray',
};
类型声明:让参数和返回值清晰
规则: 为函数参数和返回值指定类型。
// 无类型声明
function addUsers($users) {
// ...
}
// 有类型声明 - 意图明确
function addUsers(array $users): bool {
// ...
}
还可以用 联合类型(PHP 8.0):
function findUser(int|string $id): User|null {
// $id可以是整数ID或字符串UUID
}
避免深层嵌套:提前返回
原则: 检测到条件不满足时立即返回,而不是包在更深的 if 里。
坏例子:
function processUser($user) {
if ($user !== null) {
if ($user->isActive()) {
if ($user->hasPermission('edit')) {
// 处理逻辑
}
}
}
}
好例子:
function processUser($user) {
if ($user === null || !$user->isActive() || !$user->hasPermission('edit')) {
return;
}
// 处理逻辑
}
使用DTO/ValueObject替代数组
坏例子:
$user = [
'name' => 'Alice',
'age' => 30,
'email' => 'alice@example.com'
];
// 访问时需要记忆键名
echo $user['email'];
好例子:
class UserDTO {
public function __construct(
public readonly string $name,
public readonly int $age,
public readonly string $email
) {}
}
$user = new UserDTO('Alice', 30, 'alice@example.com');
echo $user->email; // IDE自动补全
保持一致的编码风格
推荐标准: PSR-12(PHP编码规范)
可借助工具自动格式化:
- PHP CS Fixer:
php-cs-fixer fix . - PHP CodeSniffer:报告风格问题
- Laravel Pint:Laravel专用的格式化工具
实战检查清单
| 要点 | 做法 |
|---|---|
| 命名 | 自解释,不用缩写 |
| 函数长度 | ≤ 20-30行,一个函数一个职责 |
| 缩进 | 不超过3层 |
| 注释 | 解释“为什么” |
| 类型 | 使用强类型 |
| 空值处理 | 使用 null safe 或提前返回 |
| 一致性 | 遵循PSR-12 |
额外建议:代码审查与重构
- 定期代码审查:让团队成员检查可读性
- 重构旧代码:每次修改时,顺手把附近代码改善一下(童子军规则)
- 阅读优秀代码:学习 Laravel、Symfony 等知名项目的代码风格
最终目标不是写出“完美”代码,而是让下一个人(包括6个月后的你)能快速理解你的意图,坚持以上原则,你的PHP代码可读性会有明显提升。