开发工具代码质量静态分析【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址https://gitcode.com/gh_mirrors/ph/phpstan点击查看免费下载导读new.internalEnum是 PHPStan 静态分析工具用于标识从包外部实例化被标记为internal的枚举这一违规行为的错误标识符。本文以 new.internalEnum.md 为核心骨架结合仓库内 errorsIdentifiers.json 中的标识符注册信息与 restricted-usage-extensions.md 中的扩展机制文档完整讲解该标识符的触发场景、报告原理、与new.enum的边界关系以及从实操到源码级的修复与规避策略。读完本文你将能准确识别这类内部 API 误用理解 PHPStan 为何及如何将其与普通枚举实例化区分开并掌握面向internal符号的规范开发与配置实践。一、什么是 new.internalEnum标识符语义与触发场景new.internalEnum的 shortDescription 为Referencing an internal enum in an instantiation context即在实例化上下文中引用内部枚举。它属于 PHPStan 错误标识符体系中的一员与new.internalClass、new.internalInterface、new.internalTrait构成new.*系列中针对internal符号的同类检测族。从 errorsIdentifiers.json 的注册信息可以看出该标识符由规则类PHPStan\Rules\InternalTag\RestrictedInternalClassNameUsageExtension产生其源码位置对应 phpstan-src 2.3.x 分支的src/Rules/InternalTag/RestrictedInternalClassNameUsageExtension.php。也就是说new.internalEnum并非独立手写的规则而是受限内部类名使用扩展在实例化这一具体位置上的产物——同一个扩展还会在其它使用位置上生成propertyTag.internalClass、class.implementsInternalClass等不同的标识符。触发代码示例原文档给出了最小复现示例?php declare(strict_types 1); namespace Vendor { /** internal */ enum CacheDriver { case Redis; case Memcached; } } namespace App { $driver new \Vendor\CacheDriver(); // error: Instantiation of internal enum Vendor\CacheDriver. }复现要点定义方Vendor命名空间内声明了一个带/** internal */注解的枚举CacheDriver包含Redis、Memcached两个 case使用方App命名空间中用new关键字试图实例化该枚举这一行即触发new.internalEnum报告跨包/跨命名空间使用位置处于枚举根命名空间之外这是内部 API 越界访问判断成立的前提。运行 PHPStan 后对应错误消息为Instantiation of internal enum Vendor\CacheDriver.。Frontmatter 元信息解读原文档 frontmatter 中ignorable: true与unlikely: true两个字段值得注意ignorable: true表示该标识符默认允许被忽略可在phpstan.neon的ignoreErrors中通过identifier定向忽略可结合 conf/bleedingEdge.neon 与配置参考文档了解忽略机制的运用unlikely: true则提示该错误在实际分析中不常见——正如后文将分析的因为枚举本身不可实例化通常更先命中new.enum。二、与 new.enum 的边界为什么实际更常见到 new.enum原文档明确指出实践中该错误通常以new.enumCannot instantiate enum的形式被报告因为枚举本身完全无法实例化。只有当内部访问违规是首要关注点时new.internalEnum才会被报告。对照 new.enum.md 文档enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; } $suit new Suit(); // error: Cannot instantiate enum Suit.new.enum描述的是 PHP 语言层面的硬性事实PHP 中的枚举不能通过new关键字实例化枚举 case 是预定义的单例必须通过 case 名直接访问如Suit::Hearts运行时对枚举使用new会导致致命错误。两者的分工可以这样理解标识符报告侧重点前提条件new.enum语言层面枚举不可实例化任何枚举被newnew.internalEnumAPI 边界层面internal枚举被包外实例化枚举被new且该枚举标记了internal同样的关系也存在于new.internalTrait与new.trait之间——new.internalTrait.md 明确说明触发该标识符需要实例化 trait而 PHP 不允许这样做因此 PHPStan 总是同时报告new.trait实践中new.internalTrait不会伴随出现。枚举场景的逻辑与之类似由于new.enum总会先命中new.internalEnum是次要且罕见的报告分支。这一点也解释了为什么其在 errorsIdentifiers.json 中仅对应一处源码位置、且 frontmatter 标记unlikely: true。三、为什么会被报告internal 契约与公共 API 边界原文档Why is it reported?部分的语义要点如下内部枚举正被用于实例化上下文使用方从枚举的根命名空间之外引用它internal意味着非公共 API被标记的枚举不属于定义该枚举的包package的公开 API只应在包内部使用稳定性风险内部实现细节可能在未来的任何版本中不经通知地变更或移除不遵循语义化版本控制semver。从 PHPStan 的规则设计看/** internal */是一种显式声明 API 边界的 PHPDoc 约定开发者通过它向工具与协作者表明这个符号不在契约之内。PHPStan 的RestrictedInternalClassNameUsageExtension族规则正是把这种约定变成可执行的静态检查——任何从包外部即 root namespace 之外对internal符号的使用都会被标记而new实例化只是其中的一种使用位置。这类报告的价值在于把编译期可见但契约上不可用的符号使用前置到 CI 阶段如果不小心直接使用了内部枚举升级依赖时可能因内部实现变更而静默出错而 PHPStan 能在合并代码前就把这种脆弱依赖暴露出来。四、如何修复从替换调用到请求公共 API原文档给出的标准修复路径是使用包提供的公共 API 替代直接引用内部枚举namespace App { - $driver new \Vendor\CacheDriver(); $driver \Vendor\CacheFactory::create(); }修复要点寻找定义该枚举的包对外暴露的工厂方法、服务入口或公开类本例为\Vendor\CacheFactory::create()如果包内不存在公共替代方案则应联系包维护者请求为所需功能提供公开 API——这正是internal契约的意图迫使使用者走受支持的路径。需要特别说明的是由于枚举本就无法实例化本例中的正确用法从纯语言层面讲应当是直接使用枚举 case如\Vendor\CacheDriver::Redis——但CacheDriver是internal的即使直接引用其 case 也属于内部 API 越界。因此这里正确的长期策略仍然是改用包提供的公共 API工厂方法返回的公开类型而不是绕过internal标记直接引用内部 case。这与new.internalClass文档new.internalClass.md中使用包内公共 API 而非直接实例化内部类若无公共替代则向维护者提交功能请求的修复逻辑完全一致。在实践中如何处理这类错误由于该错误ignorable: true若你的代码库确有合理原因临时引用内部符号例如作为第三方集成方必须使用未公开接口可以在phpstan.neon中按标识符定向忽略parameters: ignoreErrors: - identifier: new.internalEnum message: #Instantiation of internal enum Vendor\\CacheDriver# path: src/LegacyIntegration.php但需要注意忽略只应作为受控例外长期仍应推动依赖方向公共 API 迁移否则升级依赖时面临静默破坏的风险。五、源码级视角new.internalEnum 从何而来通过 errorsIdentifiers.json 可以精确回溯该标识符的生产链路规则类PHPStan\Rules\InternalTag\RestrictedInternalClassNameUsageExtension源码锚点phpstan-src 2.3.x 分支src/Rules/InternalTag/RestrictedInternalClassNameUsageExtension.php对应第 65 行附近的报告逻辑。结合 restricted-usage-extensions.md 对RestrictedClassNameUsageExtension机制的说明可以推断出完整链路该扩展针对独立类名引用场景被调用覆盖类继承、接口实现、参数与返回类型、PHPDoc 引用、静态方法调用、静态属性与类常量访问等25 个以上的使用位置。扩展实现通过ClassNameUsageLocation对象提供的createMessage()与createIdentifier()方法把统一的内部符号被外部引用信息按位置差异化Instantiation of internal class Foo.→new.internalClass同理Instantiation of internal enum Vendor\CacheDriver.→new.internalEnumClass Bar implements internal class Foo.→class.implementsInternalClass也就是说new.internalEnum是RestrictedInternalClassNameUsageExtension在实例化这一ClassNameUsageLocation上针对枚举类型getClassTypeDescription()返回enum自动生成的标识符与new.internalClass、new.internalInterface、new.internalTrait共享同一套底层报告机制只是按符号类型与使用位置区分为不同 identifier。这正是同一规则、多标识符设计在 PHPStan 错误标识符体系中的体现。六、同类标识符一览与扩展机制延伸internal检测并不只覆盖实例化位置。从 errorsIdentifiers.json 可以检索到同一 InternalTag 机制派生出的、针对枚举的兄弟标识符例如assert.internalEnum在断言上下文中引用内部枚举attribute.internalEnum在属性Attribute上下文中引用内部枚举catch.internalEnum在 catch 子句中引用内部枚举配合new.internalEnum构成同一符号多位置覆盖classConstant.internalEnum、instanceof.internalEnum、method.internalEnum、methodTag.internalEnum、mixin.internalEnum等。这些标识符共同说明PHPStan 对internal的检查是按使用位置全覆盖的而不是只在new时检查一次。如果你在代码库中看到形如xxx.internalEnum的其它标识符其含义与修复思路同本文完全一致——从包外部访问了内部枚举应改用公共 API。对于想要自定义内部使用限制的扩展开发者restricted-usage-extensions.md标识为 Available in PHPStan 2.1.13还提供了通用扩展接口RestrictedMethodUsageExtension、RestrictedPropertyUsageExtension、RestrictedClassConstantUsageExtension、RestrictedFunctionUsageExtension与RestrictedClassNameUsageExtension可通过注册phpstan.restrictedClassNameUsageExtension等 tag 挂载到配置中实现完全自定义的受限使用规则——这也是internal检查机制的可编程化延伸。七、总结识别、修复与防范维度结论触发条件在枚举根命名空间之外用new实例化带/** internal */的枚举错误消息Instantiation of internal enum Vendor\CacheDriver.与new.enum关系枚举本就不可实例化实际通常先报new.enum当内部访问违规是首要关注点时报告new.internalEnum根因internal符号不是包的公共 API可能随时变更或移除包外直接使用形成脆弱依赖标准修复改用包提供的公共 API如工厂方法无公共替代时向维护者请求公开 API受控例外ignorable: true可在phpstan.neon中按 identifier 定向忽略底层实现PHPStan\Rules\InternalTag\RestrictedInternalClassNameUsageExtension在实例化位置上按符号类型自动生成new.internalEnum虽然罕见unlikely: true却精确地揭示了 PHPStan 错误标识符体系的设计精髓同一套内部 API 边界检查按符号类型与使用位置拆分为细粒度、可忽略、可检索的标识符。理解它就等于理解了internal契约在现代 PHP 静态分析中的落地方式也能让你在依赖第三方包时养成只走公共 API的健壮习惯。赞分享开发工具代码质量静态分析【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址https://gitcode.com/gh_mirrors/ph/phpstan点击查看免费下载相关推荐PHPStan 错误标识符深度解析enum.implementsInternalEnum —— 枚举实现内部枚举internal的检测与修复PHPStan 错误标识符深度解析enum.implementsInternalEnum —— 枚举实现内部枚举internal的检测与修复 导读 en开发工具代码质量静态分析PHPStan 错误标识符 assert.internalEnum 详解phpstan-assert 引用 internal 枚举的检测与修复PHPStan 错误标识符 assert.internalEnum 详解 phpstan assert 引用 internal 枚举的检测与修复 asse开发工具代码质量静态分析PHPStan 错误标识符 enum.implementsDeprecatedEnum枚举实现已弃用枚举的检测原理与修复方案PHPStan 错误标识符 enum.implementsDeprecatedEnum枚举实现已弃用枚举的检测原理与修复方案 导读 enum.implemen开发工具代码质量静态分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
I2C总线从物理层到多主仲裁:开漏输出、上拉电阻与波形调试实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:09:25
电力监控网络安全态势感知架构设计与实战落地指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:09:25
《智能软件工程》全套PPT课件(同济大学) 《智能软件工程》全套PPT课件(同济大学)
课件内容:
Ch1-什么是软件工程-2025.pptx
Ch2-过去我们是如何开发软件的-2025.pptx
Ch3-如何获取用户的真实需求-N2025.pptx
Ch4-如何设计软件-2025.pptx
Ch5-如何高效地进行软件开发.pptx
Ch6-如何保… · 2026/9/24 10:50:48
设计行业招聘季:作品集、面试与职业成长避坑指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:50:41
Vivado 2023.1补丁安装全攻略:从下载到验证的实操指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:50:35
飞轮储能辅助火电机组一次调频:建模、控制与容量优化复现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:50:29
泰科纳气泡图软件:图纸更新,可以自动版本比对,不用重新标注! 产品研发阶段图纸迭代频繁,每一次图纸改版,质检团队都要重新标注气泡、重新整理检测项目。微小改动,也要整张图纸重新核对,大量重复工作,拖慢样品验证进度。很多气泡工具没有版本对比功能,图纸一改… · 2026/9/24 10:50:16
第九章 · 代理 — 明星不出面,经纪人全搞定 这一章,她学会了"代理":正主不露面,中间挡一层。起因,是她迷上了一个所有事都走经纪人的爱豆。晚上八点,沙发
“我跟你讲,我这个爱豆,微博从来不自己发,全是经纪人发的。”… · 2026/9/24 10:50:10
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44