位运算符仅支持整数,字符串和浮点数会被静默转为0;权限系统中用&判断、|添加、& ~移除;&优先级高于=,and则相反;负数右移会算术扩展,需谨慎处理。

位运算符只认整数,字符串和浮点数会被静默转成0
PHP 的 &、|、^、~、、<code>>> 全部要求操作数是整型。一旦传入字符串或 float,会触发隐式类型转换:字符串转为 0(除非是纯数字字符串且未启用严格模式),float 截断小数部分,null 和 false 也变成 0。
常见错误现象:echo '12' & '3'; 输出 0,不是 12 和 3 的按位与结果;echo 12 & '3'; 同样输出 0——因为右侧字符串被转成整数 0,实际算的是 12 & 0。
- 确保输入是整数:用
(int)强制转换,或先用is_int()检查 - 权限系统中别写
$perm & 'READ',而应定义常量const READ = 1; - 调试时用
var_dump(gettype($x), $x)确认值的类型和内容,别只看echo结果
权限控制里用 & 判断、| 添加、& ~ 移除
位运算在权限系统中高效且省内存,每个权限对应一个 2 的幂:比如 READ = 1(0b001)、WRITE = 2(0b010)、EXECUTE = 4(0b100)。用户权限是这些值的组合,如 7 表示全有(0b111)。
关键操作不是逻辑判断,而是位判断:
立即学习“PHP免费学习笔记(深入)”;
- 判断是否拥有某权限:
if ($userPerm & READ) { ... }—— 注意不是if ($userPerm and READ) - 添加权限:
$userPerm |= WRITE;(等价于$userPerm = $userPerm | WRITE;) - 移除权限:
$userPerm &= ~EXECUTE;(~EXECUTE得到掩码,再用 & 清除对应位)
& 和 and 完全是两回事,优先级差异会导致赋值失效
& 是位运算符,优先级高于 =;and 是逻辑运算符,优先级比 = 还低。这直接导致语义错乱。
示例:$a = 5 & 3; 正确计算为 $a = 1;但 $a = 5 and 3; 实际执行顺序是 ($a = 5)(返回 true),再执行 true and 3(返回 true),而 $a 仍是 5,表达式结果却被丢弃。
- 永远用
&做权限判断或位操作,别用and替代 - 加括号也救不了:
($a = 5) and 3还是逻辑表达式,不改变$a的位运算意图 - 检查权限生效与否,直接输出
var_dump($perm & FLAG_A),别依赖if ($perm and FLAG_A)
右移 >> 对负数做算术右移,非预期结果很常见
>> 在 PHP 中对非负整数是“除以 2 的 n 次方并向下取整”,但对负数会保留符号位进行算术右移。例如 -1 >> 1 在多数环境下仍为 -1(补码全 1 右移后高位补 1),而不是 0 或 -0.5。
溢出和边界问题同样危险:1 在 64 位系统上结果为 <code>0(PHP 8+ 抛 ValueError),0x80000000 >> 1 可能因符号扩展产生意外负值。
- 只对已知非负整数使用移位;不确定时先用
abs($x)或$x & 0xffffffff截断 - 需要无符号右移效果?用
($x >> $n) & ~(~0 ,或改用 <code>gmp扩展 - 移位位数不能为负,也不能 ≥ 当前平台整数位宽(如 64 位系统最大允许
> 63)
位运算不是语法糖,它是直通二进制的操作。类型不对、符号位干扰、优先级误判——这三个点只要踩中一个,结果就完全不可信。调试时别只盯输出值,先确认输入是不是你想象中的整数,再看它在内存里到底长什么样。



















