PHP如何实现登录并分配数据库:从基础到实践的完整指南
在Web应用开发中,用户登录是核心功能之一,而根据用户角色或权限动态分配数据库访问权限,则是保障系统安全性和灵活性的关键,本文将详细介绍如何使用PHP实现用户登录功能,并在登录成功后根据用户角色动态分配对应的数据库连接,确保不同用户只能访问其权限范围内的数据。
核心设计思路
要实现“登录分配数据库”的功能,核心逻辑分为三个步骤:
- 用户认证:验证用户提交的登录信息(如用户名、密码)是否正确;
- 角色获取:从用户表中获取当前用户的角色(如管理员、普通用户、访客等);
- 动态分配数据库:根据用户角色,创建对应的数据库连接对象或配置,后续操作均使用该连接。
这一流程的关键在于数据库连接的动态管理,避免所有用户共用一个数据库连接导致权限混乱。
准备工作:数据库与用户表设计
创建数据库与用户表
假设我们需要管理两个数据库:db_admin
(管理员专用)和db_user
(普通用户专用),首先创建这两个数据库,并在各自的数据库中创建用户表(以MySQL为例):
-- 创建管理员数据库 CREATE DATABASE db_admin; USE db_admin; -- 管理员用户表 CREATE TABLE admin_users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, role VARCHAR(20) NOT NULL DEFAULT 'admin' ); -- 插入测试数据(密码需使用password_hash加密) INSERT INTO admin_users (username, password, role) VALUES ('admin', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'admin');
-- 创建普通用户数据库 CREATE DATABASE db_user; USE db_user; -- 普通用户表 CREATE TABLE normal_users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, role VARCHAR(20) NOT NULL DEFAULT 'user' ); -- 插入测试数据 INSERT INTO normal_users (username, password, role) VALUES ('user1', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'user');
数据库用户权限配置
为确保安全性,需要为每个数据库创建独立的MySQL用户,并限制其权限:
-- 创建管理员数据库用户(仅允许访问db_admin) CREATE USER 'admin_user'@'localhost' IDENTIFIED BY 'admin_password'; GRANT ALL PRIVILEGES ON db_admin.* TO 'admin_user'@'localhost'; -- 创建普通用户数据库用户(仅允许访问db_user) CREATE USER 'normal_user'@'localhost' IDENTIFIED BY 'user_password'; GRANT ALL PRIVILEGES ON db_user.* TO 'normal_user'@'localhost'; -- 刷新权限 FLUSH PRIVILEGES;
注意:密码需替换为强密码,且根据环境调整主机名(如允许任意主机连接,生产环境建议限制为
localhost
或特定IP)。
PHP实现步骤
数据库连接配置(动态化)
将不同数据库的连接信息存储在配置文件中,方便后续动态调用,创建config.php
:
<?php // 数据库配置信息 $db_configs = [ 'admin' => [ 'host' => 'localhost', 'username' => 'admin_user', 'password' => 'admin_password', 'database' => 'db_admin', 'charset' => 'utf8mb4' ], 'user' => [ 'host' => 'localhost', 'username' => 'normal_user', 'password' => 'user_password', 'database' => 'db_user', 'charset' => 'utf8mb4' ] ]; // 全局变量存储当前数据库连接 $current_db_connection = null; ?>
用户登录验证
创建login.php
,实现用户登录逻辑,并根据用户角色分配数据库连接:
<?php require_once 'config.php'; session_start(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; // 先尝试从管理员数据库验证 try { $admin_conn = new PDO( "mysql:host={$db_configs['admin']['host']};dbname={$db_configs['admin']['database']};charset={$db_configs['admin']['charset']}", $db_configs['admin']['username'], $db_configs['admin']['password'] ); $admin_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $admin_conn->prepare("SELECT * FROM admin_users WHERE username = :username"); $stmt->bindParam(':username', $username); $stmt->execute(); $admin_user = $stmt->fetch(PDO::FETCH_ASSOC); if ($admin_user && password_verify($password, $admin_user['password'])) { // 登录成功,分配管理员数据库连接 $_SESSION['user_role'] = 'admin'; $_SESSION['db_connection'] = $admin_conn; $_SESSION['username'] = $username; header('Location: dashboard.php'); exit; } } catch (PDOException $e) { echo "管理员数据库连接失败: " . $e->getMessage(); } // 管理员验证失败,尝试普通用户数据库验证 try { $user_conn = new PDO( "mysql:host={$db_configs['user']['host']};dbname={$db_configs['user']['database']};charset={$db_configs['user']['charset']}", $db_configs['user']['username'], $db_configs['user']['password'] ); $user_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $user_conn->prepare("SELECT * FROM normal_users WHERE username = :username"); $stmt->bindParam(':username', $username); $stmt->execute(); $normal_user = $stmt->fetch(PDO::FETCH_ASSOC); if ($normal_user && password_verify($password, $normal_user['password'])) { // 登录成功,分配普通用户数据库连接 $_SESSION['user_role'] = 'user'; $_SESSION['db_connection'] = $user_conn; $_SESSION['username'] = $username; header('Location: dashboard.php'); exit; } } catch (PDOException $e) { echo "普通用户数据库连接失败: " . $e->getMessage(); } // 所有验证均失败 $error = "用户名或密码错误"; } ?> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8">用户登录</title> </head> <body> <h2>登录系统</h2> <?php if (isset($error)): ?> <p style="color: red;"><?php echo $error; ?></p> <?php endif; ?> <form method="POST"> <div> <label>用户名: <input type="text" name="username" required></label> </div> <div> <label>密码: <input type="password" name="password" required></label> </div> <button type="submit">登录</button> </form> </body> </html>
动态数据库连接的使用
登录成功后,用户会跳转到dashboard.php
,此时通过$_SESSION
获取当前用户的数据库连接,并执行相应的数据库操作:
<?php session_start(); // 检查用户是否登录 if (!isset($_SESSION['user_role']) || !isset($_SESSION['db_connection'])) { header('Location: login.php'); exit; } $username = $_SESSION['username']; $role = $_SESSION['user_role']; $db_connection = $_SESSION['db_connection']; // 获取动态分配的数据库连接 // 根据角色执行不同的数据库操作 try { $stmt = $db_connection->prepare("SELECT * FROM users WHERE username = :username"); $stmt->bindParam(':username', $username); $stmt->execute(); $user_data = $stmt->fetch(PDO::FETCH_ASSOC); echo "<h2>欢迎, " . htmlspecialchars($username) . "!</h2>"; echo "<p>您的角色: " . htmlspecialchars($role) . "</p>"; echo "<p>用户ID: " . htmlspecialchars($user_data['id']) . "</p>"; echo "<p>当前数据库: " . $db_connection->query("SELECT DATABASE()")->fetchColumn() . "</p>"; // 管理员可查看所有用户(示例),普通用户只能查看自己 if ($role === 'admin') { echo "<h3>所有用户列表
还没有评论,来说两句吧...