在Web开发的世界里,PHP与数据库的交互是构建动态应用的核心,掌握如何使用PHP原生代码连接数据库,是每一位PHP开发者的基本功,本文将详细介绍两种主流且推荐的原生连接方式:MySQLi扩展和PDO(PHP数据对象)扩展,并阐明它们的区别与最佳实践。

使用MySQLi扩展连接数据库
MySQLi(MySQL Improved)是专门为MySQL数据库设计的扩展,它提供了面向对象和过程化两种编程风格,相较于古老的mysql_*函数,它在性能和功能上都有了显著提升。
面向对象风格
这是现代PHP开发中更推荐的方式,代码结构更清晰,易于维护。
<?php
// 数据库连接配置
$host = 'localhost';
$username = 'your_username';
$password = 'your_password';
$database = 'your_database';
// 创建MySQLi对象
$mysqli = new mysqli($host, $username, $password, $database);
// 检查连接是否成功
if ($mysqli->connect_error) {
die('连接失败 (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
echo '数据库连接成功!';
// 执行查询(示例)
$result = $mysqli->query("SELECT id, name FROM users");
// 关闭连接
$mysqli->close();
?>
过程化风格
对于习惯传统函数式编程的开发者,MySQLi也提供了过程化的API。
<?php
// 数据库连接配置
$host = 'localhost';
$username = 'your_username';
$password = 'your_password';
$database = 'your_database';
// 建立连接
$connection = mysqli_connect($host, $username, $password, $database);
// 检查连接是否失败
if (!$connection) {
die('连接失败: ' . mysqli_connect_error());
}
echo '数据库连接成功!';
// 执行查询(示例)
$result = mysqli_query($connection, "SELECT id, name FROM users");
// 关闭连接
mysqli_close($connection);
?>
使用PDO(PHP数据对象)扩展连接数据库
PDO是PHP官方推荐的数据库抽象层,它的最大优势在于“数据库无关性”,这意味着,如果你将来需要从MySQL切换到PostgreSQL或SQLite,你只需要修改连接字符串(DSN),而大部分查询代码无需改动,PDO对预处理语句的支持非常出色,是防止SQL注入的最佳武器。

<?php
// 数据库连接配置(DSN)
$host = 'localhost';
$db = 'your_database';
$user = 'your_username';
$pass = 'your_password';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 设置错误模式为异常
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 设置默认获取模式为关联数组
PDO::ATTR_EMULATE_PREPARES => false, // 禁用预处理语句的模拟
];
try {
// 创建PDO实例
$pdo = new PDO($dsn, $user, $pass, $options);
echo 'PDO数据库连接成功!';
} catch (\PDOException $e) {
// 捕获连接异常
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
MySQLi与PDO对比
为了更直观地理解两者的差异,下表进行了简单的对比:
| 特性 | MySQLi | PDO (PHP数据对象) |
|---|---|---|
| 数据库支持 | 仅支持MySQL | 支持多种数据库(MySQL, PostgreSQL, SQLite等) |
| API风格 | 面向对象和过程化 | 主要面向对象 |
| 预处理语句 | 支持,但接口略复杂 | 支持,接口简洁且强大 |
| 命名参数 | 不支持 | 支持(如name),使SQL更清晰 |
| 错误处理 | $mysqli->error 或过程化函数 |
基于异常(PDOException),更现代 |
重要提醒:已弃用的mysql_*函数
你可能会在一些老旧教程中看到mysql_connect()、mysql_query()等函数,请务必注意,这些函数自PHP 5.5版本起已被标记为废弃,并在PHP 7.0中完全移除,它们存在严重的安全漏洞(如无法有效防止SQL注入),且不支持新特性,任何新项目都应坚决避免使用。
相关问答 (FAQs)
Q1: 我应该选择MySQLi还是PDO来连接数据库?
A: 这取决于你的项目需求,如果你的项目确定只使用MySQL数据库,且团队更熟悉其API,MySQLi是一个完全可行的选择。强烈推荐使用PDO,原因有二:第一,PDO提供了数据库抽象层,为未来可能的数据库迁移提供了极大的便利;第二,PDO的预处理语句接口更简洁、更安全,是防止SQL注入攻击的最佳实践,对于大多数新项目而言,PDO的灵活性和安全性使其成为更优的选择。

Q2: 连接数据库后,如何有效防止SQL注入?
A: 防止SQL注入最有效、最根本的方法是始终使用预处理语句,无论是使用PDO还是MySQLi,都应遵循此原则,预处理语句的工作原理是将SQL命令和用户提交的数据分两次发送给数据库服务器,首先发送SQL模板(其中包含占位符或name),数据库服务器会对其进行编译,再将用户数据作为参数发送过去,此时数据库只会将这些数据当作纯粹的文本处理,而绝不会将其解释为SQL代码的一部分,这样就从机制上彻底杜绝了SQL注入的风险。