#[Override]是PHP 8.3引入的编译期强制校验属性,用于显式声明方法重写意图并验证签名兼容性,不改变运行时行为但可被PHPStan等工具提前捕获LSP违规问题。
![php8.3 新增 #[\override] 属性校验父类方法,防止重写签名错误](https://img.php.cn/upload/article/001/503/042/179101057789447.png?x-oss-process=image/resize,p_40)
PHP 8.3 引入了 #[Override] 属性,用于显式标记子类中重写父类方法的意图。它本身不改变运行时行为,但配合静态分析工具(如 PHPStan、Psalm)或 IDE,能提前发现签名不兼容的重写——比如参数类型变弱、返回类型变宽、缺少 final 约束等潜在错误。
为什么需要 #[Override]?
在 PHP 中,子类重写父类方法时,若签名不符合 LSP(里氏替换原则),可能引发运行时异常或逻辑错误。例如:
- 父类方法返回
string,子类声明返回string|null(变宽,合法但可能破坏调用方假设); - 父类参数类型是
DateTimeInterface,子类改成DateTime(变窄,违反协变规则,PHP 会报错); - 父类方法有
final,子类仍尝试重写(语法错误,但仅在运行时报)。
#[Override] 不解决语法错误,而是让“本意是重写,但签名意外不兼容”的情况更易被工具捕获。
怎么使用 #[Override]?
在子类中重写的方法上添加该属性即可:
class ParentClass
{
public function process(string $input): int
{
return strlen($input);
}
}
<p>class ChildClass extends ParentClass
{</p><h1>[Override]</h1><pre class="brush:php;toolbar:false;">public function process(string $input): int
{
return parent::process($input) * 2;
}}
若签名不兼容(如改了参数类型),PHPStan 等工具会在分析阶段提示警告,例如:
#[Override] public function process(mixed $input): int // ⚠️ 参数类型比父类更宽,触发警告
它和 abstract/final 有什么关系?
#[Override] 是纯标注性属性,不影响继承规则:
- 父类方法是
abstract,子类实现时加#[Override]是合理且推荐的; - 父类方法是
final,子类加#[Override]会导致 PHP 解析失败(语法错误),因为根本不能重写; - 没加
#[Override]的重写方法不会被检查——工具默认不校验,除非你开启严格模式并启用该规则。
实际项目中怎么落地?
要真正发挥作用,需配合开发流程:
- 升级到 PHP 8.3+ 并启用属性支持;
- 在 PHPStan 配置中启用
phpstan/phpstan-deprecation-rules或自定义规则识别#[Override]; - CI 流程中加入静态分析步骤,把
#[Override]不匹配作为构建失败项; - 团队约定:所有重写方法必须加
#[Override],避免遗漏。
它不是银弹,但让“重写是否安全”从靠经验变成可验证的事实。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











