~是按位取反而非逻辑取反,对整数每位二进制翻转并返回补码负数;!返回布尔值,二者不可互换;常用于掩码构造如~0xff清零低8位;decbin()不支持负数,类型隐式转换易引发错误。

PHP中~是按位取反,不是逻辑取反
PHP的~操作符对整数的**每一位二进制位做翻转**(0变1,1变0),结果是带符号补码表示的负数。它和!完全不同:!只关心真假值、返回布尔型;~严格按位运算、返回整数。
常见误用场景:想“取反一个条件”却写了~$flag,结果得到一个大负数,后续判断直接出错。
-
~0→-1(因为 PHP 整数是补码,全 1 表示 -1) -
~1→-2(1 的二进制是 ...001,取反后是 ...110,即 -2) -
~255→-256(不是 0,注意符号位参与运算)
想清零低8位?用~0xFF配合&
按位取反常用于构造掩码(mask)。比如要清除一个整数的低 8 位(即让最后 8 个 bit 变 0),可以先用~0xFF得到一个“除了低 8 位全是 1”的掩码,再与原数做&:
$x = 0x1234; $result = $x & ~0xFF; // 保留高字节,清零低8位 → 0x1200
这里0xFF是 255(二进制 11111111),~0xFF在 64 位系统上实际是0xFFFFFFFFFFFFFF00(高位全 1),但 PHP 会自动按整数位宽处理,无需手动补位。
- 别写
& 0xFFFFFF00——平台相关,32/64 位结果可能不一致 -
~0xFF可读性更好,也更安全 - 若要清零低 n 位,用
& ~( (1
和bindec()/decbin()混用时要注意符号扩展
PHP 的decbin()只显示正数的二进制形式,对负数(如~5)直接返回空字符串或报 Warning。反过来,bindec('11111111')永远是 255,不会被解释为 -1。
-
echo decbin(~5);→ 空输出(PHP 8+ 报Warning: decbin(): Argument must be greater than or equal to 0) - 调试时想看补码形式,得自己转:
sprintf('%08b', $x & 0xFF)(取低8位再转) - 不要依赖
decbin(~$n)来“观察取反效果”,它不反映真实位模式
性能和类型陷阱:字符串、float、null 都会强制转 int
~只定义在整数上。遇到其他类型,PHP 会静默转换,但结果往往不符合直觉:
-
~"123"→ 先转成 int 123,再取反 →-124 -
~3.14→ 截断为 3 →-4 -
~null→ 转为 0 →-1 -
~[]→ 转为 0(空数组转 int 是 0)→-1
这种隐式转换容易掩盖逻辑错误。如果业务真需要位运算,务必确保操作数是明确的int类型,可用(int)强制转换,或用is_int()校验。
补码、类型转换、掩码构造这三点没理清,~很容易变成“看起来像在干活,其实结果完全不对”的操作符。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











