首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 位運算權限系統:二進制交叉授權微型類實現與場景解析

     編輯:PHP 綜合知識

核心思想:位掩碼

每個權限點對應一個二進制位 (2ⁿ),用戶權限值 = 擁有權限位的 按位或 (|) 組合。判斷權限 = 用戶值 & 權限位 非零。

權限位索引 (n)二進制十進制值
add10000 00011
del20000 00102
read30000 01004
list40000 10008
mod50001 000016
detail60010 000032
pub70100 000064
collect81000 0000128

用戶擁有 add|del|read → 值 = 1|2|4 = 7。

微型類實現 (s_allow.php)

<?php
/**
 * 二進制交叉權限微型類
 * 支援:場景隔離、配置驅動、閉包批處理、陣列翻轉查找
 */
class s_allow {
    public $scene;           // 場景標識: 'access', 'cert', 'bind'
    public $caseList = [];   // 該場景所有權限定義 [位索引=>名稱]
    public $allowValue = 0;  // 用戶權限值 (位掩碼)
    public $allowList = [];  // 用戶擁有權限名稱列表

    // 配置文件解析器 (簡化版,實際可用 parse_ini_file)
    private static $configCache = [];
    private static function config(string $scene, string $key) {
        if (!isset(self::$configCache[$scene])) {
            // 模擬讀取 ini 文件
            $ini = [
                'access' => ['add','del','read','list','mod','detail','pub','collect','like','send'],
                'cert'   => ['email','tel','qq','identity_card','real_name','business_license'],
                'bind'   => ['qq','weibo','taobao','alipay','renren','weichat','baidu'],
            ];
            self::$configCache[$scene] = array_combine(range(1, count($ini[$scene])), $ini[$scene]);
        }
        return $key === 'allow' ? self::$configCache[$scene] : null;
    }

    public function __construct(string $scene, int $allowValue = 0) {
        $this->scene = $scene;
        $this->caseList = $this->caseList(true); // 獲取完整定義 [索引=>名稱]

        if ($allowValue > 0) {
            $this->allowValue = $allowValue;
            $this->allowList = $this->allowList($allowValue, true);
        }
    }

    // 獲取所有權限定義
    public function caseList(bool $full = false): array {
        $list = self::config($this->scene, 'allow');
        return $full ? $list : array_keys($list); // 全量 或 僅索引
    }

    // 從權限值解析擁有權限列表
    public function allowList(int $allowValue = 0, bool $full = false): array {
        $value = $allowValue ?: $this->allowValue;
        $buffer = [];
        foreach ($this->caseList as $idx => $name) {
            if ($value & (1 << ($idx - 1))) { // 位運算判斷
                $buffer[$idx] = $name;
            }
        }
        return $full ? $buffer : array_keys($buffer);
    }

    // 從權限名稱陣列計算權限值 (批處理 + 閉包)
    public function allowValue(array $allowList = null): int {
        $list = $allowList ?? $this->allowList;
        array_walk($list, function(&$v, $k) { $v = 1 << ($k - 1); }); // 索引轉位值
        return array_sum($list);
    }

    // 判斷是否擁有某權限
    public function isAllow(string $case): bool {
        $flipped = array_flip($this->caseList); // 名稱→索引
        $idx = $flipped[$case] ?? 0;
        return $idx > 0 && ($this->allowValue & (1 << ($idx - 1))) !== 0;
    }
}

配置文件 (permissions.ini)

[access]
1=add
2=del
3=read
4=list
5=mod
6=detail
7=pub
8=collect
9=like
10=send

[cert]
1=email
2=tel
3=qq
4=identity_card
5=real_name
6=business_license

[bind]
1=qq
2=weibo
3=taobao
4=alipay
5=renren
6=weichat
7=baidu

使用示例

<?php
require 's_allow.php';

// 1. 權限分配:用戶擁有 讀、寫、列表、發布
$access = new s_allow('access');
$userPerms = ['read', 'add', 'list', 'pub']; // 來自數據庫/配置
$userValue = $access->allowValue(array_flip($userPerms)); // 計算值:4|1|8|64 = 77
// 存入數據庫:permissions = 77

// 2. 權限驗證:從數據庫讀取值實例化
$userAccess = new s_allow('access', 77);
if ($userAccess->isAllow('add')) {
    echo "✅ 允許新增";
}
if (!$userAccess->isAllow('del')) {
    echo "❌ 禁止刪除";
}

// 3. 認證場景:用戶完成 郵箱、手機、實名 認證
$cert = new s_allow('cert', 0);
$certValue = $cert->allowValue(['email', 'tel', 'real_name']); // 1|2|5 = 1|2|16 = 19

// 4. 第三方綁定:用戶綁定 QQ、微信、支付寶
$bind = new s_allow('bind', 0);
$bindValue = $bind->allowValue(['qq', 'wechat', 'alipay']); // 1|6|4 = 1|32|8 = 41

// 5. 批量檢查 (陣列翻轉 O(1) 查找)
$required = ['read', 'mod', 'pub'];
foreach ($required as $perm) {
    echo $perm . ': ' . ($userAccess->isAllow($perm) ? 'YES' : 'NO') . "\n";
}

進階:多場景組合權限 (位段劃分)

<?php
class MultiScopeAuth {
    // 位段分配:每場景佔 16 位 (支援 65535 個權限點)
    const SHIFT = 16;
    const MASK  = 0xFFFF;

    public static function encode(array $scopes): int {
        $value = 0;
        foreach ($scopes as $scene => $permValue) {
            $value |= ($permValue & self::MASK) << ($scene * self::SHIFT);
        }
        return $value;
    }

    public static function decode(int $value, string $scene): int {
        return ($value >> ($scene * self::SHIFT)) & self::MASK;
    }
}

// 使用:將 access(16位) + cert(16位) + bind(16位) 合並為單一 48 位整數
$combined = MultiScopeAuth::encode([
    0 => 77,  // access
    1 => 19,  // cert
    2 => 41,  // bind
]);
// 存入單一字段:auth_bitmap = 18014398509481984... (大整數)
// 讀取時:
$accessVal = MultiScopeAuth::decode($combined, 0); // 77

優缺點與適用邊界

優點缺點適用場景
極致緊湊:單整數存 64 權限權限點超過 64 需大整數/多字段RBAC 核心權限、功能開關、功能授權
判斷極快:單次位運算不可直接表達「否決/排除」邏輯高頻檢查 (中間件、模板渲染)
組合靈活:位或/位與/位異或業務語義不直觀,需文檔/常量維護多租戶功能開關、會員等級特權
無連表查詢:權限值隨用戶行存儲權限變更需更新所有用戶值靜態權限結構、低頻變更

現代替代:Caser / Laravel Permission

  • spatie/laravel-permission:角色-權限關係表、緩存、指令、Blade 指令
  • caser:基於屬性的權限、上下文感知、策略類
  • 位運算方案適合輕量級、無框架、極致性能、權限結構固定的微服務/中間件/嵌入式場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved