PHP连接MySQL数据库完整指南:从旧版接口到PDO实践
在PHP开发中,连接MySQL数据库是构建后端应用的核心基础。早期版本广泛使用的`mysql_*`系列函数因安全性问题已被移除。现代PHP项目推荐使用`mysqli`或`PDO`(PHP Data Objects)扩展进行数据库交互。本文将梳理数据库连接原理,分析不同扩展函数的特点,并提供处理查询结果集的标准操作代码。
PHP与MySQL的连接架构
MySQL采用“客户端/服务器”(Client/Server)架构。PHP作为客户端脚本语言,通过安装的扩展函数向MySQL服务端发送SQL命令,并接收执行后的结果集返回给前端或控制器。根据SQL语句的类型,处理方式有所不同:
- DQL语句(数据查询语言):如
SELECT、DESC table_name,执行后会返回结果集,需要PHP进一步解析字段和数据。 - DML/DDL语句(数据操纵/定义语言):如
INSERT、UPDATE、DELETE或创建表语句,通常不直接返回结果集,但会影响数据库状态(如影响行数),需判断执行是否成功。
传统接口分析:为何不再使用 mysql_* 函数
在PHP 5.5之前,mysql_connect 和 mysql_query 是主流的连接方式。虽然其逻辑简单,存在以下严重缺陷:
1. 安全性低:原生不支持预处理语句,易受SQL注入攻击。
2. 性能一般:无法高效处理复杂对象。
3. 已废弃:自PHP 7.0起彻底移除,强制迁移至其他驱动。
原理解析与旧版代码逻辑
尽管不再使用,理解其参数结构有助于掌握后续新接口的演变。旧版流程通常包含:建立连接 → 选择数据库 → 设置字符集 → 执行SQL → 检查结果 → 关闭连接。
<?php
// ⚠️ 警告:此代码仅供理解历史API,严禁在生产环境使用
// 1. 尝试建立连接 (主机, 用户名, 密码)
$link = @mysql_connect('localhost', 'root', 'password');
if (!$link) {
die('连接失败: ' . mysql_error());
}
// 2. 选择目标数据库
mysql_select_db('test_db') or die('选择数据库失败');
// 3. 设置字符编码(防止乱码)
mysql_query("SET NAMES utf8mb4");
// 4. 执行非查询类SQL(DML)
$sql = "INSERT INTO users (id, name) VALUES ('1', 'dwqs')";
$result = mysql_query($sql);
// 5. 判断是否影响记录及获取插入ID
if ($result && mysql_affected_rows() > 0) {
echo '插入成功,自增ID为: ' . mysql_insert_id();
} else {
echo '插入失败';
}
// 6. 务必手动关闭连接
mysql_close($link);
推荐方案一:使用 PDO (PHP Data Objects)
PDO提供了统一的数据库访问接口,支持多种数据库(不仅是MySQL)。其最大优势在于预处理语句(Prepared Statements),能有效防御SQL注入,且功能强大,适合绝大多数现代PHP项目。
第1步:初始化PDO连接
通过构造函数传入DSN(数据源名称)、用户名和密码。设置属性以开启异常模式,便于捕获数据库错误而非显示敏感信息。
<?php
$dsn = 'mysql:host=localhost;dbname=test_db;charset=utf8mb4';
$user = 'root';
$pass = 'password';
try {
$pdo = new PDO($dsn, $user, $pass);
// 设置错误模式为异常抛出
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 设置默认取数模式为关联数组
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
echo "PDO连接成功";
} catch (PDOException $e) {
// 生产环境中应记录日志而非直接echo
error_log($e->getMessage());
die('数据库连接错误');
}
?>
推荐方案二:使用 MySQLi
MySQLi专为MySQL设计,提供面向对象(OOP)和过程化两种接口。相比PDO,它在纯MySQL场景下略有性能优势,但仅支持MySQL。以下展示其面向对象用法及结果集处理。
第2步:建立连接并处理Select查询结果集
使用select语句后,PHP会获得一个结果集资源。我们需要从中提取数据行。以下是几种常见的提取方法及效率对比:
<?php
$mysqli = new mysqli("localhost", "root", "password", "test_db");
// 检查连接
if ($mysqli->connect_error) {
die("连接失败: " . $mysqli->connect_error);
}
$sql = "SELECT * FROM test WHERE status = 1";
$result = $mysqli->query($sql);
if ($result) {
// 获取总行数
$row_count = $result->num_rows;
// 迭代输出每一行数据
while ($row = $result->fetch_assoc()) {
echo "ID: " . htmlspecialchars($row['id']) . " - Name: " . htmlspecialchars($row['name']) . "<br>";
}
// 释放内存
$result->free();
} else {
echo "查询执行失败: " . $mysqli->error;
}
$mysqli->close();
?>
结果集处理函数对比
在处理查询结果时,可根据数据结构需求选择不同的获取方法:
| 函数/属性 | 返回数据结构 | 适用场景 |
|---|---|---|
fetch_assoc() | 关联数组(Key为列名) | 需要按列名访问,最常用,内存占用小 |
fetch_row() | 索引数组(Key为数字0,1,2...) | 按位置访问,速度略快于assoc |
fetch_array() | 关联+索引双数组 | 既需要键名又需要索引,但内存开销大,不推荐高频使用 |
fetch_object() | stdClass对象 | 习惯使用对象语法访问字段 |
常见问题与安全建议
在进行数据库交互时,请务必遵循以下最佳实践:
- 始终使用预处理语句:无论是PDO的
prepare()/bind_param()还是MySQLi的同等方法,永远不要将用户输入直接拼接进SQL字符串。 - 关闭连接:对于长时间运行的脚本,显式关闭不必要的数据库连接可以节省服务器资源。
- 错误处理:不要在公共页面上直接输出数据库错误信息(如
die(mysql_error())),这可能会泄露数据库结构、路径等敏感信息给攻击者。
以上就是PHP连接MySQL及相关扩展函数的详细内容,更多关于PHP数据库优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













