首页/新闻资讯/正文详情

PHP-CS-Fixer 规则详解:general_attribute_remove 按 FQN 批量移除 PHP 属性

发布时间:2026/9/23 1:56:33 来源:云帆数科 栏目:资讯中心
PHP-CS-Fixer 规则详解:general_attribute_remove 按 FQN 批量移除 PHP 属性
开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载导读general_attribute_remove是 PHP-CS-Fixer 中归属于AttributeNotation属性记法分类的一类可配置Configurable规则其核心能力是按照属性的完全限定名FQNFully Qualified Name批量删除代码中不再需要的 PHP 8 属性Attribute。在项目迁移、框架升级、逐步淘汰旧注解体系的场景下开发者可以通过一行配置精准清除指定属性同时保留其余属性、命名空间别名use与注释原样不动。读完本文你将掌握该规则的配置参数、匹配语义含命名空间解析与别名校验、底层实现原理以及如何用命令行与规则集落地这一清理工作。规则概览定位与适用场景general_attribute_remove位于 doc/rules/attribute_notation/general_attribute_remove.rst其规则全名为general_attribute_remove对应的 Fixer 实现类是 src/Fixer/AttributeNotation/GeneralAttributeRemoveFixer.php。规则官方描述只有一句话Removes configured attributes by their respective FQN.按各自的完全限定名移除已配置的属性。它适用于以下典型场景框架/库升级旧版本框架的注解在新版本中被移除或改名需要从全量代码中删除旧属性声明注解体系迁移从一种属性体系切换到另一种例如从第三方属性迁移到 PHP 原生属性需要先批量删除旧属性代码清理删除调试、实验性或已废弃的内部标记属性保持源码整洁。该规则的一个关键特性是它只删除匹配的属性本身不会顺带删除对应的use导入语句。例如删除#[BarAlias]之后use A\B\Bar as BarAlias;依然保留可配合 no_unused_imports 规则再做一轮清理。配置参数attributesgeneral_attribute_remove是可配置规则Configurable通过attributes选项指定要删除的属性 FQN 列表。项目说明选项名attributes用途需要删除的属性 FQN 列表允许类型listclass-string字符串数组每个元素是一个类的完全限定名默认值[]空数组即默认不删除任何属性是否必填否配置项的底层定义见 GeneralAttributeRemoveFixer.php 中的createConfigurationDefinition()方法protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { return new FixerConfigurationResolver([ (new FixerOptionBuilder(attributes, List of FQNs of attributes for removal.)) -setAllowedTypes([class-string[]]) -setDefault([]) -getOption(), ]); }从源码可以看到类型约束为class-string[]即数组元素必须是类名字符串传其他类型会抛出配置校验异常默认值为空数组[]因此不配置该规则时它什么都不做必须显式给出attributes列表才有实际效果。FQN 的书写方式配置中的 FQN 支持两种写法行为有细微差别带前导反斜杠如\A\B\Foo表示全局命名空间下的绝对路径匹配时会与源码中#[\A\B\Foo]这种显式全局写法直接对应不带前导反斜杠如A\B\Bar同样按完全限定名语义解析与use别名解析后的目标类名比对。需要特别强调的是匹配依据是解析后的完全限定名而非源码中的书写形式。也就是说即使源码里写的是#[BarAlias]别名或#[AB\Baz]命名空间缩写只要它最终解析出的 FQN 命中配置列表就会被删除。这一点在下面的示例和原理部分会详细展开。官方示例从最小配置到别名场景示例 1删除单个全局 FQN 属性配置[attributes [\A\B\Foo]]--- Original New ?php -#[\A\B\Foo] function foo() {}源码中的#[\A\B\Foo]被整体删除函数声明不受影响。示例 2同时处理全局写法与 use 别名配置[attributes [\A\B\Foo, A\B\Bar]]--- Original New ?php use A\B\Bar as BarAlias; -#[\A\B\Foo] -#[BarAlias] function foo() {}这个示例揭示了两个要点#[\A\B\Foo]以显式全局写法出现直接命中配置第一项\A\B\Foo#[BarAlias]在源码中只是别名但BarAlias通过use A\B\Bar as BarAlias;解析出的 FQN 是A\B\Bar命中配置第二项A\B\Bar因此同样被删除use A\B\Bar as BarAlias;这行导入语句被保留——规则不会越界清理 use 语句。匹配语义详解命名空间解析与别名展开general_attribute_remove最值得深入理解的部分是如何判断源码中的属性等于配置中的 FQN。其核心逻辑在 src/Tokenizer/Analyzer/AttributeAnalyzer.php 的determineAttributeFullyQualifiedName()方法中实现处理流程如下显式全局写法如果属性名以\开头如\A\B\Foo直接返回该名称本身不做任何解析普通名称解析否则通过NamespacesAnalyzer收集当前代码所处命名空间及所有use导入分析结果NamespaceUseAnalysisuse 别名匹配取属性名的第一个段如BarAlias、AB在 use 映射表中查找若命中且属性名只有一段返回 use 导入的完整 FQN如BarAlias→A\B\Bar若命中且属性名有多段如AB\Baz则用 use 导入的命名空间前缀拼接剩余段如A\BBaz→A\B\Baz兜底拼接未命中任何 use 时返回当前命名空间 属性名。正是因为这种解析机制规则的匹配行为具有以下特征命名空间感知同一写法在不同命名空间下解析出的 FQN 不同。测试用例 Multiple namespaces见 tests/Fixer/AttributeNotation/GeneralAttributeRemoveFixerTest.php专门验证了多个命名空间块、全局命名空间混存时删除动作只作用于目标命名空间内的对应属性别名展开use别名与命名空间别名use A\B as AB;都能被正确解析注释与空白不影响匹配测试用例 With whitespaces同一测试文件与 With commentsL306-L334证明属性块内部的空格、换行、/* */注释都不会干扰 FQN 解析与删除。底层实现Fixer 的逐 Token 处理流程从源码结构看GeneralAttributeRemoveFixer继承自AbstractFixer并实现ConfigurableFixerInterface实际删除动作集中在applyFix()方法GeneralAttributeRemoveFixer.php其工作流程可分为四步第一步候选判定isCandidatepublic function isCandidate(Tokens $tokens): bool { return $tokens-isTokenKindFound(FCT::T_ATTRIBUTE); }仅当 token 流中出现属性标记#[时才运行没有任何属性的文件会直接跳过保证性能。第二步逐个属性块分析遍历所有T_ATTRIBUTEtoken调用AttributeAnalyzer::collectOne()收集该属性块的完整分析结果AttributeAnalysis起始索引、结束索引、属性列表其中collectAttributes()AttributeAnalyzer.php会精确切分出块内的每个属性元素及其名称、起止位置。第三步按 FQN 逐元素删除对块内的每个属性元素调用determineAttributeFullyQualifiedName()解析出 FQN与配置attributes列表做严格比较\in_array(..., true)区分大小写命中则用clearRange()清除该元素占用的 token 范围并记录删除计数若该元素后紧跟逗号说明不是块内最后一个元素连逗号一并清除避免留下悬空分隔符。第四步整体与残留清理如果块内所有属性都被删除count($attributeAnalysis-getAttributes()) $removedCount则直接清除整个属性块覆盖多行属性块的场景见测试用例 With multiple attributes 与 Multiline with no trailing comma如果只删除了部分属性则检查属性块关闭括号]前的最后一个有意义的 token若残留尾逗号则一并清除。通过命令行与配置使用该规则general_attribute_remove未包含在默认规则集如PSR12、Symfony中属于需要按需显式启用的规则。启用方式有两种方式一项目配置文件.php-cs-fixer.php在项目根目录的.php-cs-fixer.php中注册规则并给出attributes配置?php use PhpCsFixer\Config; return (new Config()) -setRules([ general_attribute_remove [ attributes [ \App\Attributes\DeprecatedMarker, App\Attributes\Experimental, ], ], ]) -setFinder( (new PhpCsFixer\Finder()) -in(__DIR__./src) );方式二命令行--rules直接指定根据 doc/usage.rst 的说明--rules选项允许直接覆盖默认规则集支持 JSON 格式传入带参数的规则配置php php-cs-fixer.phar fix . --rules{general_attribute_remove: {attributes: [\\App\\Attributes\\DeprecatedMarker, App\\Attributes\\Experimental]}}执行后工具会以 diff 形式输出将要删除的属性块确认无误后即可完成批量移除。注意JSON 字符串中的反斜杠需要转义因此\App\...要写成\\App\\...。官方测试向后兼容承诺的边界PHP-CS-Fixer 官方文档明确声明测试类定义了官方支持的行为每个测试用例都是向后兼容承诺backward compatibility promise的一部分。general_attribute_remove的测试集中在 tests/Fixer/AttributeNotation/GeneralAttributeRemoveFixerTest.php该测试类标注#[RequiresPhp( 8.0.0)]——属性Attribute语法自 PHP 8.0 引入因此本规则只在 PHP 8.0 环境下生效。测试覆盖的关键行为包括测试场景验证要点Explicit in namespace命名空间内别名、命名空间别名use A\B as AB、全局写法混合时的精确删除Explicit in global namespace全局命名空间下的解析与删除Multiple namespaces多命名空间块、全局命名空间下互不干扰的删除With whitespaces属性块内空格/换行不影响匹配With docblock删除属性时保留相邻的 PHPDoc 注释With comments属性块内的/* */注释不影响匹配With multiple attributes多行属性块内部分删除与整块删除Multiline with no trailing comma无尾逗号的多行属性块整块删除Multiple with comments多行属性块内嵌注释与 PHPDoc 的删除行为此外在 tests/Test/AbstractFixerTestCase.php 中general_attribute_remove被列入allowedFixersWithoutDefaultCodeSample——这是因为该规则必须显式配置attributes才有意义没有默认代码样例default code sample属于测试基础设施对该类规则的豁免项。注意事项与边界PHP 版本前提属性语法要求 PHP 8.0规则仅在 PHP 8.0 环境可用不清理 use 导入删除属性后遗留的无用use语句需要配合no_unused_imports等导入类规则处理FQN 大小写敏感比较使用严格模式\in_array(..., true)配置中的类名大小写需与解析结果完全一致默认不生效不配置attributes时规则为空操作属于必须配置才能工作的可配置规则非 risky 规则该规则没有risky描述删除操作基于确定的 FQN 匹配行为可预期。小结general_attribute_remove为 PHP 代码库提供了一种声明式的属性批量清理能力只需在配置中列出目标 FQNFixer 就能借助AttributeAnalyzer的命名空间解析机制准确识别并删除包括别名写法在内的目标属性同时妥善处理多行属性块、逗号残留与相邻注释。结合 AttributeAnalyzer.php 的源码与 GeneralAttributeRemoveFixerTest.php 的丰富用例开发者可以放心地将它纳入迁移与清理工作流并通过官方测试保障的行为边界预测每次变更的结果。赞分享开发工具代码质量静态分析Lint格式化【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer点击查看免费下载相关推荐PHP-CS-Fixer 规则详解no_null_property_initialization 移除属性多余的 null 初始化PHP CS Fixer 规则详解no_null_property_initialization 移除属性多余的 null 初始化 no_null_prope开发工具代码质量静态分析Lint格式化Feather框架革命性同步Rust Web框架告别async/await的复杂性Feather框架革命性同步Rust Web框架告别async/await的复杂性 Feather框架是一个革命性的同步Rust Web框架它通过创新的同开发工具代码质量静态分析Lint格式化PHP-CS-Fixer encoding 规则详解自动移除 PHP 文件中的 UTF-8 BOMPHP CS Fixer encoding 规则详解自动移除 PHP 文件中的 UTF 8 BOM 导读 encoding 是 PHP CS Fixer 中一开发工具代码质量静态分析Lint格式化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Spring Boot Admin 服务端 Hazelcast 集群:高可用事件存储与分布式通知实战
Spring Boot Admin 服务端 Hazelcast 集群:高可用事件存储与分布式通知实战

后端可观测性指标监控监控大盘MCP 服务 【免费下载链接】spring-boot-admin Admin UI for administration of spring boot applications 项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot-admin 点击查看 免费下载 导读 当 Spring Boot Admin Server 需要… · 2026/9/23 1:56:33

JavaWeb购物商城项目实战:MySQL表设计、JDBC连接池与下单事务解析
JavaWeb购物商城项目实战:MySQL表设计、JDBC连接池与下单事务解析

简介:一款面向 JavaWeb 初学者及课程设计/毕业设计需求的完整购物商城项目源码,基于 Java 与 MySQL 开发,核心采用 MVC 设计模式和动态代理模式。项目从前台购物到后台管理形成完整闭环:主页展示热销商品,支持商品搜索… · 2026/9/23 1:56:33

JavaWeb商城课设源码:DAO前缀规范+JDBC防注入+Tomcat部署避坑指南
JavaWeb商城课设源码:DAO前缀规范+JDBC防注入+Tomcat部署避坑指南

简介:本资源是一套完整的JavaWeb毕业设计项目——基于JSP与Servlet架构的电子商城系统源码及配套数据库,面向计算机专业本科生、Java初学者及课程设计实践者,解决电商类Web应用从需求分析到部署上线的全流程学习需求。压缩包共417个文件&… · 2026/9/23 1:56:27

文化对照实验室:周星驰《功夫》三语网站的搭建运营实录
文化对照实验室:周星驰《功夫》三语网站的搭建运营实录

1. 为什么是“周星星功夫”?一个三语网站的选题逻辑1.1 从《功夫》在东亚的真实影响力说起做这个项目的念头,最早是从一条评论开始的。当时我在一个影视社区里闲逛,看到有人发帖问:周星驰的《功夫》在日韩到底算不算经典&#xff… · 2026/9/23 13:53:57

中音谱号与次中音谱号:提升弦乐读谱效率的视觉坐标系统
中音谱号与次中音谱号:提升弦乐读谱效率的视觉坐标系统

1. 为什么中音谱号和次中音谱号不是“冷门配件”,而是乐谱设计的底层逻辑?你有没有在翻谱时突然卡住——明明是同一个音高,中提琴谱上写的是中央C,大提琴谱上却标在五线谱最下面那条线上?或者看到一首老乐谱里&#xf… · 2026/9/23 13:53:57

Excel 按列批量拆分成多个工作簿:三种方案实测对比
Excel 按列批量拆分成多个工作簿:三种方案实测对比

背景 把一张总表按某一列拆成多个工作簿,是办公场景里非常高频的需求:按部门拆发给负责人、按区域拆做分发、按门店拆做台账。但大多数方案都会在同一个地方翻车——格式没了。 本文把三种常见做法列出来,说清各自的适用边界。 方案一&#x… · 2026/9/23 13:53:49

C++安全编程实战:从内存安全到并发防御的完整指南
C++安全编程实战:从内存安全到并发防御的完整指南

1. 为什么要专门谈C安全编程C这门语言,从诞生到现在几十年了,性能确实能打,但它也是最容易“伤到自己”的语言之一。很多人在初学阶段被指针、内存管理、类型转换这些概念绕晕,等真正写起项目来,又发现各种莫名其妙的崩… · 2026/9/23 13:53:36

HarmonyOS TTS多实例冲突:从根源剖析到统一调度根治方案
HarmonyOS TTS多实例冲突:从根源剖析到统一调度根治方案

先说个我自己踩过的大坑。去年做一个资讯类App的语音播报功能,页面A朗读新闻到一半,用户切到页面B又触发了一次朗读,结果两个声音叠在一起,合成引擎像卡了痰一样忽快忽慢,最后直接把系统音频服务整崩了。排查半天&… · 2026/9/23 13:53:36

TopLevel与Topmost区别详解:窗口层级与置顶原理及常见坑
TopLevel与Topmost区别详解:窗口层级与置顶原理及常见坑

1. TopLevel是什么:窗口体系里的“根节点”与它的多重身份1.1 窗口层级里的“顶级”不是你以为的“置顶”先把一个最常被搞混的点说清楚:TopLevel说的不是一个窗口摆在最上面,而是说它在窗口管理器里属于“根级”窗口。很多刚接触桌面开发的朋… · 2026/9/23 13:53:30

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码