PHPStan 错误标识符 method.deprecatedEnum 详解:如何在废弃枚举上调用方法时精准报错
2026/9/23 20:24:25 网站建设 项目流程

PHPStan 错误标识符 method.deprecatedEnum 详解:如何在废弃枚举上调用方法时精准报错

【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan

method.deprecatedEnum是 PHPStan 在调用一个被@deprecated标记的枚举(enum)上的实例方法时报告的错误标识符(error identifier)。本文以 method.deprecatedEnum.md 为核心骨架,结合仓库中同族错误文档与 errorsIdentifiers.json 中记录的实现类,讲清该错误的触发场景、背后规则来源、修复方式与忽略策略,帮助你理解"枚举整体废弃"在静态分析中的传播逻辑。

错误速览

属性
标识符method.deprecatedEnum
一句话描述调用的方法所属的枚举被标记为@deprecated(Called method belongs to an enum marked as@deprecated.)
是否可忽略是(frontmatter 中ignorable: true
提供规则的扩展phpstan/phpstan-deprecation-rules
对应规则类PHPStan\Rules\Deprecations\RestrictedDeprecatedMethodUsageExtension

该文档的 frontmatter 由 website/errors/method.deprecatedEnum.md 顶部给出,同时可在 errorsIdentifiers.json 的method.deprecatedEnum条目中查到其规则类归属与源码定位信息。

触发该错误的代码示例

在 PHP 8.1+ 中,枚举可以像类一样拥有方法。当一个枚举整体被@deprecated标记时,调用它的实例方法就会命中method.deprecatedEnum

<?php declare(strict_types = 1); /** @deprecated Use NewStatus instead */ enum OldStatus: string { case Active = 'active'; case Inactive = 'inactive'; public function label(): string { return $this->value; } } function doFoo(OldStatus $status): void { $status->label(); // ERROR: Call to method label() of deprecated enum OldStatus. }

示例的关键点:

  • 被废弃的是枚举本身@deprecated Use NewStatus instead),而不是label()方法;
  • label()方法本身没有@deprecated标记,但调用仍会报错,因为整个枚举已被标记废弃;
  • 报告的错误消息为Call to method label() of deprecated enum OldStatus.

为什么会被报告

根据 method.deprecatedEnum.md 的说明,该错误由phpstan/phpstan-deprecation-rules扩展报告。

核心语义是:对一个被@deprecated标记的枚举的实例调用方法,等于在使用这个即将被移除或替换的 API。即使方法本身未废弃,只要枚举整体废弃,枚举的所有用法——包括调用它的方法——都应当被替换为文档建议的替代方案。

这种"废弃传播"是 deprecation-rules 的典型设计:废弃标记会沿着类型引用关系扩散。从 errorsIdentifiers.json 中method.deprecatedEnum条目可以看到,它对应规则类为PHPStan\Rules\Deprecations\RestrictedDeprecatedMethodUsageExtension(来源于phpstan/phpstan-deprecation-rules),同族标识符(如method.deprecatedInterfacemethod.deprecatedTrait)也由同一规则类负责,说明该扩展对类、接口、特质、枚举上的废弃方法调用采用统一的分析逻辑。

同族标识符:废弃枚举的"全家族"报告

method.deprecatedEnum只是"废弃枚举"标识符家族中的一员。仓库的 website/errors 目录下还存在一系列同类标识符,覆盖了枚举在代码中出现的几乎所有位置:

标识符触发场景
method.deprecatedEnum在废弃枚举实例上调用方法
staticMethod.deprecatedEnum在废弃枚举上调用静态方法
new.deprecatedEnum对废弃枚举使用new表达式
property.deprecatedEnum属性类型引用了废弃枚举
staticProperty.deprecatedEnum访问废弃枚举的静态属性
classConstant.deprecatedEnum访问废弃枚举的常量
parameter.deprecatedEnum函数/方法参数类型引用废弃枚举
return.deprecatedEnum返回类型引用废弃枚举
instanceof.deprecatedEnuminstanceof表达式使用废弃枚举
catch.deprecatedEnumcatch块捕获废弃枚举
attribute.deprecatedEnum属性(attribute)使用废弃枚举
assert.deprecatedEnum@phpstan-assert断言类型引用废弃枚举
methodTag.deprecatedEnum@methodPHPDoc 标签引用废弃枚举
propertyTag.deprecatedEnum@propertyPHPDoc 标签引用废弃枚举
varTag.deprecatedEnum@varPHPDoc 标签引用废弃枚举
mixin.deprecatedEnum@mixinPHPDoc 标签引用废弃枚举
typeAlias.deprecatedEnum类型别名引用废弃枚举
sealed.deprecatedEnum@phpstan-sealed标签引用废弃枚举
selfOut.deprecatedEnum@phpstan-self-out标签引用废弃枚举
requireExtends.deprecatedEnum@phpstan-require-extends标签引用废弃枚举
requireImplements.deprecatedEnum@phpstan-require-implements标签引用废弃枚举
traitUse.deprecatedEnumuse特质引用废弃枚举
generics.deprecatedEnumBound@template T of边界约束引用废弃枚举
generics.deprecatedEnumDefault@template T =默认值引用废弃枚举

这些标识符的命名与 CLAUDE.md 中"Identifier prefix reference"一节的规则一致——前缀(methodpropertynew等)表示废弃枚举出现的语言位置,后缀deprecatedEnum表示被废弃的对象类型。阅读同族文档可帮助你理解:只要代码库中某处引用了废弃枚举,PHPStan 就能在几乎所有引用点上给出提示。

如何修复

修复思路很直接:把废弃枚举的用法替换为推荐的替代枚举

方案一:替换为推荐的替代枚举

原文档给出的修复方案是将参数类型从OldStatus改为推荐的NewStatus

<?php declare(strict_types = 1); -function doFoo(OldStatus $status): void +function doFoo(NewStatus $status): void { $status->label(); }

注意,仅替换调用点还不够——如果NewStatus是新枚举,还需要确认label()方法在新枚举中同样存在(或相应调整调用),并同步更新所有传入OldStatus的上游调用方,避免类型不匹配引发新的method.notFound或参数类型错误。

方案二:配合 PHPStan 的 reportUnmatchedIgnoredErrors 进行迁移管理

在大型代码库中一次性替换所有废弃枚举的用法往往不现实。推荐的迁移路径是:先让 PHPStan 在 baseline 中记录现有错误(ignorable: true意味着这些错误可以被ignoreErrors或 baseline 机制忽略),再逐步替换。例如在phpstan.neon中通过phpstan-baseline.neon收纳现有问题,替换完成后配合reportUnmatchedIgnoredErrors检查不再触发的忽略项,确保没有遗留的"过时忽略"。仓库中的 e2e/baseline 目录展示了 baseline 机制的最小配置形态(includes: phpstan-baseline.neon),可作为参考。

方案三:正在迁移中的代码可临时标记废弃

如果你的调用方代码本身属于废弃迁移的一部分(即它也在被废弃的 API 链路上),可以给调用方函数或类加上@deprecated标记——deprecation-rules 对"废弃代码调用废弃 API"的场景通常不再报告,从而避免迁移中间态的噪音。这一点在同族文档 staticMethod.deprecatedEnum.md 中有明确说明:

+/** @deprecated */ function doFoo(): void { OldStatus::getDefault(); }

用 ignoreErrors 精确忽略单点错误

如果某个调用确实无法立即修复,也可以使用 PHPStan 的ignoreErrors配置按标识符精确忽略,例如在phpstan.neon中:

parameters: ignoreErrors: - identifier: method.deprecatedEnum path: src/Legacy/OrderHandler.php

由于该标识符ignorable: true,PHPStan 会接受这类按标识符的忽略规则,并将匹配情况纳入未匹配忽略项的报告。

延伸:废弃枚举相关边界情况

枚举无法实例化,new.deprecatedEnum是理论上的标识符

同族文档 new.deprecatedEnum.md 指出一个有趣的边界:PHP 本身不允许对枚举使用new,因此触发该标识符的代码在语法层面就无法成立。PHPStan 在这种情况下总是同时报告new.enum错误,而new.deprecatedEnum在实践中不会被单独报出。这提醒我们:不要为了触发某个标识符而构造不可能执行的代码,错误标识符的设计以真实可写的代码为准。

枚举的静态方法调用同样会被拦截

staticMethod.deprecatedEnum.md 展示了另一种常见形态——在废弃枚举上调用静态方法:

OldStatus::getDefault(); // ERROR: Static method getDefault() of deprecated enum OldStatus.

该文档还补充了一个重要细节:在废弃枚举上调用被标记废弃的静态方法也会报告此错误,无论枚举本身是否废弃。也就是说,废弃枚举本身与废弃方法任一方命中都会触发报告,二者是"或"的关系。

属性类型引用废弃枚举

property.deprecatedEnum.md 展示了废弃枚举作为属性类型声明时的报告(同时覆盖静态属性的访问场景)。这印证了废弃标记会沿类型声明传播:一旦枚举被废弃,所有把它作为类型的代码位置都会进入 deprecation-rules 的监控范围。

与 PHPStan 错误标识符体系的关联

method.deprecatedEnum是 PHPStan 2.x 错误标识符体系的一部分。标识符为每条错误提供了稳定的机器可读 ID,使得ignoreErrors可以按语义精确匹配,而不是依赖易碎的错误消息文本。这一体系的文档生成规范记录在 CLAUDE.md 中,其格式要求每条错误文档包含:触发代码示例、报告原因解释、修复方式三部分,并统一以diff-php展示代码变更。本文对应的 method.deprecatedEnum.md 即是该规范的标准产物。

若要进一步研究该标识符的底层实现,可以查看 errorsIdentifiers.json 中method.deprecatedEnum条目,其中记录了规则类RestrictedDeprecatedMethodUsageExtension及其在phpstan/phpstan-deprecation-rules仓库中的源码定位;phpstan-deprecation-rules是独立于本仓库发布的扩展包,需要在项目中通过 Composer 单独安装并在phpstan.neon中引入其配置文件后,该类错误才会被启用。

小结

  • method.deprecatedEnum在"调用被@deprecated标记枚举的实例方法"时报告,即使方法本身未废弃;
  • 该错误由phpstan/phpstan-deprecation-rules扩展的RestrictedDeprecatedMethodUsageExtension规则产生,同族标识符覆盖了废弃枚举在类型、属性、常量、参数、PHPDoc 标签等全部引用位置;
  • 修复的核心是替换为推荐枚举;迁移中可借助 baseline、@deprecated传递标记或按标识符ignoreErrors平滑推进;
  • 该标识符ignorable: true,支持通过ignoreErrors.identifier精确忽略。

【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询