PHP-CS-Fixer 的 array_syntax 规则:统一 PHP 数组声明的 long/short 语法
2026/9/23 8:12:14 网站建设 项目流程

PHP-CS-Fixer 的 array_syntax 规则:统一 PHP 数组声明的 long/short 语法

【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer

array_syntax是 PHP-CS-Fixer 中用于统一 PHP 数组声明语法的核心规则,它可以在array(...)(long 语法)与[...](short 语法)之间按配置自动转换。本文以该规则的官方文档为基础,结合仓库中的 ArraySyntaxFixer 源码 与其 官方测试用例,完整讲解配置参数、运行效果、底层 token 级实现原理、优先级协作方式及所属规则集,帮助你在项目落地统一的数组书写风格。

规则概述

该规则的官方定义只有一句话:"PHP arrays should be declared using the configured syntax."(PHP 数组应使用所配置的语法来声明)。换句话说,它不关心你的项目到底该用array()还是[],而是保证全仓库只存在一种被选定的写法,从而消除同一代码库内两种语法混用带来的风格不一致。

该规则属于可配置(CONFIGURABLE)规则,唯一的配置项是syntax,因此你可以在不同项目、不同目录下定制各自的数组书写风格。

配置参数:syntax

配置项说明允许值默认值
syntax使用 long 还是 short 数组语法'long''short''short'
  • 'short':将array(1,2)转换为[1,2],这是默认行为,也符合现代 PHP(5.4+)的主流编码风格。
  • 'long':将[1,2]转换回array(1,2),适合需要兼容旧代码风格或团队规范强制 long 语法的场景。

从源码看,配置解析位于 ArraySyntaxFixer.php 的createConfigurationDefinition()中,通过FixerOptionBuilder构建:

protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { return new FixerConfigurationResolver([ (new FixerOptionBuilder('syntax', 'Whether to use the `long` or `short` array syntax.')) ->setAllowedValues(['long', 'short']) ->setDefault('short') ->getOption(), ]); }

setAllowedValues(['long', 'short'])意味着传入其他任何值都会触发配置校验错误;而setDefault('short')说明即使你只写'array_syntax' => true而不提供选项,也会按 short 语法处理。测试 testInvalidConfiguration 还验证了:传入不存在的选项(如['a' => 1])会抛出InvalidFixerConfigurationException,并提示"Defined options are: 'syntax'"。

运行效果示例

官方文档给出了两个 diff 形式的示例。

示例 1:默认配置(syntax未设置,即'short'

--- Original +++ New <?php -array(1,2); +[1,2];

示例 2:配置为['syntax' => 'long']

--- Original +++ New <?php -[1,2]; +array(1,2);

在配置文件中启用

推荐通过项目根目录的.php-cs-fixer.php配置文件声明规则(若需要全局默认值,可在.php-cs-fixer.dist.php中设置):

<?php return (new PhpCsFixer\Config()) ->setRules([ // 使用默认的 short 语法:把 array(...) 统一转为 [...] 'array_syntax' => true, // 或者显式指定为 long 语法 'array_syntax' => ['syntax' => 'long'], ]) ->setFinder( (new PhpCsFixer\Finder()) ->in(__DIR__.'/src') );

配置完成后即可执行php php-cs-fixer fix(或vendor/bin/php-cs-fixer fix)让规则生效;若只想预览改动而不写入文件,可加上--dry-run --diff参数查看 diff。

源码实现原理:token 级的双向转换

array_syntax的修复逻辑完全构建在 PHP-CS-Fixer 的 Tokenizer 之上,核心代码在 ArraySyntaxFixer.php。

候选 token 的确定。规则根据配置提前决定"要寻找哪种语法的 token":

private function resolveCandidateTokenKind(): void { $this->candidateTokenKind = 'long' === $this->configuration['syntax'] ? CT::T_ARRAY_BRACKET_OPEN : \T_ARRAY; }
  • 目标是 short 语法时,寻找T_ARRAY(即array关键字);
  • 目标是 long 语法时,寻找CT::T_ARRAY_BRACKET_OPEN(即[,这里使用了自定义 token 类型 CT 来区分"数组左括号"与"下标访问左括号")。

short 方向(array(...)[...])。找到T_ARRAY后,向后定位(,再用findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS, $openIndex)找到匹配的),把这一对括号分别替换为[],最后清除array关键字 token:

$tokens[$openIndex] = new Token([CT::T_ARRAY_BRACKET_OPEN, '[']); $tokens[$closeIndex] = new Token([CT::T_ARRAY_BRACKET_CLOSE, ']']); $tokens->clearTokenAndMergeSurroundingWhitespace($index);

long 方向([...]array(...))。找到CT::T_ARRAY_BRACKET_OPEN后,用findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_BRACKET, $index)找到匹配的],将括号对替换为(),并在原位置插入array关键字 token:

$tokens[$index] = new Token('('); $tokens[$closeIndex] = new Token(')'); $tokens->insertAt($index, new Token([\T_ARRAY, 'array']));

批量扫描方式。applyFix()采用从后向前遍历 token 的循环(for ($index = $tokens->count() - 1; 0 <= $index; --$index)),自后向前处理可以避免插入/替换 token 导致索引偏移影响后续处理。修复会递归覆盖嵌套数组、三元表达式内的数组、函数参数等所有位置,例如[[[]]]可被完整地双向转换。

优先级:与相邻规则的协作顺序

array_syntax的优先级为37,在源码注释中明确声明:

Must run before BinaryOperatorSpacesFixer, NoWhitespaceInEmptyArrayFixer, SingleSpaceAfterConstructFixer, SingleSpaceAroundConstructFixer, TernaryOperatorSpacesFixer.

这意味着它必须先于上述空格/括号类规则执行,原因很直观:array( )[ ]在转换前后括号形态变化,而空白处理规则依赖最终的括号形态。仓库用集成测试固化了这种协作,例如 array_syntax,binary_operator_spaces.test 验证了输入$a = array ();array_syntax(short)与binary_operator_spaces(赋值号单空格)同时启用时输出为$a = [];。同类优先级测试还包括array_syntaxno_whitespace_in_empty_arraysingle_space_after_constructsingle_space_around_constructternary_operator_spaces的组合(见 tests/Fixtures/Integration/priority 目录)。

边界情况:什么不会被改写

并不是所有[]都会被当成数组声明。从官方测试用例(ArraySyntaxFixerTest.php)可以看出,即使配置为syntax => 'long',以下写法保持原样、不会被转换

  • 数组追加与下标访问:$x[] = 1;$x[ ] = 1;$x[2] = 1;$x["a"] = 1;
  • 函数返回值下标:$x = func()[$x];
  • 字符串下标:$x = "foo"[$x];
  • 字符串插值中的下标:$text = "foo ${aaa[123]} bar $bbb[0] baz";
  • foreach中的数组解构:foreach ($array as [$x, $y]) {}

原因在于这些[在 tokenizer 中并不是CT::T_ARRAY_BRACKET_OPEN类型的"数组声明左括号",规则通过候选 token 类型天然规避了误伤。

所属规则集

官方文档列出了该规则参与的全部规则集(分别位于 doc/ruleSets 目录):

规则集备注
@PER已废弃(deprecated)
@PER-CS
@PER-CS2.0已废弃
@PER-CS2x0
@PER-CS3.0已废弃
@PER-CS3x0
@PHP5x4Migration
@PHP7x0Migration
@PHP7x1Migration
@PHP7x3Migration
@PHP7x4Migration
@PHP8x0Migration
@PHP8x1Migration
@PHP8x2Migration
@PHP8x3Migration
@PHP8x4Migration
@PHP8x5Migration
@PHP54Migration 至 @PHP85Migration 系列旧命名,均已废弃
@PhpCsFixer
@Symfony

规则集层面的关键点:

  • 在 PERCS2x0Set.php 中,array_syntax => true@PER-CS2x0启用,意味着遵循 PER Coding Style 2.0 的项目会自动获得 short 数组语法约束;
  • 在 PHP5x4MigrationSet.php 中,array_syntax是迁移集唯一启用的规则——这正对应 PHP 5.4 引入[]short 数组语法的历史事实,迁移到 PHP 5.4+ 时该规则会自动把所有array()改为[]
  • 更高版本的 PHP 迁移集(如@PHP7x0Migration等)通过继承链(AbstractMajorMinorDeprecationSetDefinition)向下包含该规则,所以数组语法统一贯穿整个迁移规则集体系。

测试保障与向后兼容承诺

官方测试类 ArraySyntaxFixerTest.php 是该项目"向后兼容承诺"的一部分,官方文档明确说明:"The test class defines officially supported behaviour. Each test case is a part of our backward compatibility promise."(测试类定义了官方支持的行为,每个测试用例都是向后兼容承诺的一部分)。

测试通过provideFixCases()数据提供器覆盖了大量场景,包括:默认配置、显式long/short、空数组、带空格括号、字符串元素、三元表达式嵌套数组、函数调用实参、多层嵌套([[[]]])、函数默认参数(function(array $foo = []))、数组字面量直接下标([1, 2][0])以及前文所述的各类边界情况。这意味着只要你的代码处于这些被覆盖的形态,规则的行为就是有测试背书、可放心依赖的。

小结与使用建议

array_syntax是一个"小而关键"的规则:它只做一件事——统一数组声明语法,但通过 token 级实现、优先级设计与测试保障,做到了安全、可靠、可配置。实际项目落地时可以参考以下思路:

  1. 新项目:直接启用'array_syntax' => true(short 语法),或直接使用@PER-CS2x0/@Symfony等已包含该规则的规则集;
  2. 旧项目迁移:若代码量较大,建议先用--dry-run --diff预览全部改动,确认没有foreach解构、字符串插值等边界场景被误伤;
  3. 反向约束:若团队规范要求 long 语法(例如强兼容 PHP 5.3 的遗留系统),配置['syntax' => 'long']即可反向统一;
  4. 配合验证:修改规则后运行vendor/bin/php-cs-fixer fix --dry-run --diff,并结合仓库内的集成测试理解其与其他空格类规则的协作结果。

参考与深入阅读

  • 规则官方文档:doc/rules/array_notation/array_syntax.rst
  • 修复器实现:src/Fixer/ArrayNotation/ArraySyntaxFixer.php
  • 官方测试:tests/Fixer/ArrayNotation/ArraySyntaxFixerTest.php
  • 优先级集成测试:tests/Fixtures/Integration/priority 目录下array_syntax,*系列文件
  • 规则集定义:src/RuleSet/Sets/PERCS2x0Set.php、src/RuleSet/Sets/PHP5x4MigrationSet.php

【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询