PHP-CS-Fixer `new_with_braces` 规则完全解析:`new` 关键字后括号强制与弃用迁移指南 开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载new_with_braces是 PHP-CS-Fixer 中专门统一new关键字实例化语法的规则它强制或禁止命名类与匿名类在new之后携带括号。本指南以 doc/rules/operator/new_with_braces.rst 为骨架结合 NewWithBracesFixer.php、NewWithParenthesesFixer.php 及对应测试用例完整讲解两个配置项、三个典型配置场景、底层 Token 处理原理以及该规则已弃用、如何平滑迁移到new_with_parentheses的实操路径。读完你将能准确配置该规则、理解其边界行为并避免在升级到 4.0 时踩坑。规则定位让new实例化的书写风格完全统一在 PHP 中new Foo与new Foo()都是合法的实例化写法匿名类也可以写成new class {}或new class() {}。这种书写差异在团队协作与代码审查中容易引发无谓争论。PHP-CS-Fixer 通过new_with_braces规则提供一种强制手段所有用new关键字创建实例的地方必须或不必须紧跟一对括号具体行为由两个布尔选项控制。从源码看该规则的定位非常明确。在 NewWithParenthesesFixer.php 中规则的 FixerDefinition 被定义为All instances created with new keyword must (not) be followed by parentheses.注意这里的措辞是 must(not)be followed by parentheses——括号要么必须加要么必须不加取决于配置而不是推荐某一种风格。重要警告规则已弃用请迁移到new_with_parentheses在开始使用之前必须明确一个关键事实原文档在 Warnings 一节中专门标注This rule is DEPRECATED and will be removed in the next major version 4.0. You should usenew_with_parenthesesinstead.也就是说new_with_braces是旧版命名将在 4.0 主版本中被移除官方推荐使用新规则名new_with_parentheses。新规则的功能、配置项与行为完全一致仅仅是更名。这一点在源码层面有直接证据NewWithBracesFixer同时实现了ConfigurableFixerInterface与DeprecatedFixerInterface并且本质是一个代理 FixerProxy Fixer——它继承自AbstractProxyFixer内部直接实例化并委托给NewWithParenthesesFixer完成全部工作见 NewWithBracesFixer.phppublic function __construct() { $this-newWithParenthesesFixer new NewWithParenthesesFixer(); parent::__construct(); }同时它通过getSuccessorsNames()声明了继承者public function getSuccessorsNames(): array { return [ $this-newWithParenthesesFixer-getName(), ]; }这在 PHP-CS-Fixer 中意味着工具在检测到废弃规则时会提示用户改用new_with_parentheses迁移成本极低——只需把配置中的规则名替换即可配置值完全复用。关于新规则的完整文档见 new_with_parentheses.rst。配置参数详解new_with_braces及new_with_parentheses是一个可配置规则CONFIGURABLE共有两个布尔选项来自 NewWithParenthesesFixer.php 的createConfigurationDefinition()anonymous_class含义匿名类是否应该紧跟一对括号即new class() {}还是new class {}。允许类型bool默认值true当前版本默认值future-modefalse值得留意的是anonymous_class的默认值在未来模式下会变为false。其底层实现使用了Future::getV4OrV3(false, true)见 Future.php当设置了环境变量PHP_CS_FIXER_FUTURE_MODE时返回false否则返回true。这意味着项目已经在为 4.0 版本中匿名类默认不带括号的新默认值做准备。named_class含义命名类普通具名类是否应该紧跟一对括号即new Foo()还是new Foo。允许类型bool默认值true当前版本与 future-mode 均为true源码中直接-setDefault(true)未使用未来模式切换两个选项相互独立可以单独配置。例如只关闭匿名类括号、保留命名类括号反之亦然。配置示例与运行效果原文档给出了三个可运行的配置场景均为 diff 输出格式-为原始代码为修复后代码这里完整继承并补充说明。示例 1默认配置两个选项均为 true--- Original New ?php -$x new X; -$y new class {}; $x new X(); $y new class() {};默认配置下命名类和匿名类都会被强制补上括号。示例 2配置[anonymous_class false]--- Original New ?php -$y new class() {}; $y new class {};只关闭匿名类括号命名类行为不受影响仍加括号。示例 3配置[named_class false]--- Original New ?php -$x new X(); $x new X;只关闭命名类括号匿名类仍加括号。在.php-cs-fixer.dist.php中的配置方式两种规则名均可推荐使用新名?php $finder PhpCsFixer\Finder::create()-in(__DIR__); return (new PhpCsFixer\Config()) -setRules([ new_with_parentheses [ anonymous_class false, named_class true, ], ]) -setFinder($finder) ;命令行直接运行php php-cs-fixer fix path/to/file.php --rules{new_with_parentheses: {anonymous_class: false}}。在官方规则集中的默认配置new_with_braces本身已弃用因此当前官方规则集引用的是新名new_with_parentheses。结合 new_with_parentheses.rst 的 Rule sets 一节不同规则集给出的预设不同直接决定了你在使用Symfony、PSR12等规则集时的实际行为规则集anonymous_class配置说明PSR12truePSR-12 规范要求匿名类带括号见 PSR12Set.phpPER-CS/PER-CS2.0/PER-CS3.0false新 PER-CS 风格趋向匿名类不带括号见 PERCS2x0Set.phpPER-CS1.0true早期 PER 版本仍要求带括号PhpCsFixerfalse项目自身风格SymfonyfalseSymfony 编码风格PER已弃用false旧规则集例如 PSR-12 在 PSR12Set.php 中对匿名类专门注释 defined in PSR12 ¶8. Anonymous Classes说明这一约定来自 PSR-12 规范的匿名类章节。如果你的项目基于PSR12匿名类会被强制写成new class() {}而基于PER-CS或Symfony则会被强制写成new class {}——这正是必须或不必须带括号这一措辞的由来。相关规则集文档见 doc/ruleSets/PSR12.rst、doc/ruleSets/PER-CS.rst。底层实现原理Tokenizer 驱动的括号增删理解该规则为什么能正确处理各种复杂语法需要看NewWithParenthesesFixer的实现。它继承自AbstractFixer通过 PHP-CS-Fixer 的 Tokenizer 组件src/Tokenizer按 Token 流处理代码而不是做正则替换。候选检测与优先级public function isCandidate(Tokens $tokens): bool { return $tokens-isTokenKindFound(\T_NEW); }文件内容中只要存在T_NEWToken 才会进入修复流程否则直接跳过保证性能。规则的优先级为38注释明确要求 Must run before ClassDefinitionFixer, NewExpressionParenthesesFixer见 NewWithParenthesesFixer.php保证与类定义、new表达式括号相关规则协同时不冲突。核心修复流程applyFix()从后往前遍历所有T_NEWTokenNewWithParenthesesFixer.php对每个new分两种情况处理匿名类下一个有意义的 Token 是T_CLASS根据anonymous_class配置调用ensureParenthesesAt()或ensureNoParenthesesAt()命名类如果后面紧跟[数组下标语法如new $foo[0]、new $b[class]会先借助findBlockEnd()跳过整个下标块再定位到真正的表达式结束位置然后按named_class配置增删括号。关键的NEXT_TOKEN_KINDS常量NewWithParenthesesFixer.php定义了new之后可能出现的各种后续 Token 种类运算符 - * / % | ^、比较符 ! ! 、逻辑符and or xor ||、instanceof、as、、幂运算**、太空船、?关闭标签等。这些正是如何确定new X表达式在何处结束的边界判断依据。括号删除的安全保护ensureNoParenthesesAt()去掉括号时包含两个至关重要的保护逻辑构造器有参数时不删除如果(后面不是紧跟)说明构造器有实参括号必须保留new A()-method()场景不删除源码专门注释 Preserve parentheses in expressions likenew A()-method()as per RFC。括号后紧跟对象运算符-时删除括号会改变语义new A-method()不合法因此必须保留。同理ensureParenthesesAt()补括号时会先判断当前位置是否已经是(或对象运算符避免重复插入。测试覆盖与向后兼容承诺该规则的行为可靠性由大量测试用例背书。原文档明确指出The test class defines officially supported behaviour. Each test case is a part of our backward compatibility promise.测试类定义了官方支持的行为每个用例都是向后兼容承诺的一部分。NewWithBracesFixerTest.php 覆盖了四组主要场景provideFixNamedWithDefaultConfigurationCases默认配置下命名类的修复涵盖new self、new static、new $foo[0]-bar()、链式new X(new Y(new Z))、instanceof比较、各种运算表达式、new \Exception?关闭标签场景等provideFixNamedWithoutBracesCasesnamed_class false时反向移除括号provideFixAnonymousWithDefaultConfigurationCases/provideFixAnonymousWithoutBracesCases匿名类带implements、extends、use SomeTrait、多级继承等复杂定义下的括号增删按 PHP 版本分组的用例provideFixPre80CasesPHP 8.0 的new $b{$c}花括号下标语法、provideFix80CasesPHP 8.0 的new (foo())动态类表达式、new #[Internal] class{}属性语法、provideFix81CasesPHP 8.1 新特性new表达式用于参数默认值、属性默认值、静态变量、常量const C new Foo()等new in initializers场景。例如 PHP 8.1 测试用例展示了该规则对现代语法的支持// 修复前 function test( $foo new A, $baz new C(x: 2), ) {} // 修复后 function test( $foo new A(), $baz new C(x: 2), ) {}这些用例从侧面印证了规则实现并非简单字符串替换而是真正理解 PHP 语法结构含 PHP 8 新语法这也是它能够在大型现代 PHP 代码库中安全运行的根本原因。迁移清单从new_with_braces升级到new_with_parentheses综合以上内容给出从旧规则迁移到新规则的实操清单替换规则名在.php-cs-fixer.dist.php的setRules()中把new_with_braces改为new_with_parentheses配置值anonymous_class、named_class原样保留验证规则集如果你的配置通过Symfony、PSR12、PER-CS等规则集间接启用该规则无需改动——官方规则集已全部切换为新规则名关注 future-mode 默认值变化anonymous_class的默认值在PHP_CS_FIXER_FUTURE_MODE1下为false这正是 4.0 的新默认方向。如果你的项目当前依赖匿名类默认带括号建议显式写出anonymous_class true而不是依赖默认值避免升级后行为漂移跑一次测试验证切换规则名后运行php php-cs-fixer fix --dry-run --diff检查修复结果与升级前一致。new_with_braces及其后继者new_with_parentheses通过极简的两个布尔配置把 PHP 中new语法的书写风格争议转化为可自动执行、可被测试用例保障的确定性行为是 PHP-CS-Fixer 规则体系中小规则、大边界处理的典型代表。赞分享开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载相关推荐PHP-CS-Fixer new_with_parentheses 规则完全指南统一 new 关键字后的括号风格PHP CS Fixer new_with_parentheses 规则完全指南统一 new 关键字后的括号风格 本指南深入解析 PHP CS Fixer 的开发工具代码质量静态分析Lint格式化PHP-CS-Fixer 的 no_spaces_inside_parenthesis 规则清理括号内空白与弃用迁移指南PHP CS Fixer 的 no_spaces_inside_parenthesis 规则清理括号内空白与弃用迁移指南 本指南围绕 PHP CS Fixer开发工具代码质量静态分析Lint格式化PHP-CS-Fixer PHP83Migration 规则集完全指南PHP 8.3 兼容性迁移与弃用迁移方案PHP CS Fixer PHP83Migration 规则集完全指南PHP 8.3 兼容性迁移与弃用迁移方案 导读 PHP83Migration 是 P开发工具代码质量静态分析Lint格式化上一篇Starship No Empty Icons 预置方案全解只在能确定工具集信息时才显示模块图标下一篇Imposm3扩展开发添加自定义数据处理器和过滤器的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考