- 开发工具
- 代码质量
- 静态分析
- Lint
- 格式化
【免费下载链接】PHP-CS-Fixer
A tool to automatically fix PHP Coding Standards issues
object_operator_without_whitespace是 PHP-CS-Fixer 中一条用于统一对象运算符书写格式的规则:它确保对象运算符->(以及 PHP 8.0 引入的空安全运算符?->)前后不出现空白字符。本文以官方文档 doc/rules/operator/object_operator_without_whitespace.rst 为核心,结合 ObjectOperatorWithoutWhitespaceFixer 源码与 测试用例,讲解规则行为、修复边界、所属规则集以及实际使用方式,帮助你理解并正确地在项目中启用这条规则。
规则概述
该规则的核心约束用一句话概括:
There should not be space before or after object operators
->and?->.
即:对象运算符->与?->前后不应存在空格。规则官方定义位于 FixerDefinition,其代码示例为:
<?php $a -> b;修复后变为:
<?php $a->b;该规则属于operator(运算符)类目,对应的修复器类为PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer,归属于命名空间PhpCsFixer\Fixer\Operator。
修复行为与源码实现
从源码结构看,该修复器继承自AbstractFixer,实现非常轻量,核心逻辑全部集中在applyFix()方法中(src/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixer.php):
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { // [Structure] there should not be space before or after "->" or "?->" foreach ($tokens as $index => $token) { if (!$token->isObjectOperator()) { continue; } // clear whitespace before -> if ($tokens[$index - 1]->isWhitespace(" \t") && !$tokens[$index - 2]->isComment()) { $tokens->clearAt($index - 1); } // clear whitespace after -> if ($tokens[$index + 1]->isWhitespace(" \t") && !$tokens[$index + 2]->isComment()) { $tokens->clearAt($index + 1); } } }其工作流程可以拆解为三个步骤:
候选判定(isCandidate):
isCandidate()通过Token::getObjectOperatorKinds()检查代码中是否出现对象运算符 token(src/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixer.php)。getObjectOperatorKinds()在 src/Tokenizer/Token.php 中定义,返回两种 token:T_OBJECT_OPERATOR:普通对象运算符->;FCT::T_NULLSAFE_OBJECT_OPERATOR:空安全对象运算符?->。该 token 在 src/Tokenizer/FCT.php 中定义,当 PHP 版本 >= 8.0 时映射为原生T_NULLSAFE_OBJECT_OPERATOR,否则使用自定义占位值-803,以保证解析器在低版本环境下也能识别。
如果代码中完全没有对象运算符,修复器会直接跳过,不影响性能。
遍历 token 流:对
Tokens集合逐 token 遍历,每当遇到isObjectOperator()返回 true 的 token(即->或?->),就检查其前后相邻 token。清除空白:
- 运算符前:若
$tokens[$index - 1]是仅由空格()或制表符(\t)组成的空白 token,并且$tokens[$index - 2]不是注释,则清除该空白; - 运算符后:若
$tokens[$index + 1]是空格/制表符空白 token,且$tokens[$index + 2]不是注释,则清除该空白。
- 运算符前:若
isWhitespace(" \t")意味着该方法只处理空格和水平制表符,因此换行符、回车符等垂直空白不会被移除,这为多行链式调用保留了换行格式。
关键边界:注释保护
源码中两处都带有!$tokens[$index - 2]->isComment()/!$tokens[$index + 2]->isComment()的条件判断。这意味着:
- 如果运算符前/后的空白紧邻注释,则保留该空白,避免修复器破坏注释与代码之间的分隔关系;
- 典型场景是"运算符后的行尾注释",例如
$a->method(); // comment的写法中,运算符后方的空白不会被误删。
该边界行为在测试用例中得到验证:
'<?php $this ->add() // Some comment ->delete();',(见 tests/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixerTest.php),带注释的多行链式调用不会被破坏。
典型修复示例
官方文档给出一个 diff 示例(Example #1):
--- Original +++ New -<?php $a -> b; +<?php $a->b;测试类 ObjectOperatorWithoutWhitespaceFixerTest 通过provideFixCases数据提供器进一步覆盖了更丰富的场景(tests/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixerTest.php):
| 输入(Original) | 输出(New) | 说明 |
|---|---|---|
<?php $object ->method(); | <?php $object->method(); | 运算符前多空格 |
<?php $object -> method(); | <?php $object->method(); | 运算符前后均多空格 |
<?php $object-> method(); | <?php $object->method(); | 运算符后多空格 |
<?php $object\t->method(); | <?php $object->method(); | 制表符(tab)也被清除 |
<?php $object->\tmethod(); | <?php $object->method(); | 运算符后制表符被清除 |
<?php $object\t->\tmethod(); | <?php $object->method(); | 制表符组合场景 |
以上用例说明该规则不仅处理普通空格,同时处理制表符(\t)。
PHP 8.0 空安全运算符支持
对于 PHP 8.0 引入的空安全运算符?->,测试类通过#[RequiresPhp('>= 8.0.0')]标注的provideFix80Cases数据提供器覆盖(tests/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixerTest.php):
| 输入(Original) | 输出(New) |
|---|---|
<?php $object?-> method(); | <?php $object?->method(); |
<?php $object ?-> method(); | <?php $object?->method(); |
即?->与->的修复策略完全一致。
不会误伤的边界场景
字符串字面量:
<?php echo "use it as -> you want";中字符串内部的->不会受影响——因为修复器基于 token 流而非文本替换,字符串属于T_CONSTANT_ENCAPSED_STRINGtoken,不会被当作对象运算符处理(测试见 tests/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixerTest.php)。多行链式调用:换行符不属于
" \t"集合,因此以下风格会被完整保留(tests/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixerTest.php):
<?php $object->method() ->method2() ->method3();- 注释相邻空白:如前文所述,紧邻注释的空白不会被清除,保证
// Some comment这类注释在链式调用中不被破坏。
所属规则集
根据官方文档,该规则是以下两个规则集的一部分:
@PhpCsFixer(doc/ruleSets/PhpCsFixer.rst)@Symfony(doc/ruleSets/Symfony.rst)
在源码中,@Symfony规则集于 src/RuleSet/Sets/SymfonySet.php 显式启用了该规则:
'object_operator_without_whitespace' => true,而@PhpCsFixer规则集通过继承@Symfony自动包含该规则——其定义在 src/RuleSet/Sets/PhpCsFixerSet.php 中设置了'@Symfony' => true,并在文档中描述为"基于@PER-CS与@Symfony的高度主观化推荐规则集"(src/RuleSet/Sets/PhpCsFixerSet.php)。
因此,如果你的项目已经采用@Symfony或@PhpCsFixer风格,本规则会自动生效,无需额外配置。
如何启用与使用
1. 通过规则集启用(推荐)
在.php-cs-fixer.php配置文件中使用规则集:
<?php $finder = PhpCsFixer\Finder::create() ->in(__DIR__) ; return (new PhpCsFixer\Config()) ->setRules([ '@Symfony' => true, ]) ->setFinder($finder) ;由于@Symfony已包含object_operator_without_whitespace,上述配置即可让规则生效。
2. 单独启用该规则
若项目不使用上述规则集,也可以单独启用:
return (new PhpCsFixer\Config()) ->setRules([ 'object_operator_without_whitespace' => true, ]) ->setFinder($finder) ;3. 命令行检查
启用后,可通过命令行验证效果(dry-run 只报告不修改):
php php-cs-fixer fix --dry-run --diff输出中会以 diff 形式展示->与?->两侧多余空白被移除的具体改动;确认无误后去掉--dry-run即可实际修复文件。
与其他相关规则的配合
从 doc/rules/operator/index.rst 可知,operator类目下还有其他与空白相关的运算符规则,例如binary_operator_spaces(二元运算符两侧空白)、concat_space(字符串连接符两侧空白)等。object_operator_without_whitespace只关注对象运算符->/?->,与它们互不冲突,共同保证运算符书写的统一风格。
兼容性说明
- 最低 PHP 版本要求:修复器本体不依赖 PHP 8 特性,
?->的识别通过FCT::T_NULLSAFE_OBJECT_OPERATOR的兼容映射实现(PHP < 8.0 时使用占位 token 值-803),因此工具在低版本 PHP 环境下也能解析含?->语法的代码; - 测试覆盖:空安全运算符相关用例标注
@requires PHP >= 8.0.0,仅在 PHP 8.0+ 环境中运行; - 向后兼容承诺:官方文档明确指出,测试类 中定义的每个测试用例都属于向后兼容承诺的一部分——即该规则对已覆盖输入的处理行为在未来版本中不会发生破坏性变化。
小结
object_operator_without_whitespace是一条简单但实用的代码风格规则:
- 强制
->与?->前后无空格/制表符; - 基于 token 级别的精确处理,不会误伤字符串中的
->; - 保留多行链式调用换行,并保护与注释相邻的空白;
- 内置于
@Symfony与@PhpCsFixer两大主流规则集,开箱即用; - 实现代码位于 src/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixer.php,测试证据位于 tests/Fixer/Operator/ObjectOperatorWithoutWhitespaceFixerTest.php,可供深入研读。
对于追求代码风格一致性的团队,直接启用该规则即可消除对象运算符两侧的空白不一致问题,且无需任何参数配置。
- 开发工具
- 代码质量
- 静态分析
- Lint
- 格式化
【免费下载链接】PHP-CS-Fixer
A tool to automatically fix PHP Coding Standards issues
相关推荐
PHP-CS-Fixer concat_space 规则详解:字符串拼接运算符空格规范化与配置实战
PHP CS Fixer concat_space 规则详解:字符串拼接运算符空格规范化与配置实战 导读 concat_space 是 PHP CS Fixer
开发工具代码质量静态分析Lint格式化PHP CS Fixer 规则解析:not_operator_with_space —— 为逻辑非运算符 `!` 统一加上前后空白
PHP CS Fixer 规则解析:not_operator_with_space —— 为逻辑非运算符 ! 统一加上前后空白 本篇文章聚焦 PHP CS Fi
开发工具代码质量静态分析Lint格式化SadTalker 本地部署完整指南:三条命令让静态肖像开口说话
SadTalker 本地部署完整指南:三条命令让静态肖像开口说话 你手里有一张正面人像照和一段 30 秒的解说音频,想让照片里的人"说"出这段话——CVPR 2
开发工具代码质量静态分析Lint格式化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考