🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录
⛳️ 推荐
一、连接方式对比与选择
1. 已废弃方式:mysql 扩展
2. 推荐方式对比
二、标准连接代码示例
1. MySQLi(面向对象,推荐)
2. PDO(跨数据库首选)
三、安全与最佳实践
1. 必须使用预处理语句
2. 关键配置要求
四、常见问题排查
1. 连接失败原因
2. 性能优化
PHP 连接 MySQL应优先使用 MySQLi 或 PDO 扩展,避免使用已废弃的mysql扩展(PHP 5.5 弃用,PHP 7.0+ 彻底移除)。两者均支持预处理语句以防止 SQL 注入,但PDO 因跨数据库兼容性更佳,MySQLi 因原生 MySQL 优化性能略优,具体选择需结合项目需求。以下为关键要点:
一、连接方式对比与选择
1.已废弃方式:mysql扩展
- PHP 5.5 起弃用,PHP 7.0+ 完全移除,绝对不可用于新项目。
- 仅支持过程式编程,无预处理语句支持,无法有效防御 SQL 注入。
2.推荐方式对比
| 特性 | MySQLi | PDO |
|---|---|---|
| 数据库支持 | 仅 MySQL | 支持 12+ 数据库(MySQL、PostgreSQL 等) |
| API 风格 | 面向对象 + 过程式 | 纯面向对象 |
| 预处理语句 | 支持(仅问号占位符?) | 支持(命名占位符:name+ 问号) |
| 错误处理 | 需手动检查或异常模式 | 统一异常处理(PDOException) |
| 适用场景 | 纯 MySQL 项目,追求极致性能 | 需跨数据库迁移或强调代码可维护性 |
关键结论:
- 若项目仅使用 MySQL 且需深度优化,选MySQLi(尤其面向对象风格)。
- 若需未来迁移到其他数据库或统一接口规范,选PDO。
二、标准连接代码示例
1.MySQLi(面向对象,推荐)
<?php $host = 'localhost'; $dbname = 'your_db'; $username = 'root'; $password = 'your_password'; $charset = 'utf8mb4'; // **必须显式指定 utf8mb4 支持 Emoji** try { $conn = new mysqli($host, $username, $password, $dbname); // 检查连接错误 if ($conn->connect_error) { throw new Exception("MySQLi 连接失败: " . $conn->connect_error); } // **强制设置字符集(防乱码)** $conn->set_charset($charset); echo "MySQLi 连接成功"; } catch (Exception $e) { die("错误: " . $e->getMessage()); }- 必须检查
$conn->connect_error,因 PHP 8+ 不再自动抛出异常。 set_charset("utf8mb4")不可省略,否则中文/Emoji 可能乱码。
2.PDO(跨数据库首选)
<?php $host = 'localhost'; $dbname = 'your_db'; $username = 'root'; $password = 'your_password'; $charset = 'utf8mb4'; try { $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // **强制异常模式** PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认返回关联数组 PDO::ATTR_EMULATE_PREPARES => false // **禁用模拟预处理(更安全)** ]; $pdo = new PDO($dsn, $username, $password, $options); echo "PDO 连接成功"; } catch (PDOException $e) { die("PDO 连接失败: " . $e->getMessage()); }ATTR_ERRMODE_EXCEPTION必须启用,否则错误将静默失败。ATTR_EMULATE_PREPARES => false禁用模拟预处理,确保参数真正与 SQL 逻辑分离,彻底防御 SQL 注入。
三、安全与最佳实践
1.必须使用预处理语句
- 直接拼接 SQL 字符串是高危操作,例如:
// 危险!易受 SQL 注入攻击 $sql = "SELECT * FROM users WHERE email = '$email'"; - 正确做法(PDO 命名占位符示例):
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email"); $stmt->execute([':email' => $email]); // 参数自动转义 - MySQLi 问号占位符示例:
$stmt = $conn->prepare("SELECT * FROM users WHERE email = ?"); $stmt->bind_param("s", $email); // "s" 表示字符串类型 $stmt->execute();
2.关键配置要求
- 字符集统一:连接时显式指定
charset=utf8mb4(非utf8),避免中文/Emoji 乱码。 - 错误模式:
- PDO 必须设
PDO::ERRMODE_EXCEPTION。 - MySQLi 需手动检查
connect_error或启用异常(PHP 8+ 默认抛出)。
- PDO 必须设
- 生产环境:
- 敏感信息(密码等)应通过环境变量管理,避免硬编码在脚本中。
- 连接后立即关闭未使用资源(脚本结束会自动关闭,但显式释放更规范)。
四、常见问题排查
1.连接失败原因
- MySQL 服务未运行:检查
systemctl status mysql(Linux)或服务管理器(Windows)。 - 权限不足:确认用户有远程访问权限(若非
localhost),执行:GRANT ALL PRIVILEGES ON dbname.* TO 'user'@'%' IDENTIFIED BY 'password'; - 扩展未启用:通过
phpinfo()检查mysqli或pdo_mysql是否加载。
2.性能优化
- 避免在循环内重复连接:单次请求复用连接对象。
- 长连接慎用:
PDO的PDO::ATTR_PERSISTENT或 MySQLi 的p:前缀可能引发资源泄漏,仅限高并发场景。
总结:现代 PHP 项目连接 MySQL必须使用 MySQLi 或 PDO,优先通过预处理语句防御 SQL 注入,并严格配置字符集与错误处理。若需未来兼容多数据库,PDO 是更可持续的选择;若仅针对 MySQL 且追求性能,MySQLi 面向对象风格更直接高效。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙