php位运算符怎么使用_php位运算符操作方法【进阶】

5次阅读

php位运算符怎么使用_php位运算符操作方法【进阶】

运算符php 中的实际用途是什么

PHP 的位运算符不是用来炫技的,而是解决特定问题的工具:权限控制、状态标记、网络协议解析、图像像素处理这些场景里,用 &|^~、<code>>>字符串或数组更省空间、更快。它们直接操作整数的二进制位,所以输入必须是整数(int),浮点数、字符串、NULL 会被静默转成 0,容易出错。

常见错误现象:echo '12' & '3'; 输出 0 —— 因为字符串被转成 0 再运算;echo 12 & '3'; 同样是 0;只有 12 & 3 才是预期的 01100 & 0011 = 0000)。

  • 权限系统常用 1 (1)、<code>1 (2)、<code>1 (4)定义 READ/WRITE/EXECUTE
  • 判断是否拥有某权限:用 &,如 $userPerm & READ
  • 添加权限:用 |,如 $userPerm |= WRITE
  • 移除权限:用 & ~,如 $userPerm &= ~EXECUTE

为什么 &and 结果不同

这是最容易踩的坑:& 是位运算符,and 是逻辑运算符,优先级完全不同。PHP 中 and 优先级比赋值 = 还低,而 & 优先级高于 =

示例:$a = 5 & 3; → 正确计算为 $a = 1;但 $a = 5 and 3; → 先执行 $a = 5(返回 true),再执行 true and 3(返回 true),但 $a 仍是 5,整个表达式结果却被丢弃。

立即学习PHP免费学习笔记(深入)”;

  • 永远用 & 做位判断,别用 and 替代
  • 调试时加括号不保险:($a = 5) and 3 依然不是位运算
  • 检查权限组合是否生效?直接输出 var_dump($perm & FLAG_A),别用 if ($perm and FLAG_A)

和 <code>>> 移位要注意符号和溢出

左移 相当于乘以 2 的 n 次方,右移 <code>>> 相当于除以 2 的 n 次方并向下取整——但仅对非负数成立。PHP 的整数是有符号的(通常 64 位),右移负数会做算术右移(高位补 1),结果不符合直觉。

示例:echo -8 >> 1; 输出 -4(正常),但 echo -1 >> 1; 输出 -1(因为全 1 的补码右移还是全 1);而 echo 0x80000000 >> 1; 在 32 位系统上可能变成负数,64 位上也可能因符号位触发扩展。

  • 只对已知非负整数使用移位,否则先用 abs()& 0xffffffff 截断
  • 移位位数不能为负,也不能 ≥ 整数位宽(如 64 位系统上不能 >> 64),否则结果为 0(PHP 8+ 报 ValueError
  • 需要无符号右移?用 ($x >> $n) & ~(~0 或改用 <code>gmp 扩展

位运算和类型转换的隐式陷阱

PHP 不强制类型声明,但位运算要求操作数是整型。一旦传入 floatstringbool,就会触发隐式转换,且规则不直观:

echo 12.9 & 7;12 & 7 = 4floatint 是截断,不是四舍五入);echo '12' & '7';0 & 0 = 0(字符串转整数失败时为 0);echo true & false;1 & 0 = 0bool 转整数是 1/0)。

  • 入库前或函数入口加 assert(is_int($x) && is_int($y)) 或用严格类型声明 function foo(int $a, int $b): int
  • $_GET 或数据库读来的数字,务必用 (int) 强转,别依赖自动转换
  • var_dump(gettype($x), $x) 确认真实类型,比 echo 更可靠

位运算本身很快,但类型混乱会让结果不可预测。真正难的不是记住 ^ 是异或,而是确保参与运算的每个值,从源头开始就是干净的整数。

text=ZqhQzanResources