採用「管理員 ↔ 欄目 ID 列表」映射模式:
admin.pres 字段CREATE TABLE `rc_admin` (
`admin_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`admin_name` VARCHAR(32) NOT NULL,
`pres` VARCHAR(512) NOT NULL DEFAULT '', -- 欄目ID列表: 1,3,5,12
PRIMARY KEY (`admin_id`),
UNIQUE KEY `uk_name` (`admin_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
<?php
// 分配頁面:admin_perm.php
$pdo = new PDO('mysql:host=localhost;dbname=study', 'root', 'root');
$pdo->exec('SET NAMES utf8');
// 獲取所有欄目(實際項目應從配置或菜單表讀取)
$modules = [
['id' => 1, 'group' => '獵頭服務', 'items' => ['添加獵頭企業','獵頭企業','獵頭職位','企業申請','獵頭申請管理']],
['id' => 6, 'group' => '懸賞招聘', 'items' => ['添加懸賞企業','管理懸賞企業','管理懸賞職位']],
];
// 處理提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$prom = $_POST['prom'] ?? [];
$pres = implode(',', array_map('intval', $prom));
$stmt = $pdo->prepare("INSERT INTO rc_admin (admin_name, pres) VALUES (?, ?)");
$stmt->execute(['admin', $pres]);
echo $stmt->rowCount() ? 'success' : 'error';
exit;
}
// 獲取當前管理員權限(編輯時回填)
$currentPres = [];
$stmt = $pdo->prepare("SELECT pres FROM rc_admin WHERE admin_name = 'admin'");
$stmt->execute();
if ($row = $stmt->fetch()) {
$currentPres = array_map('intval', explode(',', $row['pres']));
}
?>
<form method="post">
<table>
<?php foreach ($modules as $mod): ?>
<tr>
<td><strong><?= htmlspecialchars($mod['group']) ?></strong></td>
<td>
<?php foreach ($mod['items'] as $idx => $item):
$cid = $mod['id'] + $idx;
$checked = in_array($cid, $currentPres) ? 'checked' : '';
?>
<label>
<input type="checkbox" name="prom[]" value="<?= $cid ?>" <?= $checked ?>>
<?= htmlspecialchars($item) ?>
<label><br>
<?php endforeach; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<button type="submit">提交權限</button>
</form>
<?php
// auth_check.php - 每個受保護頁面頂部引入
session_start();
$pdo = new PDO('mysql:host=localhost;dbname=study', 'root', 'root');
$pdo->exec('SET NAMES utf8');
// 假設當前登錄用戶 ID 存於 $_SESSION['admin_id']
$adminId = $_SESSION['admin_id'] ?? 0;
$currentModuleId = (int)($_GET['module_id'] ?? 0); // 當前訪問的欄目 ID
if (!$adminId || !$currentModuleId) {
exit('未授權訪問');
}
$stmt = $pdo->prepare("SELECT pres FROM rc_admin WHERE admin_id = ?");
$stmt->execute([$adminId]);
$pres = $stmt->fetchColumn() ?? '';
// 權限判斷:當前欄目 ID 是否在允許列表中
$allowed = array_map('intval', explode(',', $pres));
if (!in_array($currentModuleId, $allowed)) {
exit('權限不足:無法訪問該欄目');
}
// 通過驗證,繼續執行業務邏輯
?>
<?php
// nav_render.php
$allowed = array_map('intval', explode(',', $pres));
$allModules = [ /* 同分配頁面的 $modules 結構 */ ];
foreach ($allModules as $mod) {
$groupItems = [];
foreach ($mod['items'] as $idx => $item) {
$cid = $mod['id'] + $idx;
if (in_array($cid, $allowed)) {
$groupItems[] = "<a href='?module_id=$cid'>$item</a>";
}
}
if ($groupItems) {
echo "<div class='nav-group'><h4>{$mod['group']}</h4>";
echo implode('<br>', $groupItems);
echo "</div>";
}
}
?>
| 優點 | 缺點 |
|---|---|
| 實現極簡,無需額外關係表 | 權限粒度僅到「欄目」,無法控制「增刪改查」 |
| 查詢極快(單表單字段) | 字符串存儲難以利用索引,用戶量大時性能下降 |
| 適合中小型後台項目 | 不支援角色繼承、多角色組合 |
admin_role + role_permission + permission(resource, action)簡易版適合快速交付,複雜業務建議遷移至標準 RBAC 模型。