通常,位字段是一种非常方便有效的工具,用于处理标志或任何布尔值集。
要了解它们,您首先需要知道二进制数是如何工作的。之后,您应该查看按位运算符的手动输入,并确保您知道按位AND,OR和左/右移位的工作方式。
位域不过是一个整数值。假设我们的位字段的大小是固定的,只有一个字节。计算机使用二进制数字工作,因此,如果我们的数字值为
29,您实际上会
00011101在内存中找到。
使用按位AND(
&)和按位OR(
|),您可以读出并分别设置数字的每一位。它们都接受两个整数作为输入,并分别对每个位执行AND / OR。
要读出号码的第一位,可以执行以下操作:
0001 1101 (=29, our number)& 0000 0001 (=1, bit mask)= 0000 0001 (=1, result)
如您所见,您需要一个特殊的数字,即仅设置我们感兴趣的位,即所谓的“位掩码”。在我们的情况下是
1。要读出第二位,我们必须将位掩码中的一位“推”到左边一位。我们可以使用左移运算符(
$number<< 1)或乘以2来实现。
0001 1101& 0000 0010= 0000 0000 (=0, result)
您可以在我们的电话号码中做到这一点。我们的数字与位掩码的二进制与结果要么为零(表示未“置位”),要么为非零整数(即该位已置位)。
如果要设置一位,则可以使用按位或:
0001 1101| 0010 0000 (=32, bit mask)= 0011 1101 (=29+32)
但是,当您想“清除”一点时,就必须走另一条路。
更一般的方法是:
// To get bit n$bit_n = ($number & (1 << $n)) != 0// Alternative$bit_n = ($number & (1 << $n)) >> $n// Set bit n of number to new_bit$number = ($number & ~(1 << $n)) | ($new_bit << $n)
乍一看,它看起来有些神秘,但实际上很简单。
到现在为止,您可能已经发现位字段是一种很底层的技术。这就是为什么我建议不要在PHP或数据库中使用它们。如果您想要一堆标志可能没问题,但是对于其他任何事情,您实际上都不需要它们。
您发布的课程对我来说有点特殊。例如,类似
... ? true :false的事情非常糟糕。如果要使用位字段,最好定义一些常量并使用上述方法。上一堂简单的课并不难。
define('PERM_READ', 0);define('PERM_WRITE', 1);class BitField { private $value; public function __construct($value=0) { $this->value = $value; } public function getValue() { return $this->value; } public function get($n) { return ($this->value & (1 << $n)) != 0; } public function set($n, $new=true) { $this->value = ($this->value & ~(1 << $n)) | ($new << $n); } public function clear($n) { $this->set($n, false); }}$bf = new BitField($user->permissions);if ($bf->get(PERM_READ)) { // can read}$bf->set(PERM_WRITE, true);$user->permissions = $bf->getValue();$user->save();我没有尝试此答案的任何代码,但是即使它开箱即用,它也应该使您入门。
请注意,每个位字段限制为32个值。



