
PHP-CS-Fixerindentation_type规则详解统一缩进风格强制 PSR-2 缩进规范【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer导读indentation_type是 PHP-CS-Fixer 中负责统一代码缩进风格的 Fixer 规则其核心目标是让项目中的每一行代码都使用配置指定的缩进类型默认 4 个空格并自动消除制表符Tab与空格混用带来的缩进混乱。本文将以 doc/rules/whitespace/indentation_type.rst 为主体骨架结合IndentationTypeFixer源码实现、单元测试与规则集定义深入讲解该规则的修复行为、与indent配置项的关系、所属规则集以及实际使用建议。读完本文你将能准确理解该规则在 PSR-2/PSR-12/PER 规范中的定位掌握其与whitespace_after_comma_in_array、array_indentation等相邻规则的协作方式并能在实际项目中安全地启用它。一、规则是什么Code MUST use configured indentation type在 IndentationTypeFixer.php 中规则的定义一句话概括Code MUST use configured indentation type.代码必须使用配置好的缩进类型。也就是说这条规则本身不限定必须用空格或必须用 Tab而是以 PHP-CS-Fixer 的全局空白配置indent为准把文件中所有与配置不符的缩进统一改写为配置值。默认情况下indent为 4 个空格因此开箱即用的效果是所有缩进 Tab 都会被转换为 4 个空格。规则文档给出的标准示例diff 形式如下--- Original New ?php if (true) { -TABecho Hello!; echo Hello!; }即if块内的语句原本以 Tab 缩进修复后变为 4 个空格其余内容保持不变。注意这里修复的是行首的缩进而不会动到行内用于对齐的空格详见下文“对齐空格不被动”一节。规则定位与优先级所属命名空间PhpCsFixer\Fixer\Whitespace优先级getPriority()返回50见 IndentationTypeFixer.php且源码注释明确要求必须在PhpdocIndentFixer之前运行否则 phpdoc 的缩进会被二次改写必须在ClassAttributesSeparationFixer之后运行类属性分隔的空行处理先完成再统一缩进。候选判定isCandidate()检查 token 流中是否存在T_COMMENT、T_DOC_COMMENT或T_WHITESPACE见 IndentationTypeFixer.php。即只有代码里出现注释、文档注释或空白 token 时才需要处理纯单行无缩进的代码会直接跳过从而保证运行性能。二、底层实现Fixer 究竟改了什么IndentationTypeFixer继承自AbstractFixer并实现WhitespacesAwareFixerInterface因此它能感知全局空白配置缩进字符串与换行符。修复过程在applyFix()中分为两类 token 处理见 IndentationTypeFixer.php注释类 tokenT_COMMENT/T_DOC_COMMENT调用fixIndentInComment()把注释块每一行行首的 Tab 转换为 4 个空格再把“4 空格”按配置缩进折算空白类 tokenT_WHITESPACE调用fixIndentToken()用正则/(\R)(\h)/找到换行符后的水平缩进先做“混合缩进归一化”再按配置换算。归一化逻辑Tab → 4 空格 → 配置缩进fixIndentToken()中见 IndentationTypeFixer.php执行了两步关键操作第一步把“1~3 个空格 Tab”或“任意空格 Tab”的混合缩进统一替换为 4 空格例如\t、\t、\t都会被归一化第二步getExpectedIndent()见 IndentationTypeFixer.php判断若配置的indent是\t则把 4 空格反向替换回 Tab否则保持 4 空格或配置的 2 空格不变。因此该规则本质上是双向的配置为空格时把 Tab 转空格配置为 Tab 时把空格转 Tab。这正是“configured indentation type”的含义。对齐空格不被动单元测试中专门有一条用例名为do not touch whitespace that is not indentation见 IndentationTypeFixerTest.phpfunction myFunction() { $foo 1; // 修复后行首变 Tab但行内对齐空格保持不变 //abc $myFunction 2; $middleVar 1; }测试证实当配置缩进为 Tab 时行首缩进会被替换为 Tab但变量赋值对齐用的行内空格原样保留。这是该规则安全性的重要保证——它不会破坏你精心对齐的赋值列。字符串内的 Tab 不受影响fixIndentToken()只处理空白 token 中的换行后缩进而字符串字面量如a: \t或 heredoc 内的 Tab不属于缩进上下文。测试用例?php $x a: \t;见 IndentationTypeFixerTest.php验证了这一点字符串内部的 Tab 不会被改写。注释块的处理细节fixIndentInComment()见 IndentationTypeFixer.php不仅处理行首 Tab还会用/^(?: )/m匹配连续 4 空格按配置折算缩进层级。测试覆盖了单层 Tab 缩进的 docblock 全部转为 4 空格IndentationTypeFixerTest.php多层 Tab 缩进的 docblock 转为多层 4 空格IndentationTypeFixerTest.php注释文本中“看起来像缩进”但实际是内容里的 Tab如should not be \t不会被误伤IndentationTypeFixerTest.php。三、配置来源indent从哪来IndentationTypeFixer通过WhitespacesAwareFixerInterface的setWhitespacesConfig()接收配置见 WhitespacesAwareFixerInterface.php。配置对象是WhitespacesFixerConfig其构造函数定义如下见 WhitespacesFixerConfig.phppublic function __construct(string $indent , string $lineEnding \n)合法取值被严格校验indent只能是 2 空格、 4 空格默认或\tTab传入其他值会抛出InvalidArgumentExceptionlineEnding只能是\n默认或\r\n。在 Config 中设置日常使用中你通常在.php-cs-fixer.php配置文件里通过Config对象设置缩进见 Config.php?php // .php-cs-fixer.php use PhpCsFixer\Config; return (new Config()) -setIndent(\t) // 把项目统一为 Tab 缩进 -setLineEnding(\n) -setRules([PER-CS true]);Config::setIndent()/setLineEnding()的定义见 Config.php。设置后所有实现WhitespacesAwareFixerInterface的 Fixer包括indentation_type、array_indentation、statement_indentation、method_chaining_indentation等都会使用这一全局缩进配置。适用前提WhitespacesFixerConfig与Config都限定缩进只能是 2 空格、4 空格或 Tab 三选一不存在“3 空格”这类自定义值。四、所属规则集跟随 PSR-2 / PSR-12 / PER-CS 全家桶根据规则文档与源码规则集定义indentation_type出现在以下规则集中规则集说明版本状态PER对应 PER.rst已废弃deprecatedPER-CS对应 PER-CS.rst当前推荐PER-CS1.0对应 PER-CS1.0.rst已废弃PER-CS1x0对应 PER-CS1x0.rst当前推荐PER-CS2.0对应 PER-CS2.0.rst已废弃PER-CS2x0对应 PER-CS2x0.rst当前推荐PER-CS3.0对应 PER-CS3.0.rst已废弃PER-CS3x0对应 PER-CS3x0.rst当前推荐PhpCsFixer对应 PhpCsFixer.rst—PSR2对应 PSR2.rst—PSR12对应 PSR12.rst—Symfony对应 Symfony.rst—从源码可以验证规则集的继承与归属链条PSR2直接声明启用indentation_type见 PSR2Set.php这正是 PSR-2 规范“使用 4 空格缩进、不使用 Tab”的直接落地PSR12继承自PSR2见 PSR12Set.php因此 PSR-12 也包含该规则PER-CS1x0继承自PSR12见 PERCS1x0Set.phpPER-CS2x0继承自PER-CS1x0见 PERCS2x0Set.phpPER-CS3x0继承自PER-CS2x0见 PERCS3x0Set.phpPER-CS当前别名对应 PERCSSet.php指向最新 PER 版本PhpCsFixer继承自PER-CS见 PhpCsFixerSet.phpSymfony继承自PER-CS3x0见 SymfonySet.php。所以结论很清晰只要你的项目使用了PSR2、PSR12、任意PER-CS*、Symfony或PhpCsFixer规则集就无需显式声明indentation_type它已经默认生效。只有当你使用自定义规则列表如--rules...且想单独启用时才需要显式写出规则名。五、命令行实战单独启用与典型用法通过--rules单独指定在不使用规则集的情况下可以直接在命令行指定规则参考 usage.rst 中的多规则示例写法php php-cs-fixer.phar fix /path/to/project --rulesindentation_type也可以与其它规则组合php php-cs-fixer.phar fix . --rulesline_ending,full_opening_tag,indentation_type在配置文件中启用?php // .php-cs-fixer.php use PhpCsFixer\Config; use PhpCsFixer\Finder; $finder Finder::create() -in(__DIR__./src) -in(__DIR__./tests); return (new Config()) -setFinder($finder) -setIndent( ) // 统一为 4 空格缩进 -setRules([ indentation_type true, // 显式启用 PER-CS true, // 或直接使用规则集已隐含该规则 ]);只检查不修改先用--dry-run --diff预览将被修改的文件与具体 diff确认缩进改动符合预期后再实际执行php php-cs-fixer.phar fix . --rulesindentation_type --dry-run --diff六、行为验证测试用例透露的边界规则文档明确指出“The test class defines officially supported behaviour. Each test case is a part of our backward compatibility promise.”测试类定义了官方支持的行为每个测试用例都是向后兼容承诺的一部分。因此 IndentationTypeFixerTest.php 就是该规则行为的权威依据值得归纳其覆盖的关键边界纯 Tab 转空格\t\techo ...→ 8 空格L52-L64各种 Tab 与空格混合\t、\t、\t、\t、\t、\t、\t等混合缩进全部归一化为 4 空格倍数L66-L162字符串内容保护a: \t中的 Tab 不动L164-L166多行字符串保护heredoc 内的 Tab 原样保留L168-L174docblock / 注释转换注释与文档注释中的行首 Tab 转为空格L176-L228尾部?后的缩进?\r\n\t$a ...不被误改L230-L232反向转换空格 → Tab测试还通过new WhitespacesFixerConfig(\t, \r\n)与new WhitespacesFixerConfig( , \r\n)双向跑同一批用例L234-L242验证了配置为 Tab 时把 4 空格转回 Tab 的能力自定义 2 空格缩进new WhitespacesFixerConfig( )场景下嵌套if、函数调用参数换行与注释块都按 2 空格为单位换算L244-L292。七、常见问题与协作建议1. 与其它缩进类 Fixer 的关系indentation_type只负责“缩进单位”的统一Tab 还是空格、几个空格而不负责缩进层级的计算。层级类缩进由以下 Fixer 负责array_indentation数组元素的多层缩进statement_indentation控制结构内语句缩进method_chaining_indentation方法链缩进。这些 Fixer 同样实现WhitespacesAwareFixerInterface共享同一个indent配置因此全局设置一次即可保持一致。2. 运行顺序的重要性由于IndentationTypeFixer优先级为 50且要求先于PhpdocIndentFixer、后于ClassAttributesSeparationFixer运行建议不要单独调整涉及这些规则的自定义顺序配置。PHP-CS-Fixer 内置的优先级调度getPriority()会自动保证正确顺序。3. 团队协作场景在多人协作仓库中建议在.php-cs-fixer.php中显式固定setIndent()并在 CI 中运行php php-cs-fixer.phar fix --dry-run --diff这样任何人的本地 IDE 设置Tab 或空格都不会影响最终入库代码从源头避免缩进 diff 噪音。总结indentation_type是 PHP-CS-Fixer 中基础但极其重要的空白类规则它以全局indent配置为准把代码中所有缩进统一为配置的缩进类型双向支持“Tab ↔ 空格”转换同时智能保护字符串内容与行内对齐空格。它内置于PSR2、PSR12、全部PER-CS*、Symfony与PhpCsFixer规则集配合 WhitespacesFixerConfig 的严格校验2 空格 / 4 空格 / Tab 三选一为 PHP 项目的缩进一致性提供了确定性的自动保障。相关实现可继续阅读 IndentationTypeFixer.php 与 IndentationTypeFixerTest.php测试类即官方支持行为的完整清单。【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考