ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

PHP-CS-Fixer braces 规则深度解析:大括号规范化与从 deprecated 到 braces_position 的迁移实践

PHP-CS-Fixer braces 规则深度解析:大括号规范化与从 deprecated 到 braces_position 的迁移实践 开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载PHP-CS-Fixer 的braces规则Fixer 类位于 src/Fixer/Basic/BracesFixer.php用于强制每一段结构体类、函数、控制结构等的代码体必须被花括号包裹、花括号位置规范、代码体缩进正确。本篇以官方文档 doc/rules/basic/braces.rst 为骨架结合仓库源码与规则集配置完整讲解该规则的 5 个可配置项、3 组官方示例并给出它在当前版本已被废弃后的迁移路径与等价位配置方案帮助你理解并平滑升级到braces_position等新规则。规则概述它到底规范化了什么根据官方文档braces规则的核心理念是三条 MUST 约束每个结构体的代码体必须用花括号包围杜绝if (...) echo x;这类省略花括号的写法花括号本身应被正确放置在行首还是行尾花括号内的代码体应被正确缩进。该规则覆盖的对象非常广泛类、接口、trait、方法、普通函数、匿名类、闭包lambda、以及if/else/elseif/for/foreach/while/do/switch/try/catch/finally等控制结构。从源码看它对应的是 PSR-2 规范 §4.1、§4.4、§5 中关于花括号与缩进的要求见 BracesFixer.php 的类注释。重要提示该规则已被废弃DEPRECATED文档在开头就给出了醒目警告This rule isDEPRECATEDand will be removed in the next major version 4.0该规则已废弃将在下一个大版本 4.0 中移除。在代码层面BracesFixer.php 实现了DeprecatedFixerInterface见 src/Fixer/DeprecatedFixerInterface.php并通过getSuccessorsNames()显式声明其继任者——返回的正是内部代理的全部修复器名称BracesFixer.php。官方给出的替代方案是以下8 个规则继任规则职责文档single_space_around_construct控制结构关键字if/foreach/match等前后保持单个空格single_space_around_construct.rstcontrol_structure_braces控制结构代码体必须用花括号包裹control_structure_braces.rstcontrol_structure_continuation_position控制结构延续部分else/elseif/catch等的位置control_structure_continuation_position.rstdeclare_parenthesesdeclare语句的括号规范化declare_parentheses.rstno_multiple_statements_per_line一行不得出现多条语句no_multiple_statements_per_line.rstbraces_position各类结构体左花括号的位置braces_position.rststatement_indentation语句缩进规范化statement_indentation.rstno_extra_blank_lines移除多余空行花括号块场景no_extra_blank_lines.rst值得注意这 8 个继任规则与源码中createProxyFixers()创建的 8 个代理修复器一一对应BracesFixer.php也就是说braces从来不是自己写一套逻辑而是按固定顺序组合调用这 8 个规则。理解了这一点迁移就是水到渠成的事。5 个可配置项详解braces是CONFIGURABLE可配置规则官方文档列出 5 个选项。其默认配置组合形成了一套 PSR-2 风格 的花括号放置方案配置项作用允许类型/取值默认值allow_single_line_anonymous_class_with_empty_body是否允许单行匿名类且空代码体的写法boolfalseallow_single_line_closure是否允许单行闭包lambda写法boolfalseposition_after_anonymous_constructs匿名结构体匿名类、lambda之后左花括号放在 next下一行还是 same同行next/samesameposition_after_control_structures控制结构之后左花括号放在 next 还是 samenext/samesameposition_after_functions_and_oop_constructs类式结构非匿名类、接口、trait、方法、非 lambda 函数之后左花括号放在 next 还是 samenext/samenext从源码 createConfigurationDefinition() 可以看到这些选项的校验方式三个position_*选项通过setAllowedValues()限制取值必须为LINE_NEXTnext或LINE_SAMEsame常量BracesFixer.php两个allow_single_line_*选项通过setAllowedTypes([bool])限定布尔类型。选项到底如何生效到新规则配置的映射braces的配置并不会直接被 BracesFixer 使用而是在configurePostNormalisation()中被翻译并下发到两个核心代理修复器BracesFixer.php。这张映射表对迁移至关重要braces 选项翻译到 BracesPositionFixer 的选项翻译到 ControlStructureContinuationPositionFixerposition_after_control_structurescontrol_structures_opening_bracepositionposition_after_functions_and_oop_constructsfunctions_opening_brace、classes_opening_brace—position_after_anonymous_constructsanonymous_functions_opening_brace、anonymous_classes_opening_brace—allow_single_line_anonymous_class_with_empty_bodyallow_single_line_empty_anonymous_classes—allow_single_line_closureallow_single_line_anonymous_functions—其中next会被翻译为 BracesPositionFixer 的NEXT_LINE_UNLESS_NEWLINE_AT_SIGNATURE_ENDsame翻译为SAME_LINEtranslatePositionOption()。NEXT_LINE_UNLESS_NEWLINE_AT_SIGNATURE_END的语义是默认把左花括号放到下一行但如果签名末尾如参数闭合括号)前已经因多行参数而换行则保持与)同行参见 BracesPositionFixer.php 的实现。control_structure_continuation_position的position在next时取NEXT_LINE否则取SAME_LINE。因此braces的默认配置等价于以下显式配置// 等价于 braces 默认配置的新规则写法 braces_position [ control_structures_opening_brace same_line, functions_opening_brace next_line_unless_newline_at_signature_end, classes_opening_brace next_line_unless_newline_at_signature_end, anonymous_functions_opening_brace same_line, anonymous_classes_opening_brace same_line, allow_single_line_empty_anonymous_classes false, allow_single_line_anonymous_functions false, ], control_structure_continuation_position [position same_line],官方示例逐条拆解示例一默认配置下的完整修复效果默认配置下一段 花括号随意摆放 省略花括号 的代码会被一次性修正为 PSR-2 风格?php -class Foo { - public function bar($baz) { - if ($baz 900) echo Hello!; class Foo { public function bar($baz) { if ($baz 900) { echo Hello!; } - if ($baz 9000) if ($baz 9000) { echo Wait!; } - if ($baz true) - { if ($baz true) { echo Why?; - } - else - { } else { echo Ha?; } - if (is_array($baz)) - foreach ($baz as $b) - { if (is_array($baz)) { foreach ($baz as $b) { echo $b; } } } }这个示例集中展示了四条修复行为类与方法的大括号换行class Foo {→class Foo{方法同理——这正是position_after_functions_and_oop_constructs next的默认效果省略花括号的控制结构补全if ($baz 900) echo Hello!;→ 补上{ ... }同时嵌套的if包裹foreach也会为foreach补全花括号——这是control_structure_braces的职责花括号位置与else同行} \n else \n {→} else {——这是control_structure_continuation_position的职责代码体缩进修正foreach内层echo $b;的缩进被同步调整——这是statement_indentation的职责。示例二开启单行闭包allow_single_line_closure true?php $positive function ($item) { return $item 0; }; $negative function ($item) { - return $item 0; }; return $item 0; };单行闭包$positive因为满足 单行且简洁 的条件而被保留而$negative实际内容跨了多行属于伪单行写法被拆成标准的换行缩进形式。注意修复后$positive这种function ($item) { return $item 0; };写法得以保留正是allow_single_line_closure true即新规则中的allow_single_line_anonymous_functions的作用。示例三类式结构大括号同行position_after_functions_and_oop_constructs same?php -class Foo -{ - public function bar($baz) - { - if ($baz 900) echo Hello!; class Foo { public function bar($baz) { if ($baz 900) { echo Hello!; } - if ($baz 9000) if ($baz 9000) { echo Wait!; } - if ($baz true) - { if ($baz true) { echo Why?; - } - else - { } else { echo Ha?; } - if (is_array($baz)) - foreach ($baz as $b) - { if (is_array($baz)) { foreach ($baz as $b) { echo $b; } } } }将position_after_functions_and_oop_constructs设为same后类与方法改为 Allman 变体——左花括号与声明同行class Foo {、public function bar($baz) {而控制结构仍保持if (...) {同行风格因为position_after_control_structures默认仍是same。这演示了不同结构体可以混用不同的括号风格。源码实现代理修复器Proxy Fixer机制braces能一次完成这么多修复关键在于它继承自AbstractProxyFixer见 src/AbstractProxyFixer.php。该抽象类在构造函数中收集createProxyFixers()返回的修复器列表并按照优先级排序后存储AbstractProxyFixer.php执行修复时依次调用每个代理修复器的fix()方法AbstractProxyFixer.php。braces实际代理的 8 个修复器及其配置createProxyFixers()return [ $singleSpaceAroundConstructFixer, // 关键字前后单空格 new ControlStructureBracesFixer(), // 控制结构补花括号 $noExtraBlankLinesFixer, // 移除花括号块内多余空行 $this-getBracesPositionFixer(), // 花括号位置 $this-getControlStructureContinuationPositionFixer(), // else/catch 延续位置 new DeclareParenthesesFixer(), // declare 括号 new NoMultipleStatementsPerLineFixer(), // 单行多语句拆分 new StatementIndentationFixer(true), // 语句缩进 ];其中SingleSpaceAroundConstructFixer被配置为对elseif/for/foreach/if/match/while/use_lambda之后保留单空格、对use_lambda之前保留单空格NoExtraBlankLinesFixer被限定只处理curly_brace_block场景。执行优先级braces自身的优先级为35getPriority()文档化的执行约束是必须早于HeredocIndentationFixer执行必须晚于ClassAttributesSeparationFixer、ClassDefinitionFixer、EmptyLoopBodyFixer、NoAlternativeSyntaxFixer、NoEmptyStatementFixer、NoUselessElseFixer、SingleLineThrowFixer、SingleSpaceAfterConstructFixer、SingleSpaceAroundConstructFixer、SingleTraitInsertPerStatementFixer执行。而代理链内部的顺序则由Utils::sortFixers()按各子修复器的优先级统一排序例如ControlStructureBracesFixer优先级为 1、BracesPositionFixer为 -2保证先补全花括号、再调整位置与缩进的正确执行顺序。BracesPositionFixer自身同样声明了严格的先后约束必须晚于ControlStructureBracesFixer、MultilinePromotedPropertiesFixer、NoMultipleStatementsPerLineFixer见 BracesPositionFixer.php。迁移指南用新规则替换 braces在.php-cs-fixer.php配置文件中将braces true替换为一组新规则即可获得完全等价甚至更精细的修复能力。以下配置完全复刻braces的默认行为?php // .php-cs-fixer.php return (new PhpCsFixer\Config()) -setRules([ // 替代废弃的 braces true single_space_around_construct true, control_structure_braces true, control_structure_continuation_position [position same_line], declare_parentheses true, no_multiple_statements_per_line true, braces_position [ control_structures_opening_brace same_line, functions_opening_brace next_line_unless_newline_at_signature_end, classes_opening_brace next_line_unless_newline_at_signature_end, anonymous_functions_opening_brace same_line, anonymous_classes_opening_brace same_line, allow_single_line_empty_anonymous_classes false, allow_single_line_anonymous_functions false, ], statement_indentation true, no_extra_blank_lines [tokens [curly_brace_block]], ]) -setFinder(PhpCsFixer\Finder::in(__DIR__));如果你原本配置了braces [allow_single_line_closure true]则对应将braces_position中的allow_single_line_anonymous_functions改为true并将allow_single_line_empty_anonymous_classes按需保留默认true如果你原本配置了position_after_functions_and_oop_constructs same则对应将functions_opening_brace与classes_opening_brace都改为same_line。迁移后可运行php-cs-fixer fix --dry-run --diff先行验证效果。迁移到新规则后还能获得braces不具备的更细粒度控制例如单独将anonymous_classes_opening_brace设为next_line_unless_newline_at_signature_end而不影响普通函数或通过allow_single_line_empty_anonymous_classes true保留new class { };这类空体单行匿名类。这些选项的完整定义见 BracesPositionFixer.php。规则集中的应用现状在当前仓库的官方规则集定义中src/RuleSet/Sets目录旧的braces规则已不再被任何规则集引用取而代之的是它的继任者PSR12PSR12Set.php与PSR2PSR2Set.php都启用braces_position其中PSR12的配置为[allow_single_line_anonymous_functions false, allow_single_line_empty_anonymous_classes true]SymfonySymfonySet.php同样启用braces_positionPSR2还额外启用了control_structure_braces。也就是说如果你使用PSR12、Symfony、PhpCsFixer等规则集花括号相关风格已经由新规则接管无需再手动配置braces。各规则集的完整花括号配置可查看 PSR12.rst、Symfony.rst、PhpCsFixer.rst。测试与向后兼容承诺官方文档强调测试类定义了官方支持的行为每一个测试用例都是向后兼容承诺的一部分。braces规则的测试位于 tests/Fixer/Basic/BracesFixerTest.php约 6000 行覆盖了各种花括号场景的输入输出对其继任者braces_position的测试位于 tests/Fixer/Basic/BracesPositionFixerTest.php同样以大量用例锁定了same_line、next_line_unless_newline_at_signature_end等所有取值组合的行为。如果你在迁移过程中发现新旧规则输出不一致这些测试文件就是判断哪种行为才是官方预期的权威依据。结语braces是 PHP-CS-Fixer 中最具代表性的聚合型修复器之一它把补花括号、摆位置、调缩进三件事打包成一个可配置规则。理解它的 5 个配置项与源码中的代理机制后迁移到braces_position等 8 个新规则只需按映射表逐项翻译配置且能获得更细粒度、更符合 PSR-12 时代风格的风格控制。对于新项目建议直接使用新规则或PSR12/Symfony规则集对于存量项目建议在升级到 4.0 之前完成上述配置迁移避免规则被移除后风格回归失控。赞分享开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载相关推荐PHP-CS-Fixer curly_braces_position 规则详解花括号位置的可配置化统一与 braces_position 迁移指南PHP CS Fixer curly_braces_position 规则详解花括号位置的可配置化统一与 braces_position 迁移指南 curly开发工具代码质量静态分析Lint格式化Windows终极优化神器Winhance中文版让系统飞起来的完整指南Windows终极优化神器Winhance中文版让系统飞起来的完整指南 你是不是经常觉得Windows系统越用越慢却不知道从哪里开始优化面对复杂的注册表设开发工具代码质量静态分析Lint格式化PHP-CS-Fixer 的 no_spaces_inside_parenthesis 规则清理括号内空白与弃用迁移指南PHP CS Fixer 的 no_spaces_inside_parenthesis 规则清理括号内空白与弃用迁移指南 本指南围绕 PHP CS Fixer开发工具代码质量静态分析Lint格式化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表