PHP连接MySQL数据库实现用户登录功能详解**
在Web开发中,用户登录功能是最基础也是最常见的需求之一,PHP作为一种流行的服务器端脚本语言,搭配MySQL数据库,可以高效地实现这一功能,本文将详细介绍如何使用PHP连接MySQL数据库,并逐步构建一个简单但安全的用户登录系统。
准备工作
在开始之前,请确保你已经具备以下环境:
- PHP环境:已安装并配置好PHP(如XAMPP、WAMP、MAMP等集成环境,或单独安装的PHP)。
- MySQL数据库:已安装并运行MySQL服务,并且有可以操作的数据库。
- Web服务器:如Apache(通常集成在XAMPP/WAMP中)。
创建数据库和用户表
我们需要在MySQL数据库中创建一个用于存储用户信息的表。
- 登录到MySQL(可以通过命令行或phpMyAdmin等工具)。
- 创建一个数据库,
test_db
:CREATE DATABASE test_db;
- 选择该数据库:
USE test_db;
- 创建一个用户表,
users
,包含id
,username
,password
等字段:CREATE TABLE users ( id INT(11) AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
- 注意:为了安全,
password
字段我们使用VARCHAR(255)
,因为后续我们会存储哈希后的密码,而不是明文。
- 注意:为了安全,
- 向表中插入一个测试用户(重要:密码请先使用哈希函数处理,如
password_hash()
):-- 假设我们要插入的用户名是 "admin",密码是 "123456" -- 在PHP中,我们可以用 password_hash('123456', PASSWORD_DEFAULT) 来生成哈希值 -- 这里假设生成的哈希值是 $2y$10$abcdef1234567890abcdef1234567890abcdef1234567890 INSERT INTO users (username, password) VALUES ('admin', '$2y$10$abcdef1234567890abcdef1234567890abcdef1234567890');
实际开发中,哈希操作应该在PHP代码中进行,而不是直接在SQL里写死。
PHP连接MySQL数据库
PHP连接MySQL数据库有多种方式,推荐使用 PDO (PHP Data Objects),因为它支持多种数据库类型,且更安全、更灵活。
使用PDO连接MySQL
以下是一个使用PDO连接MySQL数据库的示例代码 (db_connect.php
):
<?php // 数据库配置信息 $db_host = 'localhost'; // 或 '127.0.0.1' $db_name = 'test_db'; $db_user = 'root'; // 你的MySQL用户名 $db_pass = ''; // 你的MySQL密码 try { // 创建PDO实例 $pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass); // 设置PDO错误模式为异常 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // echo "数据库连接成功!"; // 可以取消注释测试连接是否成功 } catch (PDOException $e) { // 如果连接失败,捕获异常并输出错误信息 // 在实际生产环境中,不应该直接显示详细的错误信息,而是记录日志 die("数据库连接失败: " . $e->getMessage()); } ?>
代码解释:
mysql:host=$db_host;dbname=$db_name;charset=utf8mb4
:这是DSN(Data Source Name),指定了数据库类型、主机名、数据库名和字符集(推荐使用utf8mb4
以支持更广泛的字符,包括emoji)。$db_user
和$db_pass
:分别是MySQL数据库的用户名和密码。new PDO()
:创建PDO对象,尝试连接数据库。setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
:设置PDO在发生错误时抛出异常,便于错误处理。catch (PDOException $e)
:捕获连接过程中可能抛出的异常,并处理错误。
创建登录页面和处理逻辑
登录页面 (login.html
或 login.php
)
这是一个简单的登录表单页面:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0">用户登录</title> <style> body { font-family: Arial, sans-serif; background-color: #f4f4f4; } .login-container { max-width: 400px; margin: 100px auto; padding: 20px; background-color: #fff; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } h2 { text-align: center; } .form-group { margin-bottom: 15px; } label { display: block; margin-bottom: 5px; } input[type="text"], input[type="password"] { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; } input[type="submit"] { width: 100%; padding: 10px; background-color: #5cb85c; color: white; border: none; border-radius: 4px; cursor: pointer; } input[type="submit"]:hover { background-color: #4cae4c; } .error { color: red; text-align: center; margin-bottom: 10px; } </style> </head> <body> <div class="login-container"> <h2>用户登录</h2> <?php // 如果有错误信息,显示出来 if (isset($_GET['error'])) { echo '<div class="error">' . htmlspecialchars($_GET['error']) . '</div>'; } ?> <form action="login_process.php" method="post"> <div class="form-group"> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> </div> <div class="form-group"> <label for="password">密码:</label> <input type="password" id="password" name="password" required> </div> <div class="form-group"> <input type="submit" value="登录"> </div> </form> </div> </body> </html>
登录处理逻辑 (login_process.php
)
这个页面负责接收登录表单提交的数据,验证用户名和密码。
<?php // 开启会话(用于后续存储用户信息) session_start(); // 引入数据库连接文件 require_once 'db_connect.php'; // 检查请求方法是否为POST if ($_SERVER["REQUEST_METHOD"] == "POST") { // 获取并过滤用户输入 $username = trim($_POST['username']); $password = $_POST['password']; // 密码不需要trim,因为前后空格可能是用户故意输入的 if (empty($username) || empty($password)) { // 如果用户名或密码为空,跳转回登录页面并提示错误 header("Location: login.php?error=用户名和密码不能为空"); exit(); } try { // 准备SQL查询语句,使用预处理语句防止SQL注入 $sql = "SELECT id, username, password FROM users WHERE username = :username"; $stmt = $pdo->prepare($sql); // 绑定参数 $stmt->bindParam(':username', $username, PDO::PARAM_STR); // 执行查询 $stmt->execute(); // 获取查询结果 $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user && password_verify($password, $user['password'])) { // 密码验证成功,登录成功 // 将用户信息存储到会话中 $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; // 重定向到用户主页或仪表盘 header("Location: welcome.php"); exit(); } else { // 用户名不存在或密码错误 header("Location: login.php?error=用户名或密码错误"); exit(); } } catch (PDOException $e) { // 查询出错 die("查询失败: " . $e->getMessage()); } } else { // 如果不是POST请求,直接
还没有评论,来说两句吧...