开发工具代码质量静态分析【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址https://gitcode.com/gh_mirrors/ph/phpstan点击查看免费下载本篇指南围绕 PHPStan 错误标识符property.readOnly展开讲解其在当前开源仓库 PHPStanPHP Static Analysis Tool 中何时被触发、背后的 PHP 语言语义与里氏替换原则LSP冲突以及两种官方推荐的修复方案。读者读完本文后能够准确识别子类用readonly属性覆盖父类可读写属性的反模式掌握保持类型契约一致性的实战修正方法并理解property.readOnly与同族 readonly 错误标识符之间的区别。错误标识符速览property.readOnly是 PHPStan 错误标识符体系Error Identifier中的一员。它针对的是 PHP 类属性声明本身其文档位于 website/errors/property.readOnly.md该文档的 frontmatter 给出了该标识符的元数据--- title: property.readOnly shortDescription: Readonly property overrides a readwrite property from the parent class. ignorable: false ---title错误标识符的名称即property.readOnly。shortDescription一句话概括触发条件——子类中的 readonly 属性覆盖了父类中的可读写readwrite属性。ignorablefalse表示该错误不可忽略。按照 website/errors/CLAUDE.md 中记录的约定ignorable: false对应规则构建链中使用了-nonIgnorable()的情形或以phpstan.、phpstanPlayground.开头的标识符意味着此类问题不能通过常规的ignoreErrors配置掩盖必须真正修正代码。在 PHPStan 输出的错误报告中每个错误都带有标识符形如Line 6: Readonly property Child::$value overrides readwrite property Base::$value. ── property.readOnly标识符是错误信息中的稳定机器可读标签配合--error-format或编辑器集成可用于精确定位与统计一类问题。触发示例最小复现代码原文档给出了一个最小化的 PHP 示例能够稳定触发property.readOnly?php declare(strict_types 1); class Base { public mixed $value; } class Child extends Base { public readonly mixed $value; }核心特征有两点父类Base声明了一个可读写readwrite属性$value子类Child用readonly修饰符覆盖了同名属性$value。在 PHP 8.1 起引入的 readonly 属性语义下readonly属性只能在初始化时赋值一次此后不可再写入。子类这一覆盖行为把父类可读写的契约收窄成了只读。为什么会被报告LSP 契约破坏原文档明确指出该错误的本质是违反里氏替换原则Liskov Substitution Principle, LSPAreadonlyproperty in a child class is overriding a readwrite property in the parent class. The parent class allows both reading and writing, but the child class restricts writing. This violates the Liskov Substitution Principle because code written against the parent type expects to be able to assign the property.也就是说子类Child是父类Base的子类型任何针对Base类型编写的代码都假定可以读取并写入$value。当Child实例被当作Base使用多态替换时写入操作会在运行时抛出ErrorPHP 对 readonly 属性二次赋值会抛出Error: Cannot modify readonly property。子类通过readonly收窄了父类公开的写入能力破坏了子类必须能够替换父类且不改变程序行为的契约。从 PHP 语言语义角度看这也是一个真实可运行的运行时风险而不仅仅是静态分析层面的洁癖PHP 允许声明这种覆盖readonly与普通属性的覆盖在语言层面是合法的但在运行时任何基于父类类型签名编写的赋值代码遇到Child实例都会直接报错。PHPStan 的作用就是在运行之前把这个隐患暴露出来。更隐蔽的变体readonly修饰符的冲突不止出现在直接 extends 的场景。从 website/errors/ 目录中同族标识符可见PHPStan 会系统性地检查 readonly 属性的各类非法使用方式例如property.readOnlyAssignNotInConstructor.mdreadonly 属性在构造函数之外被赋值property.readOnlyAssignNotOnThis.mdreadonly 属性不是通过$this-在声明类内部赋值property.readOnlyAssignOutOfClass.mdreadonly 属性在声明类外部被赋值property.readOnlyNoNativeType.mdreadonly 属性缺少原生类型声明readonly 属性必须有类型property.readOnlyDefaultValue.mdreadonly 属性带有默认值不允许property.readOnlyInInterface.md接口中声明了 readonly 属性不允许assign.readOnlyProperty.mdreadonly 属性被赋值多次。其中assign.readOnlyProperty与本文主题最接近但角度不同它关注的是单个 readonly 属性在构造流程中被赋值多次而property.readOnly关注的是继承层级中可写契约被收窄。两者分别对应 readonly 属性只能初始化一次和不能覆盖可写父类属性两条独立约束。如何修复两种方向原文档给出了两种修复方向分别对应子类让步与父类对齐两种契约调整策略。方案一移除子类的 readonly 修饰符匹配父类契约如果属性在父类中就是可读写的子类应保持一致去掉readonly?php declare(strict_types 1); class Base { public mixed $value; } class Child extends Base { - public readonly mixed $value; public mixed $value; }这是最直接的修复子类不再收窄父类契约针对Base编写的赋值代码在任何子类型上都能正常工作LSP 冲突消除。方案二父类也声明为 readonly让整个层级只读如果业务上该属性本就应该是只读的例如依赖注入的配置项、不可变值对象那么应当让父类同步声明readonly使契约在整个继承层级中一致收窄?php declare(strict_types 1); class Base { - public mixed $value; public readonly mixed $value; } class Child extends Base { public readonly mixed $value; }注意当父类属性为readonly时子类覆盖该属性必须也使用readonly修饰符这是 PHP 语言的硬性要求——因此方案二的改写同时满足了两层约束语言层面合法静态分析层面不再冲突。如何选择若属性在运行时确实会被重新赋值可变状态选方案一去掉子类的readonly若属性是初始化后不可变的不可变对象、配置快照选方案二并确保所有赋值都发生在声明类内部通常位于构造函数或__clone()中。两种方案的共同原则是继承层级中的属性读写契约必须一致不允许子类单方面收窄父类的公开能力。深入理解PHP readonly 属性约束全景要彻底理解property.readOnly需要把 PHP readonly 属性的完整约束装进头脑。readonly 属性自 PHP 8.1 引入其约束包括只能赋值一次初始化后的再次赋值会抛出运行时Error初始化位置受限赋值只能在声明它的类内部、且通过$this-进行通常即构造函数必须声明类型readonly属性不能缺少原生类型声明不能有默认值readonly属性不能带默认值因为没有类型声明之外的初始化入口不能用于接口接口中的属性不能声明为readonly克隆时重新初始化PHP 8.3自 PHP 8.3 起readonly属性可以在__clone()中重新初始化但每个克隆过程仍只能赋值一次。property.readOnly是上述约束在继承场景下的延伸即使子类属性的赋值行为完全合规例如在子类构造函数中只赋值一次只要它覆盖了父类一个可写属性就破坏了针对父类类型编写的外部代码的假设。这也是该错误标识符ignorable: false的原因——它代表的是设计层面的契约破坏无法通过忽略配置来规避。在项目中定位与排查在实际项目中遇到property.readOnly时建议按以下步骤排查定位报告行PHPStan 会在覆盖发生的属性声明行上报告错误在示例中是Child::$value的声明行查看继承链向上查找父类或接口、trait中同名属性的声明确认其是否可读写确认运行时行为判断该属性在真实业务中是否会被重新赋值。若会选方案一若不会选方案二并把父类的契约一并改掉检查同族问题修复后运行 PHPStan 全量扫描确认没有连带触发 assign.readOnlyProperty 等其他 readonly 相关标识符。需要注意本仓库镜像未包含 PHPStan 的src/完整源码目录因此上述关于规则实现细节的说明主要依据 website/errors/CLAUDE.md 中记录的标识符文档生成规范与 website/errors/ 目录下的各标识符文档推断得出从这些文档的 frontmatter 与结构看每个错误标识符文档统一采用 Code example → Why is it reported? → How to fix it 三段式结构property.readOnly即遵循这一标准模板。延伸阅读错误标识符文档规范了解 PHPStan 错误标识符文档的生成方式、frontmatter 字段含义title、shortDescription、ignorable与撰写约定assign.readOnlyProperty.mdreadonly 属性重复赋值的检测逻辑与修复示例含 PHP 8.3__clone()重新初始化场景property.readOnlyAssignNotInConstructor.md 与 property.readOnlyNoNativeType.mdreadonly 属性其他常见违规形式的参考README.mdPHPStan 项目概览与基本使用方式。赞分享开发工具代码质量静态分析【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址https://gitcode.com/gh_mirrors/ph/phpstan点击查看免费下载相关推荐PHPStan 错误标识符 property.readWrite 详解可写属性覆盖父类 readonly 属性的检测与修复PHPStan 错误标识符 property.readWrite 详解可写属性覆盖父类 readonly 属性的检测与修复 本篇技术指南围绕 PHPStan开发工具代码质量静态分析PHPStan 错误标识符 property.nonStatic子类非静态属性覆盖父类静态属性时的静态性冲突检测PHPStan 错误标识符 property.nonStatic子类非静态属性覆盖父类静态属性时的静态性冲突检测 本篇技术指南讲解 PHPStan 错误标识符开发工具代码质量静态分析Wagtail 嵌入式内容Embeds完全指南oEmbed、自定义 Finder 与 Embed 模型详解Wagtail 嵌入式内容Embeds完全指南oEmbed、自定义 Finder 与 Embed 模型详解 Wagtail 作为一款以灵活性和用户体验为核开发工具代码质量静态分析上一篇Honcho混合搜索指南BM25向量检索如何让AI精准找到记忆下一篇猫抓Cat-Catch浏览器资源嗅探终极指南轻松下载网页视频音频创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
有哪些适合小白的AI漫剧工具 知漫剧值得用吗 前言
AI 漫剧最劝退新手的是角色每帧变脸和流程割裂。知漫剧(zz.jiaxunai.cn)价格实惠,一键生成,小白轻松入门。平台有全流程一整套教学,角色、声音、场景一致性知漫剧都能解决。 知漫剧是什么
知漫剧是一个在线 AI … · 2026/9/24 15:42:32
Redwood 8.0 部署指南:通过 Coherence 在 GCP/AWS 上实现全生命周期环境自动化 Redwood 8.0 部署指南:通过 Coherence 在 GCP/AWS 上实现全生命周期环境自动化 【免费下载链接】redwood RedwoodGraphQL 项目地址: https://gitcode.com/gh_mirrors/re/redwood
Coherence 是 Redwood 官方支持的一款 serverful(服务器型… · 2026/9/24 15:42:19
Python网站导航项目-2.项目创建与环境配置 本项目旨在构建一个高效的导航网站系统,通过后台管理应用和前端渲染模板相结合,为用户提供便捷的导航数据管理。项目从需求分析到环境搭建、数据管理与模板优化,采用模块化设计,确保扩展性。
配置中引入Xadmin和DjangoUeditor,以提升后台操作效率,同时支持批量抓取外部网… · 2026/9/24 16:07:06
thumbor 图片旋转过滤器 rotate(angle) 完全指南:用法、参数与引擎实现原理 后端图像处理 【免费下载链接】thumbor thumbor is an open-source photo thumbnail service by globo.com 项目地址: https://gitcode.com/gh_mirrors/th/thumbor 点击查看 免费下载 本文围绕 thumbor(globo.com 开源的图片缩略图服务)内置… · 2026/9/24 16:07:00
如何用 Perfetto 系统追踪 5 步定位卡顿与内存异常:Android 性能排查实战指南 如何用 Perfetto 系统追踪 5 步定位卡顿与内存异常:Android 性能排查实战指南 【免费下载链接】perfetto Production-grade client-side tracing, profiling, and analysis for complex software systems. 项目地址: https://gitcode.com/GitHub_Trending/pe/perf… · 2026/9/24 16:06:44
基于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