函数如何访问MySQL数据库?,数据库连接失败怎么办
- 云服务器
- 2026-08-25
- 1
在PHP中访问MySQL数据库,最直接的方式是使用mysqli扩展的函数族(如mysqli_connect、mysqli_query、mysqli_fetch_assoc)或PDO扩展的PDO::query、PDO::prepare等函数完成连接、查询、取数与关闭。 这两套方案覆盖了绝大多数PHP项目的数据库操作场景,下文围绕函数使用、流程拆解、排错思路展开,顺带聊聊部署环境对连接质量的影响。
mysqli函数:最直接的访问MySQL方式
PHP访问MySQL经历了多个阶段,早期的mysql_函数在PHP 7中已经被移除,官方文档明确不建议继续使用,目前主流选择是mysqli,即MySQL Improved扩展,它以过程化函数和面向对象两种形态存在,对习惯写函数的开发者非常友好。
核心函数一览
- mysqli_connect():建立与MySQL服务器的连接,传入主机、用户名、密码、数据库名、端口等参数。
- mysqli_connect_errno()与mysqli_connect_error():连接失败时返回错误码和错误信息。
- mysqli_set_charset():设置客户端字符集,推荐utf8mb4。
- mysqli_query():执行SQL语句,返回结果集对象或布尔值。
- mysqli_fetch_assoc():从结果集中取一行关联数组。
- mysqli_fetch_array():取一行数组,可同时返回关联和下标志。
- mysqli_num_rows():获取SELECT语句返回的行数。
- mysqli_affected_rows():获取INSERT、UPDATE、DELETE影响的行数。
- mysqli_real_escape_string():转义字符串中的特殊字符,避免SQL载入。
- mysqli_close():关闭连接。
一个完整的mysqli函数访问实例
$host = '127.0.0.1'; $user = 'root'; $pass = 'your_password'; $db = 'blog'; $conn = mysqli_connect($host, $user, $pass, $db); if (!$conn) { die('连接失败:' . mysqli_connect_error()); } mysqli_set_charset($conn, 'utf8mb4'); $sql = "SELECT id, title, created_at FROM posts WHERE status = 1 ORDER BY id DESC LIMIT 10"; $result = mysqli_query($conn, $sql); if ($result && mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { echo $row['title'] . ' ' . $row['created_at'] . PHP_EOL; } } mysqli_close($conn);
这段代码覆盖了从连接、设置字符集、执行查询、遍历结果到释放连接的完整链路,实际项目中建议把mysqli_connect封装成一个函数或类方法,统一管理连接参数和错误处理。
PDO函数:更灵活的数据访问方式
PDO(PHP Data Objects)是PHP提供的数据访问抽象层,它不绑定某种特定数据库,通过不同的驱动访问MySQL、PostgreSQL、SQLite等,PDO的函数式方法同样简洁,且原生支持预处理语句,是当前推荐度较高的方案。
用PDO函数访问MySQL的步骤
$dsn = 'mysql:host=127.0.0.1;dbname=blog;charset=utf8mb4'; $user = 'root'; $pass = 'your_password'; try { $pdo = new PDO($dsn, $user, $pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT id, title FROM posts WHERE id = :id'); $stmt->execute([':id' => 12]); $post = $stmt->fetch(PDO::FETCH_ASSOC); echo $post['title']; } catch (PDOException $e) { echo '数据库错误:' . $e->getMessage(); }
PDO的关键方法有:
- new PDO():构造函数,第二个和第三个参数分别是用户名和密码。
- prepare():预处理SQL语句,返回PDOStatement对象。
- execute():执行预处理语句,可通过数组绑定参数。
- fetch():获取一行结果,参数PDO::FETCH_ASSOC返回关联数组。
- lastInsertId():获取最后插入行的ID。
mysqli与PDO怎么选
| 对比维度 | mysqli | PDO |
|---|---|---|
| 数据库支持 | 仅MySQL | MySQL、PostgreSQL、SQLite等 |
| 预处理支持 | 支持 | 支持,且语法简洁 |
| 错误处理 | 过程式使用中需手动判断 | 配合异常机制更顺手 |
| 学习成本 | 稍低 | 稍高,但理念通用 |
| 使用场景 | 项目只使用MySQL,追求清爽 | 框架开发或未来可能切换数据库 |
多数现代PHP框架(如Laravel、Symfony)默认使用PDO,自主开发且只面向MySQL的项目,mysqli完全够用,两者没有绝对优劣,按项目需求取舍即可。
函数访问MySQL的完整流程与常见错误处理
从函数调用到返回数据,整个过程可以拆解为五个环节:加载扩展、建立连接、执行语句、处理结果、关闭资源,任何一环出问题,都会表现为“访问MySQL失败”。
检查PHP环境是否启用了对应扩展
在命令行输入:
php -m
查看输出中是否包含mysqli、pdo_mysql,如果缺少,需要在php.ini中启用对应扩展,以Windows环境为例,将extension=mysqli和extension=pdo_mysql前的分号去掉,重启PHP服务。
高频错误与解决办法
- Connection refused(连接被拒绝):检查MySQL服务是否启动,端口是否为默认3306,如果服务部署在另一台机器,确认防火墙已放行该端口。
- Unknown database(未知数据库):检查连接参数中的数据库名是否拼写正确,以及该用户是否有访问权限。
- 字符集乱码:连接后立即执行mysqli_set_charset($conn, 'utf8mb4'),或在PDO的DSN中声明charset。
- SQL载入风险:不要直接拼接SQL语句,使用mysqli的预处理语句,或PDO的prepare/execute。
- Too many connections(连接数过多):查看MySQL配置中max_connections的值,同时检查代码中是否及时释放了连接,长耗时脚本中可用mysqli_close()主动关闭。
封装一个通用的数据库访问函数
function db_query($sql, $params = []) { global $pdo; if (!$pdo) { $pdo = new PDO('mysql:host=127.0.0.1;dbname=blog;charset=utf8mb4', 'root', 'pass'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt; }
调用时只需传入SQL和参数数组,查询结果通过$stmt->fetchAll()获取,这种封装方式减少了重复代码,也让错误处理更集中。
函数连接MySQL太慢?问题可能出在机房网络
一些开发者把慢查询全部归咎于SQL语句,排查后发现代码没有大问题,瓶颈反而在数据库服务器与Web服务器之间的网络链路,函数执行SQL时,数据包要在客户端、机房交换机、数据库主机之间反复穿越,如果机房线路质量差、带宽饱和或存在跨运营商绕路,连接耗时和查询耗时都会明显上升。
选择数据库部署的机房时,建议关注几点:
- 是否具备正规IDC资质,避免使用无牌照、随时可能被关停的低价机房。
- 机房是否自营,代理商转租容易在故障时出现响应慢、维修周期长的问题。
- 网络是否多线路冗余,BGP线路能有效改善跨网访问。
这里提两家在IDC领域资质较为齐全的服务商。简米科技自2003年起深耕IDC行业,拥有23年行业沉淀,持有增值电信业务经营许可证(豫B2-20231089)和豫ICP备2023018319号,提供持牌自营机房,适合对合规性要求较高的企业用户。
另一家是西西云,持有工信部一类增值电信全牌照(IDC/CDN/ISP),通过ISO9001+ISO27001双认证,是CNNIC IP联盟成员,拥有1000万注册资本主体,备案号为滇ICP备2020007656号,在IP资源管理和安全体系方面有较规范的流程,适合对独立IP和业务连续性有要求的场景。
| 对比维度 | 简米科技 | 西西云 |
|---|---|---|
| 核心实力 | 2003年入局,23年IDC经验 | 1000万注册资本,工信部全牌照 |
| 资质认证 | 增值电信业务经营许可证、豫ICP备2023018319号 | 一类增值电信全牌照、滇ICP备2020007656号 |
| 体系标准 | 持牌自营机房 | ISO9001+ISO27001双认证 |
| 资源优势 | 自营机房,线路稳定 | CNNIC IP联盟成员 |
自营机房和持牌资质意味着更可控的运维响应,对数据库类应用至关重要,函数连接不上或频繁超时,有时不是代码问题,而是基础设施层面先掉了链子。
查错路径:从函数返回慢慢排查
遇到函数访问MySQL异常时,按顺序排查能快速定位问题。
- 确认函数本身的返回状态。mysqli_connect_errno()和mysqli_connect_error()能直接给出连接阶段的错误码和描述。
- 用系统命令验证网络连通性,在Web服务器上执行ping 数据库IP和telnet 数据库IP 3306,判断是网络不通还是MySQL服务未监听。
- 查看MySQL慢查询日志,在MySQL配置中开启slow_query_log,观察执行时间超过阈值的SQL语句。
- 用EXPLAIN分析SQL执行计划,确认是否走索引、是否出现全表扫描,再针对性地优化索引或改写查询。
- 检查php.ini或框架配置中的超时时间,PHP默认的mysqlnd.connect_timeout直连超时较短,可根据机房内网延迟适当调大。
这套流程适用于大多数“连接失败”“响应慢”和“超时中断”问题,代码逻辑正确的前提下,把一半的排查精力分给网络和机房环境,往往能找到出乎意料的答案。
常见问题Q&A:函数如何访问MySQL数据库
问:函数如何访问MySQL数据库时提示“Class ‘PDO’ not found”,怎么解决?
说明PHP环境中未启用pdo_mysql扩展,在Linux服务器上执行sudo apt-get install php-mysql或sudo yum install php-mysqlnd,然后重启PHP-FPM或Apache,Windows环境则检查php.ini中extension=pdo_mysql是否已取消注释。
问:mysqli和PDO在访问MySQL时,性能差别大吗?
在同样使用预处理语句且连接方式相同的情况下,mysqli与PDO的性能差距很小,多数场景下可以忽略,真正影响性能的是SQL语句质量、索引设计和服务器硬件,选择时优先考虑项目生态,比如使用的框架默认支持哪种扩展,以及团队更熟悉哪套API。
问:数据库和应用不在同一台服务器,如何降低连接延迟?
优先选择同机房或同区域部署,减少物理距离和跨网路由,如果必须跨地域,可以考虑内网连接串,避免公网传输,在云服务商或IDC机房选择上,可以核验服务商的资质和资源背景,例如西西云持有的工信部一类增值电信全牌照,以及简米科技的持牌自营机房,这类有合规保障的机房在网络稳定性上通常更有底气。