PHP-CS-Fixer `magic_constant_casing` 规则详解:强制魔数常量使用正确大小写
PHP-CS-Fixermagic_constant_casing规则详解强制魔数常量使用正确大小写【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer本篇指南围绕 PHP-CS-Fixer 的magic_constant_casing规则展开讲解它如何将__dir__、__LINE__等 PHP 魔数常量统一修正为标准大写形式并深入源码分析其 token 级修复原理、规则集归属、PHP 版本边界与官方测试覆盖帮助你在代码库中一键消除魔数常量大小写不一致问题。规则概述什么是magic_constant_casingmagic_constant_casing是 PHP-CS-Fixer 中位于Casing大小写分类下的一条非 risky 规则。根据 规则文档 的定义其核心职责是Magic constants should be referred to using the correct casing.魔数常量应使用正确的大小写形式被引用。PHP 的魔数常量Magic Constants由语言预定义、值随上下文变化如当前行号、文件名、命名空间等它们不区分大小写因此__dir__、__DIR__、__Dir__在语法上等价且都能运行。但为了代码风格统一、避免可读性混乱该规则会把所有小写或混合大小写的写法统一修正为官方文档规定的标准全大写形式。该规则不涉及任何歧义改写属于安全的纯规范化修复适合放入默认规则集全量启用。规则覆盖的魔数常量清单从 MagicConstantCasingFixer 源码 可以看到规则内部维护了一张 token 类型到标准写法的映射表Token 类型标准形式说明T_LINE__LINE__文件中的当前行号T_FILE__FILE__文件的完整路径和文件名T_DIR__DIR__文件所在目录T_FUNC_C__FUNCTION__当前函数名T_CLASS_C__CLASS__当前类名T_METHOD_C__METHOD__当前类的方法名T_NS_C__NAMESPACE__当前命名空间名称T_TRAIT_C__TRAIT__当前 trait 名称CT::T_CLASS_CONSTANTclass类名解析关键字Foo::classFCT::T_PROPERTY_C__PROPERTY__当前属性名PHP 8.4其中有两个特殊成员值得注意CT::T_CLASS_CONSTANT这是 PHP-CS-Fixer 自定义的常量 token值为10008见 CT.php由 ClassConstantTransformer 将Foo::class中的class关键字转换而来。::class本身也是“魔数常量”语义编译期类名解析因此Foo::CLASS、Foo::ClAss同样会被修正为小写标准形式Foo::class。FCT::T_PROPERTY_C对应 PHP 8.4 新增的__PROPERTY__魔数常量在属性钩子中返回当前属性名。由于仓库需兼容更低版本的 PHP 运行环境这里通过 FCT 前向兼容 Token 类 在 PHP 8.4 以下时使用占位负值-844从而让代码在不同 PHP 版本下都能安全编译。修复效果示例规则文档给出了最典型的一则 diff 示例--- Original New ?php -echo __dir__; echo __DIR__;结合 官方测试用例 可以看到规则对每个魔数常量的各种混合大小写写法都能生效?php echo __line__; // 修正为 __LINE__ echo __FILe__; // 修正为 __FILE__ echo __dIr__; // 修正为 __DIR__ echo __fUncTiOn__; // 修正为 __FUNCTION__ echo __clasS__; // 修正为 __CLASS__ echo __mEthoD__; // 修正为 __METHOD__ echo __namespace__; // 修正为 __NAMESPACE__ echo __trait__; // 修正为 __TRAIT__ echo Exception::CLASS; // 修正为 Exception::class echo Exception::ClAss; // 修正为 Exception::class在 PHP 8.4 及以上环境测试还额外覆盖了__property__、__PrOpErTy__到__PROPERTY__的修正见 provideFix84Cases说明规则持续跟进语言新特性。规则集归属默认启用开箱即用根据 规则文档 的说明该规则包含在以下规则集中Symfony在 SymfonySet.php 中显式声明magic_constant_casing true。PhpCsFixer该集合基于PER-CS与Symfony组合而成见 PhpCsFixerSet.php因此间接包含本规则。也就是说只要你在配置中启用了Symfony或PhpCsFixer规则集无需任何额外配置即可获得该规则的修复能力。对应规则集清单可查看 PhpCsFixer 规则集文档 与 Symfony 规则集文档。底层实现原理基于 token 的精准替换该规则由 MagicConstantCasingFixer 实现继承自AbstractFixer整个修复流程分为两个阶段1. 候选判定isCandidate源码在 isCandidate 方法 中通过$tokens-isAnyTokenKindsFound($magicConstantTokenIds)快速扫描文件只要发现任一魔数常量 token含CT::T_CLASS_CONSTANT等自定义类型就判定为需要处理。这是一个低成本预筛能显著减少对无关文件的无效遍历。2. 实际修复applyFixapplyFix 方法 遍历全部 token对命中映射表的 token 直接以标准文本重建$tokens[$index] new Token([$tokenId, self::MAGIC_CONSTANTS[$tokenId]]);由于替换发生在token 层而不是字符串正则层规则天然不会误伤字符串字面量或注释中的__dir__文本例如echo __dir__;单引号字符串不会被改动。这也是 PHP-CS-Fixer 基于 tokenizer 架构的核心优势。版本边界与防御性处理规则对版本差异做了明确区分这一点在 测试类 中被固化为官方行为PHP 8.0::class尚未成为关键字。测试 provideFixPre80Cases 验证了用户自定义的类常量class Bar { const __line__ foo; }以及\Bar::__line__引用不会被改写——因为此时它只是普通类常量名而非魔数常量改写反而会破坏语义。PHP 8.4规则支持新的__PROPERTY__魔数常量且修复同样不区分大小写。这套“按 token 语义而非字符串匹配”的防御逻辑保证了规则在老旧代码如将__line__用作自定义常量名与前沿 PHP 版本之间都能安全运行。使用方式在项目根目录通过仓库入口脚本或 Composer 安装的二进制直接指定规则运行# 仅对该文件路径执行本规则 php php-cs-fixer fix path/to/file.php --rulesmagic_constant_casing # 或在启用 Symfony / PhpCsFixer 规则集后随全量修复一起生效 php php-cs-fixer fix --rules{Symfony: true}也可以在项目的.php-cs-fixer.php或.php-cs-fixer.dist.php配置文件中显式声明配置格式参见 config.rstreturn (new PhpCsFixer\Config()) -setRules([ magic_constant_casing true, // 或 Symfony true, // 规则已包含在其中 ]) ;如需在 CI 中只检查不修改可使用--dry-run --diff参数查看差异而不落盘参见 usage.rst。向后兼容承诺与测试保障PHP-CS-Fixer 将 Fixer 的测试用例视为向后兼容承诺的一部分每个测试用例代表官方支持的行为一旦行为变化即视为破坏性变更。magic_constant_casing的测试覆盖包括全部 10 类 token 的混合大小写输入 → 标准输出::class关键字的大小写归一PHP 8.4__PROPERTY__的专属测试通过#[RequiresPhp( 8.4.0)]属性按运行环境条件执行PHP 8.0 以下对自定义类常量的“不干预”保证。如果你正在为该项目贡献或自定义 FixerAbstractFixerTestCase 提供了doTest($expected, $input)的断言范式可直接参照本规则的测试写法。小结magic_constant_casing是一条轻量、安全、无配置项的规则它基于 token 语义将所有魔数常量统一为标准大小写随Symfony/PhpCsFixer默认启用并通过版本感知的测试用例严格锁定行为边界。对于追求代码风格一致性的团队它是成本最低、收益最直接的基础规则之一。【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考