framjet / enum-bitmask
一个小型库,为 PHP 8.1 枚举提供作为位掩码标志的功能
1.0.0
2021-12-28 17:48 UTC
Requires
- php: ~8.1.0
Requires (Dev)
- framjet/coding-standard: ^1.0
- phpunit/phpunit: ^9.5.10
- psalm/plugin-phpunit: ^0.16.1
- roave/infection-static-analysis-plugin: ^1.12
- squizlabs/php_codesniffer: ^3.6.2
- vimeo/psalm: ^4.15.0
README
一个小型库,为 PHP 8.1 枚举提供作为位掩码标志的功能。
为什么?
有时你需要在对象上添加一些标志来表示一些功能,通常使用类型为 bool
的简单属性,但随后你开始添加多个属性,然后你的对象大小(序列化/JSON)开始大幅增加。
位掩码值一直是标志的高效存储选项。它在一个 int32
值内提供多达 32 个独特的标志。
另一个大优点是可以在一个调用中执行 AND
、OR
、NOT
操作,而不是通过多个 if 表达式来检查所有这些属性值。
安装
通过 Composer
$ composer require framjet/enum-bitmask
用法
该库提供了一个特性 BitmaskFunctionality
,它需要包含在整数支持的枚举中。
以下是一个使用 Enum
通过空间高效的位掩码整数值提供标志的简单示例
<?php use FramJet\Packages\EnumBitmask\BitmaskFunctionality; enum Flag: int { use BitmaskFunctionality; case Public = 0b000001; case Protected = 0b000010; case Private = 0b000100; case ReadOnly = 0b001000; case Static = 0b010000; case Final = 0b100000; } class Member { public function __construct(private int $flags = 0) { } public function setPublic(): void { $this->flags = Flag::set( Flag::clear($this->flags, Flag::Private, Flag::Protected), Flag::Public ); } public function isPublic(): bool { return Flag::on($this->flags, Flag::Public); } public function isReadOnly(): bool { return Flag::on($this->flags, Flag::ReadOnly); } /** @return list<Flag> */ public function getFlags(): array { return Flag::parse($this->flags); } public function getFlagsValue(): int { return $this->flags; } } class Container { /** @param list<Member> $members */ public function __construct(private array $members = []) { } public function addMember(Member $member): void { $this->members[] = $member; } public function getMembers(Flag ...$flags): array { return array_filter($this->members, static fn(Member $m) => Flag::any($m->getFlagsValue(), ...$flags)); } } $memberPublic = new Member(); $memberPublic->setPublic(); $memberPublic->getFlags(); // [Flag::Public] $memberReadOnly = new Member(Flag::build(Flag::ReadOnly)); $memberReadOnly->isReadOnly(); // true $memberReadOnly->isPublic(); // false $memberPrivate = new Member(Flag::build(Flag::Private, Flag::ReadOnly)); $memberPrivate->isReadOnly(); // true $memberPrivate->isPublic(); // false $memberPrivate->getFlags(); // [Flag::Private, Flag::ReadOnly] array_map( static fn(Flag $f) => $f->toString(), $memberPrivate->getFlags() ); // ['0b0000_0000_0000_0000_0000_0000_0000_0100', '0b0000_0000_0000_0000_0000_0000_0000_1000'] $container = new Container(); $container->addMember($memberPublic); $container->addMember($memberReadOnly); $container->addMember($memberPrivate); $container->getMembers(); // [$memberPublic, $memberReadOnly, $memberPrivate] $container->getMembers(Flag::Public); // [$memberPublic] $container->getMembers(Flag::ReadOnly); // [$memberReadOnly, $memberPrivate] $container->getMembers(Flag::ReadOnly, Flag::Public); // [$memberPublic, $memberReadOnly, $memberPrivate]
许可证
有关更多信息,请参阅许可证文件。