ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PHP-CS-Fixer `class_reference_name_casing` 规则详解:自动规范化内部类引用的大小写

PHP-CS-Fixer `class_reference_name_casing` 规则详解:自动规范化内部类引用的大小写 开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载本文围绕 PHP-CS-Fixer 内置的class_reference_name_casing修复器展开深入讲解它的核心行为——当代码中引用 PHP 内部类如Exception、Closure时必须使用该类的官方正确大小写。文章会从一条修复示例入手逐步拆解其源码实现原理、上下文判定逻辑、测试覆盖的边界情况以及如何通过Symfony/PhpCsFixer规则集或单条规则命令将其接入你的日常开发流程。读完本文你将准确掌握该规则修什么、不修什么、为什么这样修并能直接复制可运行的配置与命令。规则概述内部类引用必须使用正确大小写在 PHP 中类名本身不区分大小写new exception()与new Exception()在运行时是等价的但在统一编码规范的团队协作中混用大小写会破坏代码的一致性与可读性。class_reference_name_casing规则正是为此而生——它的官方定义为When referencing an internal class it must be written using the correct casing.也就是说当代码中引用了 PHP 自带的内部类internal class时该规则会把它强制改写为 PHP 官方声明的大小写。内部类指的是由 PHP 内核或已加载扩展注册的类例如Exception、Closure、LogicException、DateTime等。而用户自定义的类名不在本规则的处理范围内。该规则的唯一官方示例也是其FixerDefinition中内嵌的CodeSample见 src/Fixer/Casing/ClassReferenceNameCasingFixer.php--- Original New ?php -throw new \exception(); throw new \Exception();规则集归属随Symfony与PhpCsFixer自动生效该规则不需要单独配置即可进入两条常用规则集PhpCsFixer见 doc/ruleSets/PhpCsFixer.rstSymfony见 doc/ruleSets/Symfony.rst从源码可以确认这种继承关系src/RuleSet/Sets/SymfonySet.php 第 51 行直接声明了class_reference_name_casing true而 src/RuleSet/Sets/PhpCsFixerSet.php 第 30 行又通过Symfony true整体引入 Symfony 规则集。因此只要你的配置文件启用了Symfony或PhpCsFixer本规则会自动参与修复无需额外声明。对应地在项目文档 doc/rules/casing/class_reference_name_casing.rst 中也以链接形式收录了上述两条规则集与下述的 Fixer 类、测试类作为规则的权威出处。修复器实现原理从内部类清单到引用上下文判定整个修复逻辑集中在 src/Fixer/Casing/ClassReferenceNameCasingFixer.php核心分为三个步骤1. 构建内部类名映射表getClassNames()方法通过get_declared_classes()枚举当前 PHP 进程内所有已声明的类再用ReflectionClass::isInternal()筛选出由 PHP 内核/扩展提供的内部类最后生成一张小写名 → 官方名的映射表foreach (get_declared_classes() as $class) { if ((new \ReflectionClass($class))-isInternal()) { $classes[strtolower($class)] $class; } }这张表只构建一次静态缓存且完全取决于运行 PHP-CS-Fixer 时的 PHP 版本与已加载扩展。这也意味着规则能识别哪些内部类与当前运行环境的 PHP 版本强相关在较新 PHP 版本中新增的内部类如 PHP 8.x 引入的枚举相关类只有在对应版本的运行时下才会进入映射表。2. 识别类引用而不是任意标识符getClassReference()逐 token 扫描当前命名空间作用域只把符合以下特征的T_STRING视为类引用候选后一个有效 token 不是命名空间分隔符\即排除Foo\Bar这类多段名称的中间段前一个 token 是\如\Exception或者当前位于全局命名空间isGlobalNamespace()为真又或者前一个 token 不属于排除列表排除列表NOT_BEFORE_KINDS包括use ... as、T_AS、casePHP 8.1 枚举的 case、class/interface/trait/enum/function/const等声明关键字、::静态访问Foo::bar、-与?-对象属性访问$foo-exception、数组键前后 token 若恰好构成一个空括号块如())内的逗号边界则跳过若前一个 token 不是new且后一个 token 是(,;,或?之一也跳过——这一步是为了避免误伤函数调用名如exception()。经过这些过滤后剩余的标识符才会被yield出来作为待检查的类引用。3. 大小写归一化替换applyFix()对每个命中的引用做三件事通过NamespaceUsesAnalyzer收集当前命名空间内所有use导入的短名统一转小写判断该引用的小写形式是否命中内部类映射表且当前写法与官方写法不一致确认没有本地use别名覆盖即用户显式use Foo as exception时不去改动满足条件后用官方大小写的新Token替换原 token。整个过程中文件内注释、字符串字面量中的类名如exception字符串不会被触碰因为它们在 token 层面就不是T_STRING类引用。测试验证规则修什么与不修什么的权威边界测试类 tests/Fixer/Casing/ClassReferenceNameCasingFixerTest.php 是该项目向后兼容承诺的一部分每个用例都定义了官方支持的行为。结合这些用例可以总结出规则的精确边界会被修复的场景// 四种 new 写法全部统一为 Exception $a new exception; // - new Exception $b new \exception; // - new \Exception $c new exception(); // - new Exception() $d new \exception(); // - new \Exception() // ::class 静态引用 $e a.exception::class; // - a.Exception::class $f a.\exception::class; // - a.\Exception::class echo \exception::class; // - echo \Exception::class print(exception::class); // - print(Exception::class) // 继承与 catch 类型声明 class Foo extends exception {}; // - extends Exception catch(\logicexception $e) // - catch(\LogicException $e) catch(logicexception $e) // - catch(LogicException $e) catch(\INVALIDARGUMENTEXCEPTION|\logicexception $e) // - 多类型 catch 同样逐段修复 // 命名空间隔离仅全局命名空间引用会被修复 namespace Foo { $b new \exception; } // - new \Exception但 $a new exception 不动明确不会被修复的场景保持原样// 用户自定义符号大小写无关 class exception {}; // 类声明不修 interface exception {}; // 接口声明不修 trait exception {}; // trait 声明不修 function exception() {}; // 函数声明不修 const exception abc; // 常量声明不修 enum exception {} // PHP 8.1 枚举声明不修见 provideFix81Cases enum Foo { case exception; } // 枚举 case 不修 // 非类引用的使用方式 $a exception(); // 函数调用不修 $b new A\exception; // 非全局命名空间下、无前导 \ 的多段名称不修 $a Foo::exception; // 静态成员访问不修 $a $foo-exception; // 对象属性访问不修 $foo [const exception]; // 数组值/常量引用不修 // 显式 use 别名遮蔽 use Foo as exception; // 导入别名不修 use Sonata\Exporter\Writer\EXCEPTION; // 导入的第三方类名不修 class Foo { use exception; } // trait 使用不修 // 注释与字符串不修 // $a new exception(); // 行注释 /** $a new exception(); */ // 块注释此外还有几个值得注意的版本相关用例provideFix80Cases要求 PHP 8.0$var?-exception空安全属性访问不修provideFix81Cases要求 PHP 8.1多类型 catch含无变量形式catch(\InvalidArgumentException|\LogicException)会逐段修复provideFix83Cases要求 PHP 8.3类型化常量public const string ERROR ERROR、public const ?int EXCEPTION null、public const Bar ERROR Bar::X等常量名即使与内部类同名也不会被误改。这些测试共同保证了规则只做内部类引用的规范化这一件事绝不会把自定义类、常量、方法、属性或导入别名顺手改坏。实际使用如何在自己的项目中启用该规则方式一跟随规则集推荐在项目根目录创建.php-cs-fixer.php配置文件?php $finder PhpCsFixer\Finder::create() -in(__DIR__) -exclude(vendor); return (new PhpCsFixer\Config()) -setRules([ Symfony true, // 已包含 class_reference_name_casing // PhpCsFixer true, // 或使用更全的 PhpCsFixer 规则集 ]) -setFinder($finder);然后执行php-cs-fixer fix # 自动修复 php-cs-fixer fix --dry-run # 仅预览差异不写回文件方式二仅启用单条规则若只关心类引用大小写规范化可在规则数组中单独声明return (new PhpCsFixer\Config()) -setRules([ class_reference_name_casing true, ]) -setFinder($finder);也可以直接在命令行指定php-cs-fixer fix path/to/file.php --rulesclass_reference_name_casing使用前提与限制该规则不提供任何配置选项行为固定只修内部类引用的大小写识别范围取决于运行时的 PHP 版本与已加载扩展get_declared_classes()结果因此建议使用与目标运行环境一致的 PHP 版本执行修复以保证内部类清单的准确性规则与native_function_casing函数名大小写、native_type_declaration_casing类型声明大小写同属src/Fixer/Casing目录三者分工互补前者管类引用后两者分别管函数名与类型声明可组合使用形成完整的原生符号规范化方案。小结class_reference_name_casing是一个小而精准的修复器它利用运行时反射建立内部类清单通过 token 上下文分析精确识别真正的类引用并在尊重use别名与声明上下文的前提下把内部类引用统一为官方大小写。源码实现见 src/Fixer/Casing/ClassReferenceNameCasingFixer.php其全部行为边界由 tests/Fixer/Casing/ClassReferenceNameCasingFixerTest.php 以向后兼容承诺的形式固化。对于采用Symfony或PhpCsFixer规范的项目这一规则无需额外成本即可让代码中的exception、closure等写法自动归位为Exception、Closure。赞分享开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载相关推荐PHP-CS-Fixer final_internal_class 规则详解让内部类自动变为 finalPHP CS Fixer final_internal_class 规则详解让内部类自动变为 final final_internal_class 是 PHP开发工具代码质量静态分析Lint格式化PHP-CS-Fixer integer_literal_case 规则详解统一整数字面量大小写规范PHP CS Fixer integer_literal_case 规则详解统一整数字面量大小写规范 导读 integer_literal_case 是 PH开发工具代码质量静态分析Lint格式化PHP-CS-Fixer 的 phpdoc_inline_tag_normalizer 规则详解规范化 PHPDoc 内联标签的写法PHP CS Fixer 的 phpdoc_inline_tag_normalizer 规则详解规范化 PHPDoc 内联标签的写法 phpdoc_inlin开发工具代码质量静态分析Lint格式化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表