在PHP项目升级过程中,为废弃功能添加清晰规范的注释标记,绝非简单写几行说明就能完成。本质上,你需要构建一座可维护、可追溯、可自动识别的兼容性桥梁。核心要点只有三个:选对工具、写准位置、留好退路。

采用PHPDoc标准规范标注废弃信息
PHP官方推荐、主流IDE和静态分析工具(如PHPStan、Psalm)均能识别的做法是什么?没错,就是使用@deprecated标签。该标签必须放置在函数、方法或类的PHPDoc块内,紧贴声明上方。
- 务必标注废弃起始版本,例如
@deprecated since 8.5,方便团队迅速判断当前版本是否已越过此界限。 - 建议同时补充替代方案,例如
@see DateTimeImmutable::createFromFormat(),或直接提供迁移指南链接@see https://example.com/migration-guide。 - 若计划在未来版本彻底移除该功能,可添加
@removed 9.0(虽非标准标签,但团队阅读时一目了然)。
借助Doctrine Deprecations实现运行时管控
仅靠注释只能发出提示,无法阻止旧代码继续执行。此时需要引入Doctrine Deprecations库,提供真正的干预能力:
- 在废弃方法内部调用
trigger_deprecation('vendor/name', '8.5', 'Method %s is deprecated', __METHOD__);,即可统一收集、过滤甚至抑制警告。 - 通过配置
SYMFONY_DEPRECATIONS_HELPER=weak_vendors,让CI环境对第三方包的废弃提示适度宽容,集中精力修复自身问题。 - 支持按消息关键词屏蔽重复警告,避免日志刷屏,例如
ignore: "mysql_connect",谁用谁知道。
动态属性弃用的特殊应对策略
PHP 8.3及以上版本对未声明属性的赋值会触发Deprecated: Creation of dynamic property警告。这与传统函数级废弃不同,需要采用结构化方式处理:
- 首选重构:显式声明所有属性,即使初始值为
null。这是最安全、最IDE友好的做法,一劳永逸。 - 若确实需要动态行为,可为类添加
#[AllowDynamicProperties]属性。注意该注解本身不会触发警告,且子类继承同样生效。 - 切勿使用
__set()魔术方法试图掩盖问题——这样做会导致类型检查失效,同时绕过废弃警告机制,后患无穷。
与类型系统升级联动进行标注
PHP 8.5/8.7中许多废弃源于类型严格化(例如create_function被移除、联合类型校验升级)。此时注释需与类型契约同步更新:
- 废弃旧签名时,在新方法的PHPDoc中明确标注
@param int|string $input,同时在旧方法注释中说明“原接受mixed,现要求明确类型”。 - 当父类方法新增返回类型导致子类重写触发废弃警告(如PHP 8.1 PDO场景),可在子类方法注释中添加
@deprecated use return type PDOStatement|false to match parent。 - 搭配
#[ReturnTypeWillChange]属性时,PHPDoc中必须注明仅为过渡方案,并附上最终修复计划的链接,让后续开发者明确方向。
