当前位置: 首页 > news >正文

PHP 与 MySQL 详解实战入门(2)

PHP 与 MySQL 详解实战入门(2)


前言

在 Web 开发中,PHP 与 MySQL 的组合一直是构建动态数据驱动应用的核心技术栈。从用户信息的存储到商品数据的展示,从内容的更新到过期记录的清理,几乎所有交互场景都离不开对数据库的操作。掌握 PHP 操作 MySQL 的核心技能,不仅是实现数据持久化的基础,更是构建高效、安全、可维护应用的关键。
本文系统梳理了 PHP 操作 MySQL 的核心流程与关键技术,从最基础的读取数据(SELECT),到通过WHERE子句筛选数据、LIMIT实现分页、ORDER BY排序结果,再到数据的更新(UPDATE)与删除(DELETE),完整覆盖了 CRUD(创建、读取、更新、删除)的核心场景。内容不仅包含过程式、面向对象(MySQLi)及 PDO 三种主流操作方式的对比,更强调了安全实践(如异常处理、参数绑定)和性能优化(如显式指定列名、事务控制),旨在帮助开发者从 “会用” 提升到 “用好”,规避常见的安全隐患与性能陷阱。无论你是刚接触 PHP 数据库开发的初学者,还是需要巩固基础的开发者,这些内容都将为你构建可靠的数据交互层提供清晰的指引。


(6)PHP MySQL 读取数据

1.从 MySQL 表读取数据的基本方法

MySQL 中通过SELECT语句读取表数据,基本语法为:

-- 读取指定列
SELECT column1, column2 FROM table_name;
-- 读取所有列(不推荐,建议显式指定列名)
SELECT * FROM table_name;

结合 PHP,可通过数据库扩展的查询方法执行SELECT语句,获取结果集后逐行处理。

假设的表数据

以下示例基于persons表的现有数据(与前文插入的数据一致):

idfirst_namelast_nameemail
1PeterParkerpeterparker@mail.com
2JohnRambojohnrambo@mail.com
3ClarkKentclarkkent@mail.com
4JohnCarterjohncarter@mail.com
5HarryPotterharrypotter@mail.com
2.读取数据示例
a. 过程式方式(MySQLi)
<?php
$host = 'localhost';
$user = 'db_admin'; // 专用账户,禁止root
$pass = 'SecurePass@2024'; // 强密码
$dbname = 'demo';// 连接数据库
$link = mysqli_connect($host, $user, $pass, $dbname);
if (!$link) {throw new mysqli_sql_exception("连接失败:" . mysqli_connect_error());
}
// 强制字符集(PHP 8+ 必须)
mysqli_set_charset($link, 'utf8mb4');// 执行查询(推荐显式指定列名,替代SELECT *)
$sql = "SELECT id, first_name, last_name, email FROM persons";
$result = mysqli_query($link, $sql);if (!$result) {throw new mysqli_sql_exception("查询失败:" . mysqli_error($link));
}// 处理结果集
if (mysqli_num_rows($result) > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";// 逐行读取数据while ($row = mysqli_fetch_assoc($result)) { // 推荐使用assoc获取关联数组echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";
} else {echo "未找到匹配记录。";
}// 释放结果集和连接
mysqli_free_result($result);
mysqli_close($link);
?>
b. 面向对象方式(MySQLi)
<?php
$host = 'localhost';
$user = 'db_admin';
$pass = 'SecurePass@2024';
$dbname = 'demo';try {// 连接数据库(PHP 8+ 连接失败自动抛异常)$mysqli = new mysqli($host, $user, $pass, $dbname);$mysqli->set_charset('utf8mb4');// 执行查询$sql = "SELECT id, first_name, last_name, email FROM persons";$result = $mysqli->query($sql);if (!$result) {throw new mysqli_sql_exception("查询失败:" . $mysqli->error);}// 处理结果if ($result->num_rows > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";while ($row = $result->fetch_assoc()) { // 关联数组更直观echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到匹配记录。";}// 释放资源(空安全运算符防未定义错误)$result?->free();$mysqli?->close();
} catch (mysqli_sql_exception $e) {die("操作失败:" . $e->getMessage());
}
?>
c. PDO 方式
<?php
$host = 'localhost';
$user = 'db_admin';
$pass = 'SecurePass@2024';
$dbname = 'demo';try {// 连接数据库(指定字符集和异常模式)$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4",$user,$pass,[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);// 执行查询$sql = "SELECT id, first_name, last_name, email FROM persons";$result = $pdo->query($sql);// 处理结果(PDO::FETCH_ASSOC获取关联数组)if ($result->rowCount() > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";while ($row = $result->fetch(PDO::FETCH_ASSOC)) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到匹配记录。";}// 释放结果集$result = null;
} catch (PDOException $e) {die("操作失败:" . $e->getMessage());
} finally {unset($pdo); // 释放连接
}
?>

(7)WHERE语句

WHERE子句仅用于提取满足指定条件的那些记录。WHERE子句的基本语法可以通过以下方式给出:

SELECT column_name(s) FROM table_name WHERE column_name operator value

让我们使用SELECT语句中的WHERE子句进行一个SQL查询,然后通过将其传递给PHP mysqli_query()函数来执行该查询,以获取过滤后的数据。

1. 面向过程方式
<?php
// 启用MySQLi异常模式(PHP 8+推荐)
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 数据库连接(PHP 8+支持更简洁的连接方式)$link = mysqli_connect("localhost", "root", "", "demo");// 设置字符编码(强制UTF-8,避免乱码)mysqli_set_charset($link, 'utf8mb4');// 查询语句(使用单引号包裹字符串值)$sql = "SELECT * FROM persons WHERE first_name = 'john'";$result = mysqli_query($link, $sql);if (mysqli_num_rows($result) > 0) {echo "<table border='1'>";echo "<tr><th>id</th><th>名</th><th>姓</th><th>邮箱</th></tr>";// 使用fetch_assoc()获取关联数组(更明确)while ($row = mysqli_fetch_assoc($result)) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到匹配记录";}// 释放结果集mysqli_free_result($result);// 关闭连接mysqli_close($link);
} catch (mysqli_sql_exception $e) {// PHP 8+的异常处理,更清晰地捕获错误die("数据库操作失败: " . $e->getMessage());
}
?>
2. 面向对象方式
<?php
// 启用MySQLi异常模式
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 实例化MySQLi对象(PHP 8+构造函数参数更严格)$mysqli = new mysqli("localhost", "root", "", "demo");// 设置字符编码$mysqli->set_charset('utf8mb4');$sql = "SELECT * FROM persons WHERE first_name = 'john'";$result = $mysqli->query($sql);if ($result->num_rows > 0) {echo "<table border='1'>";echo "<tr><th>id</th><th>名</th><th>姓</th><th>邮箱</th></tr>";// 使用面向对象的fetch_assoc()while ($row = $result->fetch_assoc()) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";// 释放结果集$result->free();} else {echo "未找到匹配记录";}// 关闭连接$mysqli->close();
} catch (mysqli_sql_exception $e) {die("数据库操作失败: " . $e->getMessage());
}
?>
3. PDO 方式
<?php
try {// PDO连接(PHP 8+支持DSN中指定charset)$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[// PHP 8+推荐的选项配置PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 异常模式PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认关联数组PDO::ATTR_EMULATE_PREPARES => false // 禁用预处理模拟(更安全)]);$sql = "SELECT * FROM persons WHERE first_name = 'john'";$result = $pdo->query($sql);if ($result->rowCount() > 0) {echo "<table border='1'>";echo "<tr><th>id</th><th>名</th><th>姓</th><th>邮箱</th></tr>";// 直接遍历结果集(PHP 8+支持)foreach ($result as $row) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到匹配记录";}
} catch (PDOException $e) {die("数据库操作失败: " . $e->getMessage());
}// PDO会自动关闭连接,无需手动unset
?>

(8)LIMIT语句

1.LIMIT 子句基础语法

LIMIT 子句用于限制 SQL 查询返回的记录数量,核心作用是优化性能(减少数据传输)和实现分页。

基本语法
-- 语法1:返回前 N 条记录(从第1条开始)
SELECT 列名 FROM 表名 LIMIT 记录数;-- 语法2:从偏移量开始,返回 N 条记录(偏移量从0开始)
SELECT 列名 FROM 表名 LIMIT 偏移量, 记录数;
参数说明
  • 记录数:必填,指定返回的最大行数(非负整数)。
  • 偏移量:可选,指定开始返回记录的位置(从 0 开始,即LIMIT 0,5表示返回前 5 条)。
2.基础示例:返回有限记录

假设demo数据库的persons表数据如下:

idfirst_namelast_nameemail
1PeterParkerpeterparker@mail.com
2JohnRambojohnrambo@mail.com
3ClarkKentclarkkent@mail.com
4JohnCarterjohncarter@mail.com
5HarryPotterharrypotter@mail.com
1. MySQLi 面向过程方式(PHP 8+)
<?php
// 启用MySQLi异常模式(PHP 8+推荐)
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 连接数据库并设置字符编码$link = mysqli_connect("localhost", "root", "", "demo");mysqli_set_charset($link, 'utf8mb4'); // 支持emoji等特殊字符// 查询前3条记录(LIMIT 3 等价于 LIMIT 0,3)$sql = "SELECT * FROM persons LIMIT 3";$result = mysqli_query($link, $sql);if (mysqli_num_rows($result) > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";// 使用fetch_assoc()获取关联数组(更直观)while ($row = mysqli_fetch_assoc($result)) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到记录";}// 释放资源mysqli_free_result($result);mysqli_close($link);
} catch (mysqli_sql_exception $e) {die("数据库错误:" . $e->getMessage()); // 统一异常处理
}
?>
2. MySQLi 面向对象方式
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 实例化MySQLi对象$mysqli = new mysqli("localhost", "root", "", "demo");$mysqli->set_charset('utf8mb4'); // 设置编码// 从偏移量1开始,返回2条记录(即第2、3条)$sql = "SELECT * FROM persons LIMIT 1, 2";$result = $mysqli->query($sql);if ($result->num_rows > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";while ($row = $result->fetch_assoc()) { // 面向对象的fetch方法echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";$result->free(); // 释放结果集} else {echo "未找到记录";}$mysqli->close(); // 关闭连接
} catch (mysqli_sql_exception $e) {die("数据库错误:" . $e->getMessage());
}
?>
3. PDO 方式
<?php
try {// 连接数据库并配置参数(PHP 8+推荐)$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 异常模式PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认关联数组PDO::ATTR_EMULATE_PREPARES => false // 禁用预处理模拟(更安全)]);// 返回第4-5条记录(偏移量3,返回2条)$sql = "SELECT * FROM persons LIMIT 3, 2";$result = $pdo->query($sql);if ($result->rowCount() > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";foreach ($result as $row) { // 直接遍历结果集echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到记录";}
} catch (PDOException $e) {die("数据库错误:" . $e->getMessage());
}
?>
三、核心应用:分页功能实现

LIMIT 最常用的场景是分页,将大量记录拆分到多个页面。以下是完整分页实现步骤:

1. 分页核心逻辑
  • 页码参数:从 URL 获取当前页码(如 page=1)。
  • 每页记录数:固定值(如每页显示 2 条)。
  • 偏移量计算偏移量 = (当前页码 - 1) × 每页记录数
  • 总页数计算总页数 = ceil(总记录数 / 每页记录数)
2. 完整分页示例
<?php
try {$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);// 1. 获取并验证页码参数(防止无效输入)$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?? 1; // 默认为第1页$page = max($page, 1); // 确保页码≥1$perPage = 2; // 每页显示2条// 2. 计算偏移量$offset = ($page - 1) * $perPage;// 3. 查询当前页记录$stmt = $pdo->prepare("SELECT * FROM persons LIMIT :offset, :perPage");$stmt->bindParam(':offset', $offset, PDO::PARAM_INT); // 强制整数类型(防注入)$stmt->bindParam(':perPage', $perPage, PDO::PARAM_INT);$stmt->execute();$persons = $stmt->fetchAll();// 4. 查询总记录数(用于计算总页数)$totalRecords = $pdo->query("SELECT COUNT(*) FROM persons")->fetchColumn();$totalPages = ceil($totalRecords / $perPage);// 5. 显示记录if ($persons) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";foreach ($persons as $row) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "当前页无记录";}// 6. 生成分页链接echo "<div style='margin-top: 10px;'>";if ($page > 1) {echo "<a href='?page=" . ($page - 1) . "'>上一页</a> ";}for ($i = 1; $i <= $totalPages; $i++) {// 高亮当前页$active = ($i == $page) ? "style='color: red;'" : "";echo "<a href='?page=$i' $active>$i</a> ";}if ($page < $totalPages) {echo "<a href='?page=" . ($page + 1) . "'>下一页</a>";}echo "</div>";} catch (PDOException $e) {die("分页错误:" . $e->getMessage());
}
?>

(9)ORDER BY

1.ORDER BY 子句基础语法

ORDER BY 子句用于对 SQL 查询结果进行排序,可按单个或多个列升序 / 降序排列,是数据展示中不可或缺的功能(如列表排序、排行榜等)。

1.基本语法
-- 语法1:按单列排序(默认升序ASC)
SELECT 列名 FROM 表名 ORDER BY 排序列 [ASC|DESC];-- 语法2:按多列排序(先按列1排序,列1相同则按列2排序)
SELECT 列名 FROM 表名 ORDER BY1 [ASC|DESC],2 [ASC|DESC];
2.参数说明
  • 排序列:指定用于排序的字段(如 first_nameid)。
  • ASC:升序排序(默认值,可省略),如字母从 A 到 Z,数字从 0 到 9。
  • DESC:降序排序,如字母从 Z 到 A,数字从 9 到 0。
2.基础示例:单字段排序

假设demo数据库的persons表数据如下:

idfirst_namelast_nameemail
1PeterParkerpeterparker@mail.com
2JohnRambojohnrambo@mail.com
3ClarkKentclarkkent@mail.com
4JohnCarterjohncarter@mail.com
5HarryPotterharrypotter@mail.com
1. MySQLi 面向过程方式
<?php
// 启用MySQLi异常模式(PHP 8+推荐)
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 连接数据库并设置字符编码$link = mysqli_connect("localhost", "root", "", "demo");mysqli_set_charset($link, 'utf8mb4'); // 支持特殊字符// 按first_name升序排序(默认ASC,可省略)$sql = "SELECT * FROM persons ORDER BY first_name ASC";$result = mysqli_query($link, $sql);if (mysqli_num_rows($result) > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";// 使用fetch_assoc()获取关联数组while ($row = mysqli_fetch_assoc($result)) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到记录";}// 释放资源mysqli_free_result($result);mysqli_close($link);
} catch (mysqli_sql_exception $e) {die("数据库错误:" . $e->getMessage()); // 统一异常处理
}
?>
2. MySQLi 面向对象方式
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 实例化MySQLi对象$mysqli = new mysqli("localhost", "root", "", "demo");$mysqli->set_charset('utf8mb4'); // 设置编码// 按first_name降序排序(DESC显式指定)$sql = "SELECT * FROM persons ORDER BY first_name DESC";$result = $mysqli->query($sql);if ($result->num_rows > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";while ($row = $result->fetch_assoc()) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";$result->free(); // 释放结果集} else {echo "未找到记录";}$mysqli->close(); // 关闭连接
} catch (mysqli_sql_exception $e) {die("数据库错误:" . $e->getMessage());
}
?>
3. PDO 方式
<?php
try {// 连接数据库并配置参数$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 异常模式PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认关联数组PDO::ATTR_EMULATE_PREPARES => false // 禁用预处理模拟]);// 按id降序排序(从大到小)$sql = "SELECT * FROM persons ORDER BY id DESC";$result = $pdo->query($sql);if ($result->rowCount() > 0) {echo "<table border='1'>";echo "<tr><th>ID</th><th>名</th><th>姓</th><th>邮箱</th></tr>";foreach ($result as $row) { // 直接遍历结果集echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['first_name']}</td>";echo "<td>{$row['last_name']}</td>";echo "<td>{$row['email']}</td>";echo "</tr>";}echo "</table>";} else {echo "未找到记录";}
} catch (PDOException $e) {die("数据库错误:" . $e->getMessage());
}
?>

(10)UPDATE

1.UPDATE 子句基础语法

UPDATE 语句用于修改数据库表中的现有记录,核心作用是更新符合条件的数据。必须结合WHERE子句使用,否则会误更新全表数据!

-- 基础语法:更新单表中的字段
UPDATE 表名 
SET1 =1,2 =2, ... 
WHERE 条件; -- 关键:指定更新哪些记录

核心说明

  • SET子句:指定要更新的列和对应的值(多个列用逗号分隔)。
  • WHERE子句:筛选需要更新的记录(如id = 1status = 'active'),缺失则更新全表
  • 返回值:MySQL 返回受影响的行数(可用于判断更新是否成功)。

假设demo数据库的persons表初始数据如下:

idfirst_namelast_nameemail
1PeterParkerpeterparker@mail.com
2JohnRambojohnrambo@mail.com
2. MySQLi 面向过程方式
<?php
// 启用MySQLi异常模式(PHP 8+推荐)
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 连接数据库并设置编码$link = mysqli_connect("localhost", "root", "", "demo");mysqli_set_charset($link, 'utf8mb4');// 更新id=1的记录:修改email$sql = "UPDATE persons SET email = 'peter.new@mail.com' WHERE id = 1";$affectedRows = mysqli_query($link, $sql);// 判断更新结果(mysqli_affected_rows返回受影响行数)if (mysqli_affected_rows($link) > 0) {echo "记录更新成功!受影响行数:" . mysqli_affected_rows($link);} else {echo "未找到匹配记录或无需更新。";}mysqli_close($link);
} catch (mysqli_sql_exception $e) {die("更新失败:" . $e->getMessage()); // 统一异常处理
}
?>
3. MySQLi 面向对象方式
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {// 实例化MySQLi对象$mysqli = new mysqli("localhost", "root", "", "demo");$mysqli->set_charset('utf8mb4');// 更新id=2的记录:同时修改first_name和last_name$sql = "UPDATE persons SET first_name = 'Johnny', last_name = 'Rambo Jr' WHERE id = 2";$mysqli->query($sql);// 判断结果($mysqli->affected_rows获取受影响行数)if ($mysqli->affected_rows > 0) {echo "更新成功!受影响行数:" . $mysqli->affected_rows;} else {echo "未找到匹配记录或数据无变化。";}$mysqli->close();
} catch (mysqli_sql_exception $e) {die("更新失败:" . $e->getMessage());
}
?>
4. PDO 方式
<?php
try {// 连接数据库并配置参数$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 异常模式PDO::ATTR_EMULATE_PREPARES => false // 禁用预处理模拟(安全)]);// 更新id=1的记录:使用PDO::exec()执行更新$sql = "UPDATE persons SET email = 'peter.updated@mail.com' WHERE id = 1";$affectedRows = $pdo->exec($sql); // exec()返回受影响行数if ($affectedRows > 0) {echo "更新成功!受影响行数:" . $affectedRows;} else {echo "未找到匹配记录或数据未变更。";}
} catch (PDOException $e) {die("更新失败:" . $e->getMessage());
}
?>
5.高级用法:事务处理与批量更新
a. 事务确保更新原子性

当需要同时更新多个表或多条记录时,使用事务保证操作的原子性(要么全成功,要么全失败):

<?php
try {$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);// 开始事务$pdo->beginTransaction();// 操作1:更新用户表$stmt1 = $pdo->prepare("UPDATE persons SET balance = balance - 100 WHERE id = 1");$stmt1->execute();// 操作2:更新日志表$stmt2 = $pdo->prepare("INSERT INTO logs (user_id, action) VALUES (?, '扣款100元')");$stmt2->execute([1]);// 提交事务(所有操作成功才生效)$pdo->commit();echo "事务执行成功!";
} catch (PDOException $e) {// 回滚事务(任何操作失败则全部撤销)$pdo->rollBack();die("事务失败:" . $e->getMessage());
}
?>
b. 批量更新多条记录

通过循环或批量 SQL 语句一次性更新多条记录:

<?php
try {$pdo = new PDO("mysql:host=localhost;dbname=demo;charset=utf8mb4","root","",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);// 批量更新数据(例如:批量修改状态)$updates = [['id' => 1, 'status' => 'active'],['id' => 2, 'status' => 'inactive'],['id' => 3, 'status' => 'active']];// 预处理单条更新语句$stmt = $pdo->prepare("UPDATE persons SET status = :status WHERE id = :id");// 循环执行批量更新foreach ($updates as $data) {$stmt->execute($data);}echo "批量更新完成!共更新 " . count($updates) . " 条记录。";
} catch (PDOException $e) {die("批量更新失败:" . $e->getMessage());
}
?>

(11)DELETE

1.删除数据库表数据

正如将记录插入表中一样,您可以使用SQL DELETE语句从表中删除记录。它通常与WHERE子句结合使用,仅删除那些符合特定条件或条件的记录。

DELETE语句的基本语法可以通过以下方式给出:

DELETE FROM table_name WHERE column_name=some_value

让我们使用DELETE语句和WHERE子句进行一个SQL查询,然后通过将其传递给PHP mysqli_query()函数来执行此查询,以删除表记录。请看demo数据库中的以下persons表:

+----+------------+-----------+----------------------+
| id | first_name | last_name | email                |
+----+------------+-----------+----------------------+
|  1 | Peter      | Parker    | peterparker@mail.com |
|  2 | John       | Rambo     | johnrambo@mail.com   |
|  3 | Clark      | Kent      | clarkkent@mail.com   |
|  4 | John       | Carter    | johncarter@mail.com  |
|  5 | Harry      | Potter    | harrypotter@mail.com |
+----+------------+-----------+----------------------+

下面示例中的PHP代码将从persons表中删除first_name等于John的人的记录。

2.面向过程方式
<?php
/* 尝试MySQL服务器连接。 假设您正在运行MySQL。
具有默认设置的服务器(没有密码的用户“root”) */
$link = mysqli_connect("localhost", "root", "", "demo");//检查连接
if($link === false){die("错误:无法连接。 " . mysqli_connect_error());
}//尝试执行删除
$sql = "DELETE FROM persons WHERE first_name='John'";
if(mysqli_query($link, $sql)){echo "记录已成功删除。";
} else{echo "错误:无法执行 $sql. " . mysqli_error($link);
}//关闭连接
mysqli_close($link);
?>
3.面向对象方式
<?php
/* 尝试MySQL服务器连接。 假设您正在运行MySQL。
具有默认设置的服务器(没有密码的用户“root”) */
$mysqli = new mysqli("localhost", "root", "", "demo");//检查连接
if($mysqli === false){die("错误:无法连接。 " . $mysqli->connect_error);
}//尝试执行删除
$sql = "DELETE FROM persons WHERE first_name='John'";
if($mysqli->query($sql) === true){echo "记录已成功删除。";
} else{echo "错误:无法执行 $sql. " . $mysqli->error;
}//关闭连接
$mysqli->close();
?>
4.PDO方式
<?php
/* 尝试MySQL服务器连接。 假设您正在运行MySQL。
具有默认设置的服务器(没有密码的用户“root”)*/
try{$pdo = new PDO("mysql:host=localhost;dbname=demo", "root", "");//将PDO错误模式设置为异常$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){die("错误:无法连接。 " . $e->getMessage());
}//尝试更新查询执行
try{$sql = "DELETE FROM persons WHERE first_name='John'";  $pdo->exec($sql);echo "记录已成功删除。";
} catch(PDOException $e){die("错误:无法执行 $sql. " . $e->getMessage());
}//关闭连接
unset($pdo);
?>

删除后,persons表将如下所示:

+----+------------+-----------+----------------------+
| id | first_name | last_name | email                |
+----+------------+-----------+----------------------+
|  1 | Peter      | Parker    | peterparker@mail.com |
|  3 | Clark      | Kent      | clarkkent@mail.com   |
|  5 | Harry      | Potter    | harrypotter@mail.com |
+----+------------+-----------+----------------------+

正如您看到的,记录已成功从persons表中删除。

**警告:**DELETE语句中的WHERE子句指定应该删除哪些记录。如果省略WHERE子句,所有记录都将被删除。


结语

PHP 操作 MySQL 的核心技能,是连接前端交互与后端数据的桥梁。从本文介绍的读取数据、条件筛选、分页排序,到更新与删除操作,每一个环节都承载着数据流转的逻辑,也暗藏着需要规避的风险 —— 例如UPDATE和DELETE中缺失WHERE子句可能导致的全表数据误操作,或未使用预处理语句带来的 SQL 注入隐患。
通过学习三种操作方式(MySQLi 过程式、面向对象、PDO)的特性,我们不仅掌握了实现功能的工具,更理解了 “选择合适方法” 的重要性:PDO 的跨数据库兼容性、MySQLi 的原生性能优势,都需根据项目场景灵活取舍。而事务处理、批量操作等进阶技巧,则进一步提升了代码的健壮性与效率。
然而,技术的掌握不止于语法本身。真正的实践中,还需结合业务场景优化查询(如合理使用索引)、强化安全校验(如数据过滤与权限控制)、完善错误处理与日志记录。希望本文的内容能成为你开发路上的基石,让你在构建数据驱动应用时,既能精准实现需求,又能兼顾安全、性能与可维护性,为用户提供稳定可靠的服务。

http://www.lryc.cn/news/607926.html

相关文章:

  • Removing Digits(Dynamic Programming)
  • 【第三章】变量也疯狂:深入剖析 Python 数据类型与内存原理
  • Android13文件管理USB音乐无专辑图片显示的是同目录其他图片
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情数据可视化分析-热词情感趋势柱状图
  • 机器学习 —— 决策树
  • 从C++0基础到C++入门(第十五节:switch语句)
  • 计算机网络:为什么IPv6没有选择使用点分十进制
  • 如何修复非json数据
  • Gemini CLI
  • 深入 Go 底层原理(五):内存分配机制
  • 操作系统-lecture5(线程)
  • Vue3核心语法基础
  • 【大模型入门】3.从头实现GPT模型以生成文本
  • 相对路径 绝对路径
  • UniappDay07
  • sqli-labs:Less-19关卡详细解析
  • Qt 槽函数被执行多次,并且使用Qt::UniqueConnection无效【已解决】
  • 24黑马SpringCloud的Docker本地目录挂载出现相关问题解决
  • Tushare对接OpenBB分析A股与港股市场
  • 解锁智能油脂润滑系统:加速度与温振传感器选型协同攻略
  • 深度学习核心:卷积神经网络 - 原理、实现及在医学影像领域的应用
  • 【Java】在一个前台界面中动态展示多个数据表的字段及数据
  • 定制开发开源AI智能名片S2B2C商城小程序的特点、应用与发展研究
  • 自进化智能体综述:通往人工超级智能之路
  • SpringBoot IOC
  • C++之vector类的代码及其逻辑详解 (中)
  • 【自动化运维神器Ansible】YAML语法详解:Ansible Playbook的基石
  • vue引入阿里巴巴矢量图库的方式
  • Kotlin协程极简教程:5分钟学完关键知识点
  • docker desktop入门(docker桌面版)(提示wsl版本太低解决办法)