应采用PSR-12规范统一代码风格,通过phpcs自动扫描与phpcbf预提交修复;函数须单职责、强类型、显式异常处理;依赖注入替代new硬编码;错误必须记录不可沉默。

用 PSR-12 规范约束代码风格,而不是靠团队自觉
PHP 没有强制语法约束缩进、空行或括号位置,但人眼对不一致的格式极其敏感。不统一风格会直接拖慢阅读速度,尤其在 review 或 debug 时。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 立刻在项目根目录加
phpcs.xml,用phpcs --standard=PSR12扫描,别只看报告——把phpcbf加进 pre-commit hook 自动修复 -
switch的case必须缩进一级,break后必须空行;很多人漏掉这点,导致后续加逻辑时误以为break缺失 - 数组声明统一用短语法
[],禁止混用array();老项目升级时,array()在 PHP 8.4 已标记为 deprecated
函数必须单职责,且返回值类型可预测
一个叫 getUserData() 的函数,有时返回 array,有时抛 Exception,有时静默返回 null,调用方只能靠文档或试错来猜——这就是维护地狱的起点。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 函数名动词+名词,且只做一件事:
formatPhoneNumber()不该同时校验格式、查数据库、发日志 - 所有公共函数加 PHPDoc 类型标注,尤其是返回值:
@return User|null比@return mixed有用十倍 - 避免隐式类型转换:用
is_string($input)显式校验,别依赖if ($input)判断非空——"0"和0都会挂掉
依赖注入代替 new 关键字硬编码
写 new DatabaseConnection() 看似简单,但测试时无法 mock,重构时改一处要搜全项目,换数据库驱动更是灾难。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 构造函数参数必须是接口,不是具体类:
public function __construct(UserRepositoryInterface $repo),而非UserRepository - 容器注册别写死路径:
$container->set('logger', new FileLogger('/var/log/app.log'))改成从配置读取config('log.path') - 临时需要对象?用工厂模式封装
new,而不是在业务逻辑里直接 new——工厂本身可被替换、可测、可缓存
错误处理不捕获异常就抛,不记录日志就沉默
常见错误是 try { ... } catch (Exception $e) { return false; },表面没报错,实际数据丢了、状态不一致,日志里连痕迹都没有。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 业务层 catch 异常后,必须记录(至少
error_log()或 PSR-3 logger),再决定是否重抛或返回兜底值 - 全局异常处理器里,区分
Throwable类型:开发环境显示堆栈,生产环境只记日志 + 返回 500,绝不暴露路径或变量名 - 不要用
@抑制错误——它连 E_WARNING 都吞,且无法被set_error_handler捕获,PHP 8+ 中已被标记为“不推荐”
可维护性最常被低估的一点:不是代码多清晰,而是当新人第一次改某个函数时,能不能在 3 分钟内确认“这里改了会不会影响订单支付”。这取决于类型提示是否完整、异常路径是否显性、依赖是否可追溯——而不是注释写得多漂亮。



















