
开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载curly_braces_position是 PHP-CS-Fixer 中负责统一花括号摆放位置的可配置规则它允许你针对类、函数、匿名函数、匿名类以及if/for/switch等控制结构分别指定开括号是放在“签名末尾同一行”还是“另起一行”。本文以该规则的官方文档为主体结合 CurlyBracesPositionFixer 与 BracesPositionFixer 的实现源码、CurlyBracesPositionFixerTest 测试用例以及相关规则集配置完整讲解全部 7 个配置项、8 个官方示例、底层 Token 级工作原理与迁移到braces_position的注意事项。规则定位与弃用警告该规则的核心目标一句话即可概括花括号必须按照配置的方式摆放Curly braces must be placed as configured.。它属于可配置规则CONFIGURABLE配置入口覆盖 7 个选项allow_single_line_anonymous_functions、allow_single_line_empty_anonymous_classes、anonymous_classes_opening_brace、anonymous_functions_opening_brace、classes_opening_brace、control_structures_opening_brace、functions_opening_brace。需要特别注意的是curly_braces_position已被标记为 DEPRECATED弃用并将在下一个大版本 4.0 中移除。官方文档明确建议应当改用braces_position规则。两者的功能与配置项完全一致——CurlyBracesPositionFixer在实现上本身就是对BracesPositionFixer的薄封装见下文“代理架构”因此迁移时只需把规则名从curly_braces_position换成braces_position原有配置数组可以原样保留。底层实现代理 Fixer 架构与 Token 级处理从源码结构看CurlyBracesPositionFixer继承自AbstractProxyFixer见 src/AbstractProxyFixer.php并在构造时创建了一个BracesPositionFixer实例作为真正的执行者// src/Fixer/Basic/CurlyBracesPositionFixer.php final class CurlyBracesPositionFixer extends AbstractProxyFixer implements ConfigurableFixerInterface, DeprecatedFixerInterface, WhitespacesAwareFixerInterface { private BracesPositionFixer $bracesPositionFixer; public function __construct() { $this-bracesPositionFixer new BracesPositionFixer(); parent::__construct(); } // ... }该类同时实现了DeprecatedFixerInterface并通过getSuccessorsNames()声明后继者public function getSuccessorsNames(): array { return [ $this-bracesPositionFixer-getName(), ]; }也就是说curly_braces_position的配置解析createConfigurationDefinition()、规则定义getDefinition()乃至修复逻辑applyFix()全部委托给BracesPositionFixer弃用的只是规则名称本身。修复算法识别结构、定位开括号、搬移 Token真正的修复逻辑位于 BracesPositionFixer::applyFix()它逐 Token 遍历按结构类型分类处理类声明含匿名类遇到 classy token 后用getNextTokenOfKind($index, [{])找到开括号再通过TokensAnalyzer-isAnonymousClass()区分匿名类与具名类分别套用anonymous_classes_opening_brace与classes_opening_brace两个配置。函数/方法/匿名函数遇到T_FUNCTION后定位开括号若TokensAnalyzer-isLambda()判定为闭包则走anonymous_functions_opening_brace否则走functions_opening_brace。控制结构通过CONTROL_STRUCTURE_TOKENS常量匹配T_DECLARE、T_DO、T_ELSE、T_ELSEIF、T_FINALLY、T_FOR、T_FOREACH、T_IF、T_WHILE、T_TRY、T_CATCH、T_SWITCH以及FCT::T_MATCHmatch 表达式然后寻找参数括号的结束位置并取其后第一个有意义的 Token 作为开括号套用control_structures_opening_brace。属性钩子property hooks源码中还处理了CT::T_PROPERTY_HOOK_BRACE_OPEN相关逻辑这是 PHP 8.4 属性钩子语法支持的一部分从代码分支看多行属性钩子的开括号位置同样归入控制结构配置$positionOption control_structures_opening_brace;。在确定开括号目标位置后fixer 会执行两类核心操作保证{后的换行当花括号体内应换行$addNewlinesInsideBraces为真且开括号后没有换行、没有同行注释、后跟的也不是?时注入换行符 当前缩进。移动开括号本身根据配置把{之前的空白替换成 同一行或换行符 缩进下一行必要时连同相邻注释一起搬移代码中专门处理了/* */、//注释位于开括号前后的各种组合对应测试用例中的open brace preceded by comment and whitespace等场景。一个值得注意的细节是next_line_unless_newline_at_signature_end选项在搬移时还会回溯参数括号如果签名本身已经是多行的例如参数换行书写、返回类型跨行则回退为单个空格而不是强制换行——这正是该选项名称中unless_newline_at_signature_end的语义下面会结合示例说明。执行优先级PrioritygetPriority()返回-2并声明了与其他规则的先后关系见 BracesPositionFixer.php必须运行在SingleLineEmptyBodyFixer、StatementIndentationFixer之前必须运行在ControlStructureBracesFixer、MultilinePromotedPropertiesFixer、NoMultipleStatementsPerLineFixer之后。仓库中的集成测试文件 curly_braces_position,single_line_empty_body.test 验证了这一协作输入function foo()\n{\n}先由curly_braces_position处理花括号位置再由single_line_empty_body压缩成function foo() {}。同目录下还有control_structure_braces,curly_braces_position.test、curly_braces_position,statement_indentation.test、no_multiple_statements_per_line,curly_braces_position.test等组合用例说明该规则与花括号补充、语句缩进、单行多语句等规则存在紧密的先后依赖。配置项全解该规则的所有配置均通过BracesPositionFixer::createConfigurationDefinition()源码位置声明使用FixerOptionBuilder定义类型、允许值与默认值。下表汇总 7 个选项配置项类型允许值默认值默认值future-modeallow_single_line_anonymous_functionsbooltrue/falsetruefalseallow_single_line_empty_anonymous_classesbooltrue/falsetruetrueanonymous_classes_opening_bracestringnext_line_unless_newline_at_signature_end/same_linesame_linesame_lineanonymous_functions_opening_bracestringnext_line_unless_newline_at_signature_end/same_linesame_linesame_lineclasses_opening_bracestringnext_line_unless_newline_at_signature_end/same_linenext_line_unless_newline_at_signature_end同默认值control_structures_opening_bracestringnext_line_unless_newline_at_signature_end/same_linesame_linesame_linefunctions_opening_bracestringnext_line_unless_newline_at_signature_end/same_linenext_line_unless_newline_at_signature_end同默认值两个位置枚举值的语义same_line开括号放在签名或控制结构条件所在行的末尾即 Allman 之外的 KR / PSR-12 风格。next_line_unless_newline_at_signature_end默认把开括号放到下一行但如果签名末尾本身已经存在换行例如参数列表多行书写且最后一个)与签名内容之间有换行则保持{跟在)之后。测试用例next line with newline before closing parenthesis与next line with newline in signature but not before closing parenthesis分别演示了“)前有换行 → 同行”与“签名内有换行但)前无换行 → 下一行”两种判定结果。future-mode 默认值差异allow_single_line_anonymous_functions的默认值标注为“future-mode:false”。源码中使用Future::getV4OrV3(false, true)实现见 BracesPositionFixer.php在PHP_CS_FIXER_FUTURE_MODE1环境变量下运行或代码通过Future::runWithEnforcedFutureMode()开启时该选项默认取false与即将到来的 v4 默认行为对齐常规运行则取true。Future类的实现在 src/Future.php它同时负责在 future-mode 下把弃用用法升级为硬性报错。默认配置下的修复效果官方文档 Example #1 展示了默认配置的完整效果diff 中-为原始代码、为修复后?php -class Foo { class Foo { } -function foo() { function foo() { } -$foo function() -{ $foo function() { }; -if (foo()) -{ if (foo()) { bar(); } -$foo new class -{ $foo new class { };从中可以直观总结默认行为具名类与方法/函数的开括号换行classes_opening_brace、functions_opening_brace默认next_line_unless_newline_at_signature_end而控制结构if、匿名函数与匿名类的开括号保持同行对应三个选项默认same_line。这与 PSR-12 的风格基调一致。分结构定制7 个选项的独立示例由于 7 个选项彼此独立你完全可以只调整某一类结构的风格。官方文档给出了 8 个示例下面逐一呈现。示例 #2控制结构开括号换行配置[control_structures_opening_brace next_line_unless_newline_at_signature_end]?php -if (foo()) { if (foo()) { bar(); }该选项同样作用于else、elseif、for、foreach、while、do while、switch、try/catch/finally测试类中else (next line)、try catch finally (open brace on the next line)等用例逐一验证见 CurlyBracesPositionFixerTest.php。示例 #3函数开括号同行配置[functions_opening_brace same_line]?php -function foo() -{ function foo() { }示例 #4匿名函数开括号换行配置[anonymous_functions_opening_brace next_line_unless_newline_at_signature_end]?php -$foo function () { $foo function () { };示例 #5类开括号同行配置[classes_opening_brace same_line]?php -class Foo -{ class Foo { }示例 #6匿名类开括号换行配置[anonymous_classes_opening_brace next_line_unless_newline_at_signature_end]?php -$foo new class { $foo new class { };示例 #7空匿名类允许单行配置[allow_single_line_empty_anonymous_classes true]默认即true?php $foo new class { }; -$bar new class { private $baz; }; $bar new class { private $baz; };可见空匿名类{ }间没有任何代码可以保持单行而只要体内含有非空白、非注释内容private $baz;就会被强制展开为多行。从实现看fixer 会扫描开闭括号之间的 Token若存在非空白/非注释内容或换行则$addNewlinesInsideBraces置为真从而注入换行BracesPositionFixer.php。示例 #8匿名函数允许单行默认配置[allow_single_line_anonymous_functions true]默认即truefuture-mode 下为false?php $foo function () { return true; }; -$bar function () { $result true; - return $result; }; $bar function () { $result true; return $result; };单行闭包function () { return true; };保持不变而原本挤在一行内、实际上含换行的闭包会被规范地展开。多行签名与返回类型的智能处理从测试用例可以确认next_line_unless_newline_at_signature_end在处理带返回类型、联合类型、交叉类型甚至 DNF 类型的多行签名时相当细致多行参数 返回类型): int、): ?int、): array、): \Foo\Bar当)前存在换行时{跟随在)后同行用例next line with newline before closing parenthesis and return type当)前无换行时{换行。PHP 8.0 联合返回类型int|float、8.1 交叉返回类型FooBar、8.2 DNF 返回类型(FooBar)|int|null均有专门用例provideFix80Cases、provideFix81Cases、provideFix82Cases数据提供器。这些用例同时证明了该规则会随着 PHP 版本语法演进持续维护并在 CurlyBracesPositionFixerTest.php 中按RequiresPhp注解分版本约束执行。在官方规则集中的实际用法当前仓库的官方规则集PSR-12、PSR-2、Symfony 等已经直接采用后继者braces_position规则名。以 PSR12Set 为例braces_position [ allow_single_line_anonymous_functions false, allow_single_line_empty_anonymous_classes true, ],PSR12明确要求匿名函数不允许单行对应 PSR-12 关于闭包必须多行书写的规范同时允许空匿名类单行。PSR2与Symfony也各自声明了该规则SymfonySet。因此如果你通过PSR12或Symfony规则集启用风格检查花括号位置已经由这些默认配置覆盖若需自定义只需在项目配置中覆盖braces_position的对应选项即可。规则的完整规则集归属与配置可参考 braces_position.rst 文档的 Rule sets 一节。实战命令行与项目配置通过 CLI 直接启用在项目根目录存在.php-cs-fixer.dist.php或.php-cs-fixer.php配置文件时运行php php-cs-fixer.phar fix未配置时默认套用PSR12。若只想针对当前规则做一次检查而不改动文件可使用--dry-run等价于check命令php php-cs-fixer.phar check . --rulesbraces_position php php-cs-fixer.phar fix . --rulesbraces_position --dry-run用--rules以 JSON 形式传入完整配置php php-cs-fixer.phar fix . --rules{braces_position: {classes_opening_brace: same_line, functions_opening_brace: same_line, allow_single_line_anonymous_functions: false}}在项目配置文件中声明?php // .php-cs-fixer.dist.php return (new PhpCsFixer\Config()) -setRules([ PSR12 true, braces_position [ classes_opening_brace same_line, functions_opening_brace same_line, control_structures_opening_brace same_line, anonymous_functions_opening_brace same_line, anonymous_classes_opening_brace same_line, allow_single_line_anonymous_functions false, allow_single_line_empty_anonymous_classes true, ], ]) ;上述配置会把五类结构的开括号全部统一为同行风格Allman → KR 的一次性迁移场景。命令行的--rules参数与配置文件规则覆盖了fix、check、list-files等命令的通用用法详见 doc/usage.rst。用 describe 快速查看规则说明php php-cs-fixer.phar describe braces_position php php-cs-fixer.phar describe curly_braces_position # 会提示已弃用迁移清单与兼容性承诺由于curly_braces_position将在 v4.0 移除建议按如下清单迁移全局搜索配置文件中的curly_braces_position键替换为braces_position配置数组内容保持不变7 个选项名与取值完全一致关注allow_single_line_anonymous_functions的默认值变更v3 默认truev4 默认改为false可用PHP_CS_FIXER_FUTURE_MODE1 php php-cs-fixer.phar check .提前验证 future 行为参考 doc/usage.rst运行check确认无新增违规再执行fix落地。关于行为的权威性仓库文档明确声明测试类定义了官方支持的行为每个测试用例都是向后兼容承诺backward compatibility promise的一部分。因此 CurlyBracesPositionFixerTest.php 中从if (default)、else (next line)到open brace not preceded by space and followed by a space and comment的全部用例就是你判断某段代码会被如何修复的最可靠依据BracesPositionFixerTest 则对应新规则名的同等行为契约。小结curly_braces_position及其后继者braces_position是 PHP-CS-Fixer 中对花括号布局最精细的一把“手术刀”7 个独立配置项把类、函数、匿名函数、匿名类与控制结构五类开括号位置解耦配合allow_single_line_*两个布尔开关处理单行例外再叠加对多行签名、返回类型与注释边界的细节处理足以应对团队代码风格从 Allman 到 KR或反之的整体迁移也能只针对某一类结构做微调。理解其代理 Fixer 架构、next_line_unless_newline_at_signature_end的换行判定规则以及与SingleLineEmptyBodyFixer、StatementIndentationFixer等规则的执行顺序能帮助你在配置复杂规则集时做出正确取舍。赞分享开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载相关推荐三步搞定B站热门活动购票难题biliTickerBuy开源工具完全指南三步搞定B站热门活动购票难题biliTickerBuy开源工具完全指南 还在为抢不到Bilibili热门活动门票而烦恼吗biliTickerBuy是一款专为开发工具代码质量静态分析Lint格式化如何3分钟完成黑苹果配置OpCore Simplify图形化工具终极指南如何3分钟完成黑苹果配置OpCore Simplify图形化工具终极指南 还在为复杂的黑苹果OpenCore配置而头疼吗OpCore Simplify是一款开发工具代码质量静态分析Lint格式化PHP-CS-Fixer 规则集 PER-CS2.0 完整指南规则构成、配置详解与迁移到 PER-CS2x0PHP CS Fixer 规则集 PER CS2.0 完整指南规则构成、配置详解与迁移到 PER CS2x0 导读 PER CS2.0 是 PHP CS开发工具代码质量静态分析Lint格式化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考