PSR-12 并未淘汰 PHP 5.4 的大括号写法,而是废止了 PSR-2 中类与方法花括号必须换行的强制规则,改为按语义分层:结构体(class/interface/trait/enum)的 { 换行,方法/函数/控制结构的 { 紧跟声明行。

PSR-12 并没有“淘汰”PHP 5.4 的大括号写法——它根本就没存在过所谓“PHP 5.4 特有的大括号规则”。真正被 PSR-12 明确废止的,是 PSR-2 中关于类和方法花括号必须换行的**一刀切式强制要求**,而 PSR-12 对此做了更合理、更贴近现代 PHP 实践的细化。
PSR-2 的 { 换行规则为何不适用于现代 PHP
PSR-2 要求:类定义的 { 和所有方法定义的 { 都必须独占一行。这导致类似这样的写法被强制接受:
class UserController
{
public function index()
{
return ['ok' => true];
}
}
问题在于:该规则与 PHP 语言演进脱节。从 PHP 5.4 开始,匿名函数、闭包、短数组语法([])大量普及;PHP 7+ 引入返回类型声明、标量类型声明;PHP 8+ 加入联合类型、属性提升等。这些语法天然倾向紧凑表达,而 PSR-2 的机械换行反而割裂了逻辑单元。
- 匿名类/函数的
{若强制换行,会显著拉长垂直空间,降低可读性 - 单行方法(如 getter/setter)写成多行,纯属冗余
- PSR-2 未区分「结构体边界」和「逻辑块入口」,把类、接口、trait、方法全部套用同一规则
PSR-12 怎么重新定义 { 的位置
PSR-12 的核心调整是「按语义分层」,不是按语法节点统一处理:
立即学习“PHP免费学习笔记(深入)”;
-
class、interface、trait、enum的{必须另起一行(保留 PSR-2 原意,强调结构体开始) -
function、method的{必须跟在声明同一行(例如public function handle(): void {) - 控制结构(
if、for、foreach等)的{也必须跟在条件/头同一行 - 匿名函数/类的
{同样适用「紧跟声明行」规则,除非长度超限需换行对齐
这个改动不是技术倒退,而是回归语义:方法和控制结构是「执行入口」,不是「结构容器」,紧贴声明更符合直觉。
为什么很多人误以为「PHP 5.4 大括号被淘汰」
这个误解通常来自两个混淆点:
- 将「PSR-2 废弃」等同于「它曾经支持的写法被淘汰」——其实 PSR-2 支持的写法(如
if ($x) {)在 PSR-12 中依然合法,只是不再强制要求类的{换行 - 把 PHP 5.4 新增的语法(如短数组
[]、闭包)错误归因为「改变了大括号规则」——实际 PHP 解析器从未规定大括号必须换行,那只是 PSR-2 的风格偏好
真正被 PSR-12 淘汰的,是 PSR-2 的教条式格式主义,而不是某个 PHP 版本的语法能力。
最容易被忽略的是:PSR-12 允许方法体单行书写(如 public function id(): int { return $this->id; }),但前提是整行不超过 120 字符且无副作用。一旦涉及多表达式或复杂逻辑,就必须换行并保持 4 空格缩进——规则有弹性,但底线很清晰。



















