PHP-CS-Fixer 的 no_spaces_inside_parenthesis 规则:清理括号内空白与弃用迁移指南
PHP-CS-Fixer 的 no_spaces_inside_parenthesis 规则清理括号内空白与弃用迁移指南【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer本指南围绕 PHP-CS-Fixer 仓库中no_spaces_inside_parenthesis这一 Whitespace 类规则展开介绍它强制开括号后、闭括号前不得有空格的行为、在实际项目中如何启用与验证以及它被spaces_inside_parentheses替代后的迁移路径。读完本文你将能理解该规则的底层实现与边界行为如换行、注释、list()尾部逗号等豁免场景并掌握用新规则无缝替换旧规则的配置方法。规则概览一句话规则一整套约定在 no_spaces_inside_parenthesis.rst 中规则被定义为There MUST NOT be a space after the opening parenthesis. There MUST NOT be a space before the closing parenthesis.即开括号(之后不允许出现空格闭括号)之前不允许出现空格。它针对的是 PSR-2 规范第 ¶4.3、¶4.6 与 ¶5 节中关于括号书写的约定见 NoSpacesInsideParenthesisFixer.php 的类注释覆盖控制结构、函数调用、函数声明等几乎所有出现圆括号的语法位置。注意本规则只处理圆括号普通()与类实例化括号不涉及方括号[]与花括号{}。弃用警告请在 4.0 之前完成迁移该文档与源码均明确标注了弃用状态文档 no_spaces_inside_parenthesis.rst 的 Warning 段落声明本规则已DEPRECATED将在下一个主版本 4.0 中移除源码 NoSpacesInsideParenthesisFixer.php 的类声明同时实现了AbstractProxyFixer与DeprecatedFixerInterface并带有deprecated in favour of SpacesInsideParenthesisFixer注释。官方给出的迁移建议非常明确改用spaces_inside_parentheses。前者是后者的一个代理proxy实现——看createProxyFixers()方法即可确认// src/Fixer/Whitespace/NoSpacesInsideParenthesisFixer.php protected function createProxyFixers(): array { return [new SpacesInsideParenthesesFixer()]; }也就是说no_spaces_inside_parenthesis本身不包含任何独立的修复逻辑它只是把工作委托给SpacesInsideParenthesesFixer并保持默认配置space none即不要额外空格因此两者的默认行为完全一致。行为示例两种典型修复文档给出了两个官方 diff 示例这里完整保留并补充说明。示例一控制结构与函数调用--- Original New ?php -if ( $a ) { - foo( ); if ($a) { foo(); }开括号后的空格、闭括号前的空格被一并移除if条件与空参数调用foo()恢复标准书写。示例二函数声明--- Original New ?php -function foo( $bar, $baz ) function foo($bar, $baz) { }参数列表( $bar, $baz )两侧的空格被清除括号与参数之间不留空白。源码原理代理机制、优先级与候选判断底层修复逻辑真正的修复动作在 SpacesInsideParenthesesFixer.php 中完成。它继承AbstractFixer并实现ConfigurableFixerInterface通过ConfigurableFixerTrait支持配置项下文详述。核心处理流程applyFix()SpacesInsideParenthesesFixer.php大致为遍历 token 流找到普通(与类实例化括号CT::T_CLASS_INSTANTIATION_PARENTHESIS_OPEN用Tokens::detectBlockType()与findBlockEnd()定位配对的闭括号移除开括号后的空白、闭括号前的空白仅当该空白是不含换行的纯空格时才会被清理见removeSpaceAroundToken()SpacesInsideParenthesesFixer.php。候选判断isCandidateno_spaces_inside_parenthesis的候选判断只检查源码中是否存在(NoSpacesInsideParenthesisFixer.phppublic function isCandidate(Tokens $tokens): bool { return $tokens-isTokenKindFound((); }因此只要文件里没有任何圆括号例如纯声明文件该 fixer 就会被跳过不会做无谓的遍历。执行优先级该规则返回优先级3NoSpacesInsideParenthesisFixer.php并声明了严格的先后关系必须运行在FunctionToConstantFixer、GetClassToClassKeywordFixer、StringLengthToEmptyFixer之前必须运行在CombineConsecutiveIssetsFixer、CombineNestedDirnameFixer、IncrementStyleFixer、LambdaNotUsedImportFixer、ModernizeStrposFixer、NoUselessSprintfFixer、PowToExponentiationFixer之后。仓库在 tests/Fixtures/Integration/priority/ 目录下提供了成对的集成测试夹具来锁定这些顺序例如 combine_consecutive_issets,no_spaces_inside_parenthesis.test 验证了isset($x-foo) isset($x-bar)先被合并为isset($x-foo, $x-bar)后再做括号清理。从源码结构可以推断优先级设计是为了避免上游 fixer 生成新的括号空白也避免下游 fixer 因括号形态变化而误判。边界行为哪些情况不会被一刀切处理官方测试类 NoSpacesInsideParenthesisFixerTest.php 是向后兼容承诺的一部分文档末尾明确每个测试用例都是 backward compatibility promise 的组成部分从中可以归纳出以下重要豁免场景list()尾部逗号list($path, $mode, ) foo();与list($path, $mode,) foo();均保持不变测试第 110-117 行。源码中对应逻辑是若闭括号前的有意义 token是逗号,则跳过闭括号前的空格清理SpacesInsideParenthesesFixer.php避免破坏list()的尾部逗号语法换行与多行参数testLeaveNewLinesAlone()测试第 128-149 行证明多行调用中括号内侧的换行与缩进不会被触碰因为removeSpaceAroundToken()只清理不含\n的空白注释开括号后紧跟注释时注释与(之间的空白会被保留源码第 136 行!isComment()判断多行注释场景在测试第 119-125 行有对应夹具数组字面量array( 1, 2, 3 )与[ 1, 2, 3 ]不在本规则处理范围测试第 98-108 行。源码中若(前是T_ARRAY关键字则直接跳过SpacesInsideParenthesesFixer.php方括号则因候选判断不含[而天然不受影响PHP 版本相关测试还覆盖了 PHP 8.0 的mixed类型参数testFix80与 PHP 8.1 的一等可调用语法strlen( ... )testFix81后者修复为strlen(...)说明新语法同样被正确处理。这些豁免逻辑意味着该规则并不是简单粗暴的删空格而是经过精心设计的、对语法敏感的规范化工具。迁移到 spaces_inside_parentheses由于新规则是完全可配置的CONFIGURABLE迁移后你还能获得旧规则没有的能力统一为单个空格。配置项说明space选项定义见 SpacesInsideParenthesesFixer.php取值含义默认值none括号内侧不留任何额外空格✅默认single括号内侧的空格统一为单个空格否对应文档 spaces_inside_parentheses.rst 中space选项的说明Allowed values 为none与single默认值为none。配置示例.php-cs-fixer.php中与旧规则等价的最小配置?php return (new PhpCsFixer\Config()) -setRules([ spaces_inside_parentheses true, // 等价于 [space none] ]) ;需要括号内统一一个空格的风格时?php return (new PhpCsFixer\Config()) -setRules([ spaces_inside_parentheses [space single], ]) ;single模式的效果以官方文档示例spaces_inside_parentheses.rst为准--- Original New ?php -if ($a) { - foo( ); if ( $a ) { foo(); }注意foo( )在single模式下被修复为foo()——因为空括号内没有任何内容不需要空格而if ($a)被统一为if ( $a )。同理--- Original New ?php -function foo($bar, $baz) function foo( $bar, $baz ) { }源码中对应逻辑是先判断括号块内是否除空格之外没有其他内容空括号场景直接删除空格SpacesInsideParenthesesFixer.php否则在括号内侧插入/规范化为单个空格fixParenthesisInnerEdge()SpacesInsideParenthesesFixer.php同时保留换行与注释场景。规则集覆盖情况spaces_inside_parentheses已被多个官方规则集启用见 spaces_inside_parentheses.rstPER-CS及 1.0/2.0/3.0 各版本线、PhpCsFixer、PSR2、PSR12、Symfony。其中 PSR2Set.php 以spaces_inside_parentheses true形式启用因此使用PSR2、PSR12或PER-CS等规则集的用户其实已经在享受这一行为。作为对比旧规则no_spaces_inside_parenthesis并未出现在当前任何规则集定义中——这也是它在文档与 doc/rules/index.rst 中仅以已弃用身份存在的原因之一。使用与验证命令行直接运行规则仓库自带可执行入口 php-cs-fixer# 使用旧规则 php php-cs-fixer fix /path/to/file.php --rules{no_spaces_inside_parenthesis: true} # 推荐使用新规则 php php-cs-fixer fix /path/to/file.php --rules{spaces_inside_parentheses: true} # 或采用 single 模式 php php-cs-fixer fix /path/to/file.php --rules{spaces_inside_parentheses: {space: single}}若使用规则集则无需显式声明php php-cs-fixer fix /path/to/project --rulesPER-CS验证行为是否符合预期可直接运行仓库测试vendor/bin/phpunit tests/Fixer/Whitespace/NoSpacesInsideParenthesisFixerTest.php该测试类基于AbstractFixerTestCase其provideFixCases()数据提供器NoSpacesInsideParenthesisFixerTest.php中每一对 expected/input 都是官方承诺的稳定行为可作为迁移前后行为等价性的对照基准。小结no_spaces_inside_parenthesis是一条行为简单、边界细腻的括号空白规则默认删除括号内侧的空格但对换行、注释、list()尾部逗号与数组字面量保持克制。它在当前版本中已进入弃用通道将于 4.0 移除其全部能力由spaces_inside_parentheses继承并扩展出spacesingle模式。对新项目或正在维护的旧项目直接使用spaces_inside_parentheses是最稳妥的选择——它既保持了向后兼容的默认行为又提供了更丰富的代码风格控制力。【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考