深入解析 PHP-CS-Fixer 的no_short_bool_cast规则用(bool)取代!!双重否定【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer本篇技术指南围绕 PHP-CS-Fixer 内置规则no_short_bool_cast展开说明它为什么禁止用双重感叹号!!做布尔强转、它的修复结果长什么样、底层 Token 级实现如何工作以及它如何与cast_spaces等规则协同。读完你将能熟练地在自己的.php-cs-fixer.php配置中启用并调优该规则并通过源码与测试用例验证它的全部行为边界。规则定位什么是“短布尔强制转换”PHP 中常见的布尔强转写法有两种显式强制转换(bool) $value语义清晰、可读性好双重否定double negation!!$value先把值转成布尔再取反一次等效于布尔强转但写法晦涩容易在阅读时产生歧义。no_short_bool_cast规则的核心立场即官方规则定义文本是Short castboolusing double exclamation mark should not be used.也就是不应当使用!!这种“双重感叹号”式的布尔短转换。该规则会将代码中出现的!!统一改写为显式的(bool)强制转换。修复示例规则文档给出了标准示例!!会被改写为(bool)--- Original New ?php -$a !!$b; $a (bool)$b;从源码看该规则属于PhpCsFixer\Fixer\CastNotation命名空间下的 NoShortBoolCastFixer与之同目录的还有cast_spacesCastSpacesFixer、lowercase_cast、short_scalar_cast等一整套类型转换书写规范规则因此它被归入文档的cast_notation类型转换书写分类。源码实现它是如何在 Token 层面工作的该规则继承自AbstractFixer核心逻辑集中在三个环节候选检测、反向扫描、成对替换。候选检测isCandidatepublic function isCandidate(Tokens $tokens): bool { return $tokens-isTokenKindFound(!); }只有当整个文件的 Token 流中存在!字符时该 Fixer 才会进入实际修复流程。这保证了绝大多数不含取反运算的文件可以零成本跳过该规则。反向扫描与成对匹配applyFix / fixShortCastapplyFix从 Token 流的尾部向前遍历每遇到一个!就调用fixShortCast继续向前查找与之匹配的另一个!中间只允许出现注释Comment与空白Whitespace一旦遇到其他非注释、非空白的 Token 就立即停止。protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { for ($index \count($tokens) - 1; $index 1; --$index) { if ($tokens[$index]-equals(!)) { $index $this-fixShortCast($tokens, $index); } } }这解释了文档示例中$a !!$b;的完整修复过程找到相邻两个!或中间仅隔注释/空白的两个!确认它们构成“双重否定”后进入替换。成对替换fixShortCastToBoolCastprivate function fixShortCastToBoolCast(Tokens $tokens, int $start, int $end): void { for (; $start $end; $start) { if ( !$tokens[$start]-isComment() !($tokens[$start]-isWhitespace() $tokens[$start - 1]-isComment()) ) { $tokens-clearAt($start); } } $tokens-insertAt($start, new Token([\T_BOOL_CAST, (bool)])); }替换逻辑非常精细清空两个!及其之间的空白 Token但会保留注释包括紧跟注释之后的空白避免修复过程破坏原有注释最后在起始位置插入一个类型为T_BOOL_CAST、文本为(bool)的新 Token。正是这段保留注释的逻辑让下面的测试用例得以成立——被注释“隔开”的!依然能被识别并正确替换。行为边界测试用例揭示的完整语义官方测试类 NoShortBoolCastFixerTest 定义了该规则受向后兼容承诺保护的全部官方行为。结合测试数据可以看出以下边界1. 两个!之间允许存在注释与换行修复后注释原样保留// 输入 $c ! // lala // cc !$content; // 输出 $c // lala // cc (bool)$content;2. 两个!之间可以跨越多行、夹带块注释// 输入 $b !/* */!$a; // 输出 $b /* */(bool)$a;3. 单个!不会被误伤——!$a、! $a带空格、!(!$foo)括号包裹的取反都不属于短布尔转换$d !$a; // 保持不动 $d1 ! $a; // 保持不动 $b !(!$foo); // 保持不动4. 字符串与注释中的!!不受影响echo !!;以及注释// !! ! !都会被完整跳过因为 Token 化阶段字符串与注释是独立 Token不参与匹配。5. 无论!之间是否有空格或换行最终统一收敛为(bool)// 输入 $c ! ! $b; $e ! ! $d1; return !! $a; // 输出 $c (bool) $b; $e (bool) $d1; return (bool) $a;测试类通过#[DataProvider(provideFixCases)]驱动testFix逐条断言“期望输出”与“可选输入”的转换关系是理解该规则行为最权威的文档。与其他规则的协作优先级与集成测试每个 Fixer 都有一个优先级priority用于决定多个规则同时启用时谁先执行。NoShortBoolCastFixer的优先级为-9源码注释明确说明Must run before CastSpacesFixer.即它必须先于cast_spaces运行。原因很直观no_short_bool_cast先把!!改写成(bool)随后cast_spaces再负责把(bool)$a与(bool) $a的空格规范统一。仓库中的集成测试 no_short_bool_cast,cast_spaces.test 用端到端方式验证了这一协作流程--RULESET-- {no_short_bool_cast: true, cast_spaces: true} --INPUT-- ?php $b !!$a; --EXPECT-- ?php $b (bool) $a;输入$b !!$a;经过两个规则叠加后输出为带空格风格的(bool) $a证明两条规则在优先级机制下无缝衔接。如何启用该规则方式一使用内置规则集no_short_bool_cast是以下两个内置规则集的组成部分Symfony见 Symfony.rst配置定义位于 SymfonySet.php其中显式包含no_short_bool_cast truePhpCsFixer见 PhpCsFixer.rst该规则集在 PhpCsFixerSet.php 中通过Symfony true继承而来因此无需重复声明。在项目配置中只需引用规则集即可?php // .php-cs-fixer.php return (new PhpCsFixer\Config()) -setRules([ Symfony true, // 已包含 no_short_bool_cast ]) ;方式二单独启用如果只想启用这一条规则而不引入整个规则集可在配置中单独指定?php return (new PhpCsFixer\Config()) -setRules([ no_short_bool_cast true, ]) ;该规则没有可配置选项optiontrue即表示开启语义简单。方式三命令行验证在仓库根目录直接运行项目自带的可执行文件php-cs-fixer可以对单个文件做 dry-run 预览php php-cs-fixer fix /path/to/file.php --rulesno_short_bool_cast --dry-run --diff--dry-run只输出改动而不落盘--diff以 diff 形式展示即将产生的修改效果与文档中的示例块一致。更完整的使用说明可参考 usage.rst 与 config.rst。结语no_short_bool_cast是一个“小而精”的规范化规则它的修复目标单一明确用可读性更强的(bool)取代晦涩的!!它的实现精细在 Token 层面对注释、空白、字符串与单个取反做了周全的边界处理它的测试完备任何行为变化都受向后兼容承诺约束它与cast_spaces的优先级协作则是 PHP-CS-Fixer 规则调度机制的典型案例。无论你是通过Symfony/PhpCsFixer规则集间接启用还是单独配置它都能以零配置选项的轻量姿态提升代码的可读性。【免费下载链接】PHP-CS-FixerA tool to automatically fix PHP Coding Standards issues项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
3个坑教你怎么给照片换背景,附避坑指南 3个坑教你怎么给照片换背景,附避坑指南 你从GitHub复制的 rembg 代码,运行后背景全黑或者报错 ImportError ,根本不知道怎么调?别急,这种“复制粘贴即崩溃”的噩梦太常见了。今天这份 避坑指南… · 2026/9/23 1:57:43
深度强化学习求解动态图最短路径:DQN实战指南 简介:这是一份面向人工智能与算法学习者的深度强化学习实践代码包,聚焦于使用Deep Q-Network(DQN)求解图结构中的最短路径问题,适用于具备Python基础与强化学习入门知识的开发者、高校学生及算法爱好者。资源包含8个文… · 2026/9/23 1:57:43
栈数据结构深度解析:从函数调用到堆栈溢出实战 1. 堆栈究竟是什么:从生活场景到核心抽象如果你接触过数据结构,哪怕只是刚开始准备考研、刷LeetCode,或者在学校里正在为《数据结构》实验报告发愁,那“堆栈”这个词你一定不陌生。它还有个别名叫“栈”,英文叫Stack。… · 2026/9/23 5:39:44
management缩写避坑指南:3个常见误区+完整示例 management缩写避坑指南:3个常见误区+完整示例 官方文档翻了三遍还是记不住 management 的缩写?别慌,这不是你笨,是文档写法反人类。我见过太多开发者在配置 API 或解析日志时,因为搞混 mgmt 、 mgt 、… · 2026/9/23 5:39:44
SpringBoot+Vue箱包仓储管理系统全栈开发实践 1. 项目概述:箱包存储系统信息管理解决方案箱包存储系统信息管理系统是一套针对仓储物流行业设计的全栈解决方案,它完美结合了SpringBoot后端的高效稳定、Vue前端的灵活交互以及MySQL的数据可靠性。这个开箱即用的系统特别适合中小型物流企业、电商仓库以… · 2026/9/23 5:39:44
搞定n代表什么数:附完整示例与性能优化实战 搞定n代表什么数:附完整示例与性能优化实战 你复制来的代码跑不通,是不是经常卡在这里?别急,今天我们不聊虚的,直接上 完整示例 ,带你彻底搞懂循环变量 n 在性能优化里的坑。很多老手都栽在这上面,以为 n 只是个数,其实它决定了你的算法是… · 2026/9/23 5:39:44
从拟声词到网络热词:cua如何成为全网通用梗 最近不管是刷短视频,还是混在各种聊天群里,你大概率都见过这个词:cua。别看它只有三个字母,现在它已经不是一个简单的拟声词了,而是一种状态、一种情绪、一种“事情就这么发生了”的叙述方式。今天想好好聊聊它&#x… · 2026/9/23 5:39:37
QEMU ACPI PCI 热插拔接口规范:从 IO 端口协议到 AML 生成的完整解析 QEMU ACPI PCI 热插拔接口规范:从 IO 端口协议到 AML 生成的完整解析 【免费下载链接】qemu Official QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarbal… · 2026/9/23 5:39:37
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29