- 开发工具
- 代码质量
- 静态分析
- Lint
- 格式化
【免费下载链接】PHP-CS-Fixer
A tool to automatically fix PHP Coding Standards issues
导读
phpdoc_single_line_var_spacing是 PHP-CS-Fixer 提供的 PHPDoc 规范化规则,用于修正单行@var注释中多余或缺失的空格,将其统一为/** @var Type $variable */的标准形态。本文以 规则文档 为主体,结合 Fixer 源码 与 单元测试,完整讲解该规则的行为边界、底层实现、与其他规则的协作顺序,以及如何在项目中使用与验证。读完本文,你将掌握该规则的精确作用范围、正则匹配逻辑与规则集启用方式,可直接落地到实际项目的代码风格配置中。
规则概述:修复什么
该规则的目标非常聚焦:单行@varPHPDoc 应当具有合适的间距(proper spacing)。官方FixerDefinition描述为 "Single line@varPHPDoc should have proper spacing."(见 PhpdocSingleLineVarSpacingFixer.php)。
在源码注释中,该 Fixer 的实现定位为 "Fixer for part of rule defined in PSR5 ¶7.22"(见 源码第 26 行),即其行为与 PSR-5 草案中关于 PHPDoc 格式的 7.22 节精神一致,属于 PHPDoc 规范化的一个组成部分。
需要特别强调边界:本规则只处理"单行"形式的@var注释,即整个注释在一行内以/**开头、以*/结束。对于多行@var注释(例如属性注释跨越多行),该规则不会插手。
核心示例:一条规则的典型修复
规则文档给出了唯一的官方示例:
--- Original +++ New -<?php /**@var MyClass $a */ +<?php /** @var MyClass $a */ $a = test();可以看到,这一条修复同时完成了三件事:
- 在
/**与@var之间补上缺失的空格(/**@var→/** @var); - 将
@var后多余的空格压缩为单个空格(@var MyClass→@var MyClass); - 将注释结尾
*/前的多余空格清除($a */→$a */)。
源码解析:修复是怎么发生的
候选检查(isCandidate)
Fixer 只对包含注释的文件生效。isCandidate()通过$tokens->isAnyTokenKindsFound([\T_COMMENT, \T_DOC_COMMENT])检查 Token 流中是否存在普通注释或文档注释(源码第 51-54 行)。只要文件里没有任何注释,该 Fixer 会直接跳过,不产生任何开销。
核心正则与替换逻辑
applyFix()遍历所有 Token,对每个注释 Token 调用fixTokenContent(),核心是一个Preg::replaceCallback(源码第 72-89 行):
'#^/\*\*\h*@var\h+(\S+)\h*(\$\S+)?\h*([^\n]*)\*/$#'逐段解读这个正则:
^/\*\*:注释必须严格以/**开头;\h*:/**与@var之间允许任意数量的水平空白(含空格与 Tab,但不含换行),会被压缩;@var:标签本体;\h+(\S+):@var后至少一个水平空白,随后捕获第一个非空白片段——即类型(如MyClass);(\$\S+)?:可选的变量名捕获组,以$开头(如$a);\h*([^\n]*)\*/$:变量名之后可以跟任意数量的水平空白以及剩余描述文本([^\n]*,不含换行,说明描述必须与类型同行),最后以*/结束。$锚定确保整个注释恰好匹配这一单行形态。
替换时,Fixer 以/** @var为前缀重建内容,将捕获到的"类型"、"变量名"、"描述"各组以单个空格拼接,最后用rtrim去掉尾部空白再补上*/。由于正则锚定了整行,任何不满足单行@var形态的注释(多行注释、含换行的注释、其他标签)都不会被改动。
输出 Token 类型
替换后的内容以[\T_DOC_COMMENT, $fixedContent]写回 Token 流(源码第 66-68 行),保证注释仍被识别为文档注释,不影响后续其他 PHPDoc 类规则的 Token 解析。
与其他规则的协作:优先级与依赖
Fixer 通过getPriority()声明执行顺序,返回-10,并明确注释了约束(源码第 40-49 行):
Must run before PhpdocAlignFixer. Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, PhpdocIndentFixer, PhpdocNoAliasTagFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer.
含义如下:
- 必须在 PhpdocAlignFixer 之前运行:
phpdoc_align负责把@var、@param等标签的类型与描述做垂直对齐(见 PhpdocAlignFixer.php)。先由本规则把单行@var的多余空格收敛为标准间距,phpdoc_align再基于干净的内容做列对齐,避免两次修复互相干扰; - 必须在 AlignMultilineCommentFixer、CommentToPhpdocFixer、PhpdocIndentFixer、PhpdocNoAliasTagFixer、PhpdocScalarFixer、PhpdocToCommentFixer、PhpdocTypesFixer 之后运行:这些规则会改变注释的形态、缩进、别名标签或标量类型写法,本规则必须在它们产出的"最终形态"上再做间距统一,否则会被后续改动再次打破。
这条依赖链说明,PHP-CS-Fixer 中 Fixer 之间并非独立执行,而是通过优先级组成确定的流水线,phpdoc_single_line_var_spacing处于 PHPDoc 规范化流水线的中后段。
测试验证:官方承诺的行为边界
测试类 PhpdocSingleLineVarSpacingFixerTest.php 中的每个用例都属于官方向后兼容承诺(backward compatibility promise)的一部分。从数据提供器provideFixCases()可以归纳出规则的实际行为边界:
用例 1:缺失空格的两种情况
/**@var MyCass6 $a */ → /** @var MyCass6 $a */ /**@var MyCass6*/ → /** @var MyCass6 *//**后缺空格、*/前缺空格都会被补齐,类型名被保留。
用例 2:类型、变量、描述之间的多余空白
/** @var MyCass1 $test1 description and more.*/ → /** @var MyCass1 $test1 description and more. */ /** @var MyCass3 description. */ → /** @var MyCass3 description. */- 注释内部(含 Tab 与多个空格混用)的空白被统一为单个空格;
- 描述文本内部的单词间距不会被打散——
description and more.中"and"前的多余空格会被压成单个空格,但描述内单词间的正常分隔保留; - 变量名可省略:
/** @var MyCass2 description and such. */这种无$var的形态同样受支持。
用例 3:不越界的场景(单输入无输出)
第三个用例只有expected没有input,表示该输入不做任何修改,包括:
- 多行
@param array $options { ... }块内缩进的@var bool $required ...行(属于@param的嵌套结构,不被触碰); - 多行
@var注释块中逐行书写的@var bool $required ...与@var string $label ...; - 以
/** @var MyCass3开头但*/换行到下一行的多行注释。
这正是"单行"限定词的含义:只要注释不是单行/** ... */形态,本规则一律不动,从而避免误伤多行 PHPDoc 块与对齐排版结构。该用例同时暗示:垂直对齐任务交由phpdoc_align处理,本规则无需也不应代劳。
所属规则集与如何启用
规则文档明确该规则属于以下两个规则集(规则集文档 Symfony.rst):
@PhpCsFixer(见 PhpCsFixer.rst)@Symfony(见 Symfony.rst)
在源码层面,@Symfony规则集在 SymfonySet.php 中显式声明'phpdoc_single_line_var_spacing' => true;而@PhpCsFixer规则集通过'@Symfony' => true继承启用(见 PhpCsFixerSet.php)。因此,只要你的配置使用了这两个规则集之一,该规则就会默认生效,无需额外声明。
在命令行中单独运行
不依赖规则集,针对单个文件单独验证该规则:
# 仅运行此规则并输出修复结果 php php-cs-fixer fix path/to/File.php --rules=phpdoc_single_line_var_spacing # 只查看差异,不实际修改文件 php php-cs-fixer fix path/to/File.php --rules=phpdoc_single_line_var_spacing --dry-run --diff--dry-run与--diff组合可以安全预览该规则会改动的每一处注释,适合先评估影响面再决定是否落地。
在配置文件中启用
在项目根目录的.php-cs-fixer.php配置文件中显式开启:
<?php return (new PhpCsFixer\Config()) ->setRules([ 'phpdoc_single_line_var_spacing' => true, ]) ->setFinder( PhpCsFixer\Finder::create() ->in(__DIR__.'/src') );由于该规则默认已随@Symfony/@PhpCsFixer启用,上述显式声明通常用于只开启少量规则的轻量配置,或用于自定义规则集时精确控制。
使用建议与注意事项
- 聚焦单行,配合 phpdoc_align 使用:如果项目中同时存在多行
@var块并希望对齐,应同时启用phpdoc_align,其优先级机制(本规则先于phpdoc_align执行)能保证间距归一后再对齐,结果稳定; - 该规则无配置项:与可配置规则不同,
phpdoc_single_line_var_spacing是确定性行为、不接受参数,开与不开只有两种状态,配置成本为零; - 向后兼容承诺:官方测试用例定义了受支持的行为,升级 PHP-CS-Fixer 版本时,这些用例所覆盖的场景不会发生破坏性变化(见 规则文档),可放心纳入 CI 流程。
小结
phpdoc_single_line_var_spacing是一条小而精准的 PHPDoc 规则:它以一条锚定单行@var的正则为核心,将注释内部的多余水平空白统一为单空格,同时严格不越界处理多行注释与其他标签;它位于 PHPDoc 处理流水线的中后段,先于phpdoc_align执行,并随@Symfony与@PhpCsFixer规则集默认启用。理解它的正则形态与优先级约束,有助于你在排查 PHPDoc 相关修复差异时快速定位问题来源。
- 开发工具
- 代码质量
- 静态分析
- Lint
- 格式化
【免费下载链接】PHP-CS-Fixer
A tool to automatically fix PHP Coding Standards issues
相关推荐
PHP-CS-Fixer `@DoctrineAnnotation` 规则集详解:一键规范 Doctrine 注解格式
PHP CS Fixer @DoctrineAnnotation 规则集详解:一键规范 Doctrine 注解格式 @DoctrineAnnotation 是
开发工具代码质量静态分析Lint格式化鸣潮智能辅助工具:游戏自动化新纪元
鸣潮智能辅助工具:游戏自动化新纪元 在当今快节奏的游戏环境中,玩家们常常需要在《鸣潮》这类开放世界游戏中投入大量时间来完成重复性任务。从日常委托到声骸刷取,从资
开发工具代码质量静态分析Lint格式化PHP-CS-Fixer 规则详解:`backtick_to_shell_exec` 反引号命令统一为 `shell_exec` 调用
PHP CS Fixer 规则详解: backtick_to_shell_exec 反引号命令统一为 shell_exec 调用 本文围绕 PHP CS Fix
开发工具代码质量静态分析Lint格式化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考