reinder83 / binary-flags
二进制操作的有用类
Requires
- php: ^8.0
- ext-json: *
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.5
README
BinaryFlags
使用此类可以轻松地向您的项目添加标志。
您可以使用标志的数量受限于您的系统架构,例如:32位系统上的32个标志或64位系统上的64个标志。为了在数据库中存储64位标志,您需要将其存储为MySQL中的UNSIGNED BIGINT或您数据存储中的等效类型。
此包还包括一个特质,您可以使用它直接在您自己的类中实现二进制标志。
安装
要安装此包,只需在项目根目录中运行以下命令。
composer require reinder83/binary-flags
方法
可以使用以下方法:
setMask(int $mask)
覆盖当前掩码。这可以作为构造函数的第一个参数传递。
getMask(): int
检索当前掩码。
setOnModifyCallback(callable $onModify)
设置一个回调函数,当掩码更改时被调用。这可以作为构造函数的第二个参数传递。
getFlagNames([int $mask, [bool $asArray=false]])
为给定的 $mask
提供名称(或省略时为当前掩码)。当 $asArray
为 true
时,该方法将返回一个包含名称的数组,否则返回一个以逗号分隔的字符串(默认)。
addFlag(int $flag)
向当前掩码添加一个或多个标志。
removeFlag(int $flag)
从当前掩码中删除一个或多个标志。
checkFlag(int $flag, [bool $checkAll=true]): bool
检查给定的标志是否在当前掩码中设置。默认情况下,它将检查给定标志的所有位。如果您想匹配给定的任何标志,请将 $checkAll
设置为 false
。
checkAnyFlag(int $mask): bool
自:v1.0.1
为了您的方便,我已经为 checkFlag
添加了一个别名,将 $checkAll
设置为 false
。
count(): int
自:v1.2.0
返回已设置的标志数量。
jsonSerialize(): mixed
自:v1.2.0
返回一个可以由 json_encode() 编码的值,格式为 ["mask" => 7]
。您通常不需要直接调用此方法,相反,您可以传递 BinaryFlags 对象给 json_encode,它将将其转换为 '{"mask": 7}'。
静态方法
可以使用以下静态方法:
getAllFlags(): array
自:v1.1.0
以数组形式返回所有标志及其名称,使用它们的标志掩码作为键。此方法还可以被重载以返回标志的自定义名称,这些名称将由 getFlagNames
方法使用。
getAllFlagsMask(): int
自:v1.1.0
返回所有标志的总掩码
迭代
自:v1.2.0
您可以将 BinaryFlags 对象视为可迭代的,其中每次迭代将返回下一个已设置的位值及其描述(或表示位值的常量的名称)。
示例用法
以下是一些示例用法代码
创建类
// example classes which the following examples will refer to use Reinder83\BinaryFlags\BinaryFlags; use Reinder83\BinaryFlags\Bits; class ExampleFlags extends BinaryFlags { const FOO = Bits::BIT_1; const BAR = Bits::BIT_2; const BAZ = Bits::BIT_3; }
简单用法
$exampleFlags = new ExampleFlags(); // add BAR flag $exampleFlags->addFlag(ExampleFlags::BAR); var_export($exampleFlags->checkFlag(ExampleFlags::FOO)); // false var_export($exampleFlags->checkFlag(ExampleFlags::BAR)); // true // remove BAR flag $exampleFlags->removeFlag(ExampleFlags::BAR); var_export($exampleFlags->checkFlag(ExampleFlags::BAR)); // false
使用多个标志
$exampleFlags = new ExampleFlags(); // add FOO and BAR $exampleFlags->addFlag(ExampleFlags::FOO | ExampleFlags::BAR); var_export($exampleFlags->checkFlag(ExampleFlags::FOO)); // true var_export($exampleFlags->checkFlag(ExampleFlags::FOO | ExampleFlags::BAZ)); // false because BAZ is not set var_export($exampleFlags->checkFlag(ExampleFlags::FOO | ExampleFlags::BAR)); // true because both flags are set var_export($exampleFlags->checkFlag(ExampleFlags::FOO | ExampleFlags::BAZ, false)); // true because one of the flags is set (FOO) // alias of the above method var_export($exampleFlags->checkAnyFlag(ExampleFlags::FOO | ExampleFlags::BAZ)); // true
标志名称示例
默认情况下,标志名称基于常量名称
$exampleFlags = new ExampleFlags(); $exampleFlags->addFlag(ExampleFlags::FOO | ExampleFlags::BAR | ExampleFlags::BAZ); var_export($exampleFlags->getFlagNames()); // 'Foo, Bar, Baz' // null will force current mask var_export($exampleFlags->getFlagNames(null, true)); /* array ( 0 => 'Foo', 1 => 'Bar', 2 => 'Baz', ) */ // get flag names of given mask var_export($exampleFlags->getFlagNames(ExampleFlags::FOO | ExampleFlags::BAR)); // 'Foo, Bar'
自定义标志名称示例
如果您想使用与常量名称不相同的自定义标志名称,可以使用 getAllFlags()
覆盖这些名称
class ExampleFlagsWithNames extends BinaryFlags { const FOO = Bits::BIT_1; const BAR = Bits::BIT_2; const BAZ = Bits::BIT_3; public static function getAllFlags() { return [ static::FOO => 'My foo description', static::BAR => 'My bar description', static::BAZ => 'My baz description', ]; } } $exampleFlags = new ExampleFlagsWithNames(); $exampleFlags->addFlag(ExampleFlags::FOO | ExampleFlags::BAR | ExampleFlags::BAZ); // null will force current mask var_export($exampleFlags->getFlagNames(null, true)); /* array ( 0 => 'My foo description', 1 => 'My bar description', 2 => 'My baz description', ) */
与 Eloquent 模型一起使用示例
use Illuminate\Database\Eloquent\Model; class Test extends Model { private $flagsObject; /** * Retrieve flags * @return ExampleFlags */ public function getFlagsAttribute() { if ($this->flagsObject === null) { $this->flagsObject = new ExampleFlags( $this->attributes['flags'], // set current flags mask function (ExampleFlags $flags) { // set callback function // update the flags in this model $this->setAttribute('flags', $flags->getMask()); } ); } return $this->flagsObject; } } // retrieve object from DB $test = Test::find(1); // do binary operations on the flags class as described earlier $test->flags->checkFlag(ExampleFlag::FOO);
支持
如有bug或功能请求,请随时联系我或提交一个问题或拉取请求。或者,您可以通过给我买一杯咖啡来支持我。