ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

PHPStan 错误 `paramOut.tooWideBool` 详解:`@param-out bool` 过宽时如何收窄类型

PHPStan 错误 `paramOut.tooWideBool` 详解:`@param-out bool` 过宽时如何收窄类型 PHPStan 错误paramOut.tooWideBool详解param-out bool过宽时如何收窄类型【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstanparamOut.tooWideBool是 PHPStan 在“TooWideTypehints类型声明过宽”系列规则中针对param-out注释生成的一个错误标识符当函数通过引用参数向外输出值且param-out声明的类型是bool但函数体内实际只赋值过true或只赋值过false时触发。读完本文你将理解该错误的判定逻辑、它与其他tooWideBool标识符的关系并掌握收窄param-out类型或补齐缺失代码路径的两种修复方案。错误标识符与触发条件paramOut.tooWideBool属于 PHPStan 错误标识符error identifier体系官方文档对它的定义是Declared param-out type is bool but only one of true or false is ever assigned.声明的param-out类型为bool但实际只赋值了true或false中的某一个。该定义同时记录在文档文件的 frontmatter 中详见 paramOut.tooWideBool.mdfrontmatter 的title与shortDescription字段并被登记在标识符总表 errorsIdentifiers.json 中作为可被忽略ignorable的错误处理。触发示例原文档给出如下最小触发代码?php declare(strict_types 1); /** * param-out bool $result */ function validate(mixed $input, bool $result): void { $result true; }这里$result是一个按引用by-reference参数param-out bool承诺函数返回时该参数的类型是bool。但函数体内所有路径都只赋值true从未赋值false因此 PHPStan 判定声明的输出类型比实际产生的值“更宽too wide”从而报告paramOut.tooWideBool。为什么会报告这个错误param-out的本质是一个对外契约param-out是 PHP 的 PHPDoc 约定PHPStan 支持用于描述按引用参数在函数返回时应具有的类型。它与调用方构成契约调用方在函数调用结束后读取该变量时可以信任param-out声明的类型。这一语义在同类错误 paramOut.type 中有更直接的体现——当实际赋值与声明类型不匹配时PHPStan 会报告“expects int, string given”之类的错误。而在paramOut.tooWideBool场景下问题不是“类型不匹配”而是“声明过宽”bool在 PHPStan 的类型系统中被拆分为两个字面量类型true与false函数实际只产生其中一个。原文档指出声明的param-out类型为bool但 PHPStan 通过控制流分析确定参数只被赋值为true或只被赋值为false其中一个布尔值永远不会被产生因此声明的输出类型比必要范围更宽这说明param-out注释比函数实际赋值行为更加宽松permissive。换句话说这个错误通常暗示函数在实现上“永远返回同一个布尔常量”而声明却给了调用方一个过大的承诺——调用方可能据此编写false分支的代码但该分支实际上永远不会被执行。与true/false字面量类型的关系从 PHPStan 的类型模型看bool等价于联合类型true|false。当函数只赋值true时实际输出类型是字面量类型true它是bool的真子集因此声明bool就属于过宽。这与同一系列下的return.tooWideBool返回类型声明bool但只返回true或false和parameterByRef.tooWideBool原生按引用参数类型为bool但只赋值其一是同一套“类型收窄”哲学在不同声明位置的体现。如何修复两种方案原文档给出了两条修复路径分别对应“函数确实只会输出一个布尔值”和“函数本应输出两种布尔值”两种真实意图。方案一收窄param-out类型如果函数确实只产生true或只产生false就把param-out收窄为对应的字面量类型?php declare(strict_types 1); /** - * param-out bool $result * param-out true $result */ function validate(mixed $input, bool $result): void { $result true; }这样声明与实现完全一致调用方也能获得更精确的类型信息。方案二补齐缺失的代码路径如果函数本意是“有时返回true、有时返回false”则是函数体逻辑不完整应当补充赋值false的分支?php declare(strict_types 1); /** * param-out bool $result */ function validate(mixed $input, bool $result): void { - $result true; $result $input ! null; }此时$result既可能为true也可能为falseparam-out bool的声明就名副其实了。关联错误标识符与规则实现paramOut.tooWideBool并不是孤立存在的理解它需要结合同一主题下的几个兄弟标识符标识符触发场景参考文档paramOut.tooWideBoolparam-out声明bool但只赋值true/false之一paramOut.tooWideBool.mdparameterByRef.tooWideBool原生按引用参数类型bool但只赋值其一parameterByRef.tooWideBool.mdreturn.tooWideBool函数声明bool返回类型但只返回true/false之一return.tooWideBool.mdparamOut.type赋值与param-out声明类型不匹配而非过宽paramOut.type.md从标识符注册表 errorsIdentifiers.json 可以看出paramOut.tooWideBool由TooWideTypehints规则组中的多个规则共同产出包括TooWideFunctionParameterOutTypeRule函数param-out、TooWideMethodParameterOutTypeRule方法param-out其判定逻辑集中在phpstan-src的src/Rules/TooWideTypehints/TooWideTypeCheck.php中该文件中同时承载return.tooWideBool、parameterByRef.tooWideBool等标识符的判定入口注册表按标识符列出了对应的规则类。由此可以推断PHPStan 会把函数/方法的输出位置返回值、param-out、按引用参数、属性统一交给TooWideTypeCheck做“实际产生值类型 ⊆ 声明类型”的检查布尔字面量类型正是这套检查的典型对象。如何忽略该错误可选与所有ignorable: true的标识符一样见 CLAUDE.md 中关于 frontmatter 的说明paramOut.tooWideBool可以通过 PHPStan 的ignoreErrors配置按标识符精确忽略。但需要强调的是只有当“声明过宽”是刻意设计例如保持 API 稳定、预留未来可能返回false的空间时才建议忽略大多数情况下按本文的方案一收窄类型是更符合静态分析本意的做法能让调用方获得最精确的类型保证。小结paramOut.tooWideBool报告的是param-out声明bool、但函数只产生true或false之一的问题属于“类型声明过宽”家族。修复方式只有两条路收窄声明改成param-out true或param-out false或补全实现增加产生另一布尔值的代码路径。该标识符由TooWideTypehints规则组中的TooWideFunctionParameterOutTypeRule、TooWideMethodParameterOutTypeRule等规则触发判定逻辑位于TooWideTypeCheck.php与return.tooWideBool、parameterByRef.tooWideBool共享同一套类型过宽检测机制。【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表