wilensky / bitmask-trait
通用的PHP7特性,提供便捷的位掩码管理和集成
v1.1
2017-01-15 11:21 UTC
Requires
- php: >=7.0.1
Requires (Dev)
- phpunit/phpunit: >=4.0
This package is not auto-updated.
Last update: 2024-09-23 14:18:31 UTC
README
PHP7位掩码特性提供应用程序中位掩码的无缝集成。
位掩码在需要将多个状态分配给单个实体或/和同时存在的情况下非常有用。借助此特性,您可以轻松地将多达32/64个状态打包到单个整数中,这是其他人无法做到的。
通用示例
让我们以普通发票为例来展示其本质。
假设发票有几种状态
并且相关的付款可以有多种状态
看起来为了组织发票和付款的状态,我们需要12个字段,但使用位掩码就不需要了。
我们可以轻松地将所有的12个状态打包到一个已知的好整数值中。假设的状态映射可以是以下这样
它可以随着时间的推移以以下方式变化
基本用法
<?php use Wilensky\Traits\BitmaskTrait; class MyClass { use BitmaskTrait; // Injecting trait in your class }
为了方便使用,可以创建具有相关位位置的const
。
const INVOICE_SENT = 0; const INVOICE_OPENED = 1; // ... for the sake of brevity const PAYMENT_REFUSED = 10; const PAYMENT_REFUNDED = 11;
创建状态
// All further code assumed inside a class scope function as trait has no public methods $state = 0; // Initial/Zero state $sent = $this->setBit( $state, // Passing initial/existing state to assign few more to self::INVOICE_SENT, // (bit 0) self::INVOICE_OPENED // (bit 1) ); // 3 (bits 0/1) // Adding `PAYMENT_INPROGRESS` state to already arranged mask with 2 states $paymentInit = $this->setBit( $sent, // Passing existing mask `3` (with 2 states, 0 and 1 bits) self::PAYMENT_INPROGRESS // (bit 5) ); // 35 (bits 0/1/5) // or the same stuff with use of another method (@see BitmaskTrait::manageMaskBit()) $paymentInit = $this->manageMaskBit($sent, self::PAYMENT_INPROGRESS, true); // Proceeding to some terminal payment state $noOpenInProgress = $this->unsetBit( $paymentInit, // 35 self::PAYMENT_INPROGRESS, // Removing `PAYMENT_INPROGRESS` state (bit 5) self::INVOICE_OPENED // among with `INVOICE_OPENED` (bit 1) ); // 1 (bits 0) // to add relevant terminal states $invoiceClosed = $this->setBit( $noOpenInProgress, // Passing mask with relevant unset states self::PAYMENT_SUCCESSFUL, // (bit 6) self::INVOICE_CLOSED // (bit 2) ); // 69 (bits 0/2/6)
检查状态
$state = 69; // Invoice closed $isInvoiceSent = $this->hasBit($state, self::INVOICE_SENT); // true $isPaymentSuccessful = $this->hasBit($state, self::PAYMENT_SUCCESSFUL); // true $isRefunded = $this->hasBit($state, self::PAYMENT_REFUNDED); // false
检查段
我们记得,我们有一个包含发票状态和付款状态的单一掩码。有时,检查传递的位是否与特定的段(如果正在使用)相关,或者是否超过了掩码的大小本身,是有用的。
$invoiceSegment = [0, 4]; // Segment range as a single variable // No exception as state is in allowed range $this->isBitInRange(self::INVOICE_CLOSED, ...$invoiceSegment); // `BitAddressingException` will be thrown as payment state is not in allowed range $this->isBitInRange(self::PAYMENT_SUCCESSFUL, ...$invoiceSegment);