user/group right

本文探讨了两种不同的用户权限理解方式:一种认为用户权限是对组权限的补充;另一种则将其视为组权限的一种特殊情况。当用户权限与组权限发生冲突时,前者优先。

用户right:两种理解方式,无所谓正确错误。

1)用户权限是组权限的补充。

组权限包含, 用户单独赋给另外权限。用户和组权限并列。

2)用户权限是组权限的特例

组权限包含,用户权限特有权限,如果用户和组冲突,以用户权限优先。


第一种:

组权限有3个right,如果用户权限只需要2个,完全可以单独创建另外一个组(2个)或者单独给用户赋权限,没有必要放到这个组权限中(3个)

要实现一个**可交互的数据库连接配置界面**,让用户在安装过程中输入 `host`、`username`、`password`、`dbname` 等信息,并自动写入 `config/db.php` 文件,我们需要: 1. 提供一个表单供用户填写数据库连接参数 2. 测试连接是否成功 3. 动态生成 `db.php` 配置文件 4. 安全地保存配置(避免敏感信息暴露) --- ## ✅ 最终目标 允许用户通过浏览器访问 `install.php` 时: - 输入自己的数据库连接信息 - 点击“测试连接”或“下一步” - 系统尝试连接 MySQL - 成功后将配置写入 `config/db.php` - 继续后续安装流程(如导入 SQL 结构) --- ### 📄 完整代码:支持数据库配置的安装向导 ```php <?php // install.php - 支持用户自定义数据库配置的安装向导 session_start(); // 检查是否已安装(通过锁文件) if (file_exists('config/installed.lock')) { die('<h3 style="color:red;">⚠️ 系统已安装完毕!请删除 install.php 文件以确保安全。</h3>'); } $step = $_GET['step'] ?? 'form'; // 步骤:form => test => install $message = ''; $host = $username = $password = $dbname = $group_name = $admin_user = $admin_pass = ''; // 如果是 POST 请求,接收数据 if ($_POST) { $host = trim($_POST['db_host'] ?? 'localhost'); $username = trim($_POST['db_username']); $password = $_POST['db_password']; $dbname = trim($_POST['db_name'] ?? 'leave_db'); $group_name = trim($_POST['group_name'] ?? '中国XX集团'); $admin_user = trim($_POST['admin_username'] ?? 'admin'); $admin_pass = $_POST['admin_password']; $confirm_pass = $_POST['confirm_password']; // 保留数据用于回显 $_SESSION['setup_data'] = compact('host', 'username', 'password', 'dbname', 'group_name', 'admin_user', 'admin_pass'); } ?> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>系统安装向导</title> <style> body { font-family: 'Segoe UI', sans-serif; padding: 40px; background: #f0f2f5; } .container { max-width: 700px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } h2 { color: #007cba; border-bottom: 2px solid #eee; padding-bottom: 10px; } label { display: block; margin-top: 15px; font-weight: bold; color: #333; } input[type="text"], input[type="password"] { width: 100%; padding: 10px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; font-size: 16px; } button { margin-top: 20px; padding: 12px 24px; background: #007cba; color: white; border: none; cursor: pointer; font-size: 16px; border-radius: 4px; } button:hover { background: #005a87; } .error { color: red; margin: 15px 0; } .success { color: green; margin: 15px 0; } pre { background: #f5f5f5; padding: 10px; border: 1px solid #ddd; border-radius: 4px; overflow-x: auto; } .tab { margin-top: 20px; } .tab button { margin-right: 10px; background: #e0e0e0; color: #333; } .tab button.active { background: #007cba; color: white; } </style> </head> <body> <div class="container"> <h2>🔧 单位管理系统 - 安装向导</h2> <?php if ($step === 'form'): ?> <p>请填写数据库连接信息:</p> <form method="post" action="?step=test"> <label>数据库主机:</label> <input type="text" name="db_host" value="<?= htmlspecialchars($host ?: 'localhost') ?>" required> <label>用户名:</label> <input type="text" name="db_username" value="<?= htmlspecialchars($username) ?>" required> <label>密码:</label> <input type="password" name="db_password" value="<?= htmlspecialchars($password) ?>"> <label>数据库名:</label> <input type="text" name="db_name" value="<?= htmlspecialchars($dbname ?: 'leave_db') ?>" required> <h3>📌 初始数据设置</h3> <label>集团名称:</label> <input type="text" name="group_name" value="<?= htmlspecialchars($group_name ?: '中国XX集团') ?>"> <label>管理员账号:</label> <input type="text" name="admin_username" value="<?= htmlspecialchars($admin_user ?: 'admin') ?>" required> <label>管理员密码:</label> <input type="password" name="admin_password" required> <label>确认密码:</label> <input type="password" name="confirm_password" required> <button type="submit">→ 测试数据库连接</button> </form> <?php endif; ?> <?php if ($step === 'test'): ?> <?php // 接收并验证数据 $host = $_POST['db_host'] ?? 'localhost'; $username = $_POST['db_username'] ?? ''; $password = $_POST['db_password'] ?? ''; $dbname = $_POST['db_name'] ?? 'leave_db'; $group_name = $_POST['group_name'] ?? '中国XX集团'; $admin_user = $_POST['admin_username'] ?? 'admin'; $admin_pass = $_POST['admin_password'] ?? ''; $confirm_pass = $_POST['confirm_password'] ?? ''; if (empty($username)) { $message = "数据库用户名不能为空。"; } elseif ($admin_pass !== $confirm_pass) { $message = "两次管理员密码不一致!"; } elseif (strlen($admin_pass) < 6) { $message = "管理员密码不能少于6位。"; } else { try { // 尝试连接数据库 $pdo = new PDO("mysql:host=$host;charset=utf8mb4", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 检查数据库是否存在,不存在则创建 $pdo->exec("CREATE DATABASE IF NOT EXISTS `$dbname` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"); $pdo->exec("USE `$dbname`;"); // 保存配置到 session $_SESSION['db_config'] = [ 'host' => $host, 'username' => $username, 'password' => $password, 'dbname' => $dbname, 'group_name' => $group_name, 'admin_user' => $admin_user, 'admin_pass' => $admin_pass, ]; echo "<div class='success'>✅ 数据库连接成功!</div>"; echo "<p>准备初始化数据结构...</p>"; echo "<form method='post' action='?step=install'>"; foreach ($_POST as $k => $v) { if ($k !== 'confirm_password') { echo "<input type='hidden' name='" . htmlspecialchars($k) . "' value='" . htmlspecialchars($v) . "'>"; } } echo "<button type='submit'>→ 开始安装系统</button></form>"; goto end; } catch (PDOException $e) { $message = "数据库连接失败:" . $e->getMessage(); } } ?> <p class="error"><?= htmlspecialchars($message) ?></p> <a href="?step=form"><button>← 返回修改</button></a> <?php endif; ?> <?php if ($step === 'install'): ?> <?php // 获取之前提交的数据 $host = $_POST['db_host'] ?? 'localhost'; $username = $_POST['db_username']; $password = $_POST['db_password']; $dbname = $_POST['db_name']; $group_name = $_POST['group_name']; $admin_user = $_POST['admin_username']; $admin_pass = $_POST['admin_password']; // 1. 生成 db.php 配置文件 $configContent = <<<PHP <?php // config/db.php - 自动生成于 " . date('Y-m-d H:i:s') . " \$host = '$host'; \$dbname = '$dbname'; \$username = '$username'; \$password = '$password'; try { \$pdo = new PDO("mysql:host=\$host;dbname=\$dbname;charset=utf8mb4", \$username, \$password); \$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException \$e) { die("数据库连接失败: " . \$e->getMessage()); } ?> PHP; // 写入配置文件 \$written = file_put_contents('config/db.php', \$configContent); if (!\$written) { \$message = "❌ 无法写入 config/db.php,请检查目录权限(需要可写)"; } else { // 重新包含刚刚写入的配置 require_once 'config/db.php'; // 初始化数据库结构(简化版,你也可以读取 sql/leave_db.sql) try { initDatabase(\$pdo, \$admin_user, \$admin_pass, \$group_name, \$dbname); // 创建安装完成标记 file_put_contents('config/installed.lock', time()); echo "<div class='success'> <h3>🎉 安装成功!</h3> <p>系统数据库和管理员账户已创建。</p> <p><strong>登录账号:</strong> $admin_user</p> <p><strong>登录密码:</strong> 已设置(请妥善保管)</p> <a href='auth/login.php'><button>➡️ 前往登录页</button></a> </div>"; // 安全提醒 echo "<p style='color:#999;font-size:14px;margin-top:20px;'> ⚠️ 为安全起见,请立即删除 <code>install.php</code> 文件。 </p>"; goto end; } catch (Exception \$e) { \$message = "初始化数据失败:" . \$e->getMessage(); } } ?> <p class="error"><?= htmlspecialchars(\$message) ?></p> <a href="?step=form"><button>← 返回重试</button></a> <?php endif; ?> <?php end: ?> </div> <?php // 辅助函数:初始化数据库表结构和初始数据 function initDatabase(\$pdo, \$adminUser, \$adminPass, \$groupName, \$groupCode = 'GROUP') { \$hashedPass = password_hash(\$adminPass, PASSWORD_DEFAULT); \$pdo->exec("DROP TABLE IF EXISTS organizations, accounts, approval_flows, home_stay_records"); \$pdo->exec("CREATE TABLE organizations ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, code VARCHAR(50) UNIQUE NOT NULL, level TINYINT NOT NULL CHECK (level BETWEEN 1 AND 5), parent_id INT NULL, path VARCHAR(255) NOT NULL DEFAULT '', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (parent_id) REFERENCES organizations(id) ON DELETE CASCADE, INDEX idx_path (path) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); \$pdo->exec("CREATE TABLE accounts ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, real_name VARCHAR(50) NOT NULL, org_id INT NOT NULL, role ENUM('super_admin','dept_admin','approver_l1','approver_l2','approver_l3') DEFAULT 'dept_admin', status ENUM('active','disabled') DEFAULT 'active', last_login_at TIMESTAMP NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (org_id) REFERENCES organizations(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); \$pdo->exec("CREATE TABLE approval_flows ( id INT AUTO_INCREMENT PRIMARY KEY, org_id INT NOT NULL, flow_type ENUM('leave','home_stay') NOT NULL, levels TINYINT NOT NULL DEFAULT 2, approver_l1_org_id INT NULL, approver_l2_org_id INT NULL, approver_l3_org_id INT NULL, FOREIGN KEY (org_id) REFERENCES organizations(id), UNIQUE(org_id, flow_type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); \$pdo->exec("CREATE TABLE home_stay_records ( id INT AUTO_INCREMENT PRIMARY KEY, employee_name VARCHAR(50) NOT NULL, employee_id_card VARCHAR(18) NULL, org_id INT NOT NULL, start_date DATE NOT NULL, end_date DATE NOT NULL, total_days INT AS (DATEDIFF(end_date, start_date)+1) STORED, reason TEXT, submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, status ENUM('pending','approved','rejected') DEFAULT 'pending', approver_notes TEXT, approved_by INT NULL, approved_at TIMESTAMP NULL, FOREIGN KEY (org_id) REFERENCES organizations(id), FOREIGN KEY (approved_by) REFERENCES accounts(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); // 插入组织结构 \$pdo->exec("INSERT INTO organizations (name, code, level, parent_id, path) VALUES ('$groupName', '$groupCode', 1, NULL, '$groupCode'), ('华东分公司', 'EAST_CHINA', 2, 1, '$groupCode/EAST_CHINA'), ('人力资源部', 'HR', 3, 2, '$groupCode/EAST_CHINA/HR'), ('招聘科', 'RECRUIT', 4, 3, '$groupCode/EAST_CHINA/HR/RECRUIT'), ('一线岗位A', 'POST_A', 5, 4, '$groupCode/EAST_CHINA/HR/RECRUIT/POST_A')"); // 插入超级管理员 \$pdo->exec("INSERT INTO accounts (username, password, real_name, org_id, role) VALUES ('$adminUser', '$hashedPass', '系统管理员', 1, 'super_admin')"); // 设置审批流 \$pdo->exec("INSERT INTO approval_flows (org_id, flow_type, levels, approver_l1_org_id, approver_l2_org_id, approver_l3_org_id) VALUES (3, 'leave', 3, 4, 2, 1), (3, 'home_stay', 2, 4, 2, NULL)"); } ?> ``` --- ## ✅ 使用说明 ### 目录结构要求 ``` your-project/ ├── config/ │ └── db.php # 自动生成 │ └── installed.lock # 安装完成后生成 ├── sql/ │ └── leave_db.sql # 可选:更复杂的SQL脚本 ├── auth/ │ └── login.php ├── install.php # 本文件 └── ... ``` ### 权限要求 确保 `config/` 目录对 Web 服务器可写: ```bash chmod 755 config/ # 或 Linux 上: sudo chown www-data:www-data config/ -R ``` --- ## 🔐 安全建议 | 措施 | 说明 | |------|------| | ✅ 删除 `install.php` | 安装完成后必须删除,防止被他人重置系统 | | ✅ 锁文件保护 | `installed.lock` 防止重复安装 | | ✅ 密码加密存储 | 使用 `password_hash()` | | ✅ 防 XSS 输出 | 所有用户输入用 `htmlspecialchars()` 转义 | | ✅ 不暴露异常细节 | 生产环境关闭错误显示 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值