MySQL 是开源关系型数据库管理系统,使用SQL完成数据管理;PHP是主流的服务器端脚本语言,非常适合Web网站开发。将PHP与MySQL结合,可以快速开发动态、数据驱动的Web应用。
在PHP中操作MySQL主要有两套扩展:mysqli(增强版MySQL扩展) 和 PDO(PHP数据对象)。mysqli只针对MySQL数据库;PDO是数据库抽象层,支持MySQL、PostgreSQL等多种数据库,可做到一套代码适配不同数据库。不推荐使用已经废弃的mysql原始扩展。
PHP 连接 MySQL,可参见:PHP 连接 MySQ
本教程使用到的 Websites 表 SQL 文件:websites.sql。
一、数据库连接
1. mysqli 面向对象方式连接
mysqli 分为面向对象与面向过程两种写法,推荐面向对象风格。
<?php $servername = "localhost"; // 数据库服务地址 $username = "username"; // 数据库账号 $password = "password"; // 数据库密码 $dbname = "database_name"; // 要使用的数据库名// 创建连接实例
$conn = new mysqli($servername, $username, $password, $dbname);// 判断连接是否失败
if ($conn->connect_error) {
die("连接失败:" . $conn->connect_error);
}
echo "数据库连接成功";
?>
2. PDO 方式连接MySQL
PDO采用异常机制捕获错误,便于统一处理数据库异常。
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "database_name";try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8mb4", $username, $password);
// 设置错误模式为抛出异常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "数据库连接成功";
} catch(PDOException $e) {
echo "连接失败:" . $e->getMessage();
}
?>
小提示:连接时指定
charset=utf8mb4,完整支持中文与Emoji表情,避免乱码。
二、执行SQL实现增删改查
2.1 查询数据
mysqli 查询示例
<?php $sql = "SELECT id, name, email FROM users"; $result = $conn->query($sql);if ($result->num_rows > 0) {
// 循环读取关联数组结果
while($row = $result->fetch_assoc()) {
echo "id:{$row['id']},姓名:{$row['name']},邮箱:{$row['email']}<br>";
}
} else {
echo "没有查询到数据";
}
?>
PDO 查询示例
<?php $stmt = $conn->prepare("SELECT id, name, email FROM users"); $stmt->execute(); // 获取全部结果集,返回关联数组 $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);foreach ($rows as $row) {
echo "id:{$row['id']},姓名:{$row['name']},邮箱:{$row['email']}<br>";
}
?>
2.2 插入数据
⚠️ 直接拼接字符串SQL会产生SQL注入漏洞,业务开发必须使用预处理语句prepare。
mysqli 普通插入(不推荐直接拼接)
<?php
$sql = "INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com')";
if ($conn->query($sql) === true) {
echo "新记录插入成功";
} else {
echo "错误:{$sql}<br>{$conn->error}";
}
?>
PDO 预处理插入(安全推荐)
使用命名占位符,分离SQL结构与数据,防御SQL注入。
<?php $stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (:name, :email)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':email', $email);$name = "John Doe";
$email = "john@example.com";
$stmt->execute();
echo "插入成功";
?>
2.3 更新、删除操作
核心逻辑与插入一致,生产环境必须使用预处理语句,并且带上where条件,防止全表更新/删除。
三、SQL注入与安全开发
SQL注入是PHP+MySQL开发中最高危的安全漏洞,攻击者通过输入特殊字符篡改SQL语句。
防御手段
- 强制使用预处理语句prepare + bindParam/bind_param,不要把用户输入直接拼接到SQL字符串;
- 校验、过滤表单、GET/POST传来的用户输入;
- 数据库账号遵循最小权限原则,业务账号不授予drop、alter等高风险权限;
- 密码不要明文存储,使用
password_hash()做密码哈希,登录使用password_verify()校验; - 生产环境关闭PHP错误回显,不要把数据库错误信息输出给客户端;
- 定期备份MySQL数据库。
四、关闭数据库连接
数据库操作完成之后需要关闭连接释放服务端资源。
mysqli关闭连接
$conn->close();
PDO关闭连接
PDO没有专门close函数,将连接变量置为null即可断开:
$conn = null;
五、综合实战案例
案例1:用户注册(mysqli预处理)
接收表单POST提交,密码哈希存储,使用预处理防止注入。
<?php $conn = new mysqli("localhost","username","password","user_db"); if ($conn->connect_error) { die("连接失败:".$conn->connect_error); }// 判断是否为POST表单提交
if($_SERVER["REQUEST_METHOD"] === "POST"){
$username = $_POST['username'];
$email = $_POST['email'];
// 密码单向哈希,不保存明文
$pwdHash = password_hash($_POST['password'], PASSWORD_DEFAULT); // 预处理语句,?为占位符,sss代表三个字符串类型参数 $stmt = $conn->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $username, $email, $pwdHash); if ($stmt->execute()){ echo "注册成功!"; }else{ echo "注册失败:".$stmt->error; } $stmt->close();}
$conn->close();
?>
案例2:用户登录(mysqli预处理)
开启session,查询账号,使用password_verify校验密码哈希。
<?php session_start(); $conn = new mysqli("localhost","username","password","user_db"); if ($conn->connect_error) { die("连接失败:".$conn->connect_error); }if($_SERVER["REQUEST_METHOD"] === "POST"){
$username = $_POST['username'];
$password = $_POST['password']; $stmt = $conn->prepare("SELECT id, username, password FROM users WHERE username = ?"); $stmt->bind_param("s",$username); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows === 1){ $user = $result->fetch_assoc(); // 校验密码哈希 if(password_verify($password, $user['password'])){ $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; header("Location: dashboard.php"); exit; }else{ echo "密码错误"; } }else{ echo "该用户不存在"; } $stmt->close();}
$conn->close();
?>
六、mysqli与PDO对比总结
| 特性 | mysqli | PDO |
|---|---|---|
| 支持数据库 | 仅MySQL | 多种数据库(MySQL、Oracle等) |
| 编码风格 | 面向对象 / 面向过程 | 面向对象,异常处理 |
| 预处理 | 支持 | 支持,语法更简洁 |
| 可移植性 | 差,只适配MySQL | 优秀,切换数据库改动小 |
开发建议:项目如果未来可能更换数据库,优先选择PDO;只使用MySQL,mysqli也可以满足需求,无论选择哪一种,业务代码必须使用预处理语句。
0 条笔记