mysqli连接失败主因是扩展未启用、MySQL服务未运行或连接参数错误;须依次检查mysqli模块、MySQL进程及host配置,并依据mysqli_connect_error()提示定位问题。

mysqli_connect() 连接失败的常见原因和排查顺序
连接直接报错或返回 false,不是密码错了就是扩展没开,别急着改代码。先确认三件事:
-
mysqli扩展是否启用:运行php -m | grep mysqli或查phpinfo()页面里有没有mysqli模块 - MySQL 服务是否在运行:
systemctl status mysql(Linux)或任务管理器里看mysqld进程 - 连接参数是否写错:特别是
$host写成127.0.0.1却没开 MySQL 的skip-name-resolve,会导致超时;用localhost则走 socket,127.0.0.1才走 TCP
错误信息本身也藏线索:mysqli_connect_error() 返回的字符串里如果含 Connection refused,说明端口不通;含 Access denied,说明账号/密码/权限不对;含 Unknown MySQL server host,说明 DNS 解析失败或主机名拼错。
mysqli 面向对象方式必须做的两件事:字符集和错误检查
只写 $mysqli = new mysqli(...) 就开始查数据,大概率乱码或静默失败。必须紧接着做:
- 调用
$mysqli->set_charset('utf8mb4')—— 不是utf8,后者不支持 emoji 和部分汉字,PHP 会默默接受但存不进字段 - 检查
$mysqli->connect_error—— 不要等query()报错才处理,连接失败时$mysqli对象虽存在,但后续所有方法都返回null或触发警告
示例片段:
立即学习“PHP免费学习笔记(深入)”;
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
if ($mysqli->connect_error) {
die('Connect failed: ' . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4'); // 必须在 query 前执行
mysqli_query() 返回 false 时,怎么定位具体哪条 SQL 出了问题
mysqli_query() 返回 false,不代表语句语法错,可能是表不存在、字段名错、权限不足、甚至磁盘满。关键不是重试,而是立刻查错误源:
- 用
$mysqli->error获取最近一次查询的错误描述,比mysqli_error($mysqli)更准(后者依赖全局状态) - 用
$mysqli->errno获取错误码,比如1146是表不存在,1054是未知列,1045是权限拒绝 - 注意:
SELECT失败返回false,但空结果集(0 行)返回的是有效mysqli_result对象,别混淆
调试建议:把出问题的 SQL 单独复制到 MySQL 客户端里执行,看原生报错——很多问题(如 GROUP BY 严格模式、ONLY_FULL_GROUP_BY)在 PHP 里只报模糊错误,命令行里才显示完整提示。
预处理语句 bind_param() 类型符写错却不报错?这是真的
bind_param() 的第一个参数是类型字符串,s(string)、i(integer)、d(double)、b(blob)。写错类型不会抛异常,但会导致绑定失败、值被截断或 SQL 执行出错,且错误信息里完全不提类型问题。
- 传整数却用
's':PHP 会转成字符串再传给 MySQL,可能触发隐式类型转换,WHERE 条件失效 - 传字符串却用
'i':PHP 强转为 int,"123abc"变成123,"abc"变成0 - 参数个数不匹配:类型字符串长度 ≠ 后续变量个数,
bind_param()直接返回false,但容易被忽略
安全做法:类型符严格对应变量实际类型,调试期加一行 var_dump(gettype($var)) 确认;生产环境避免动态拼类型符,宁可拆成多个 prepare 调用。
字符集、错误检查、SQL 错误定位、类型符匹配——这四点漏掉任意一个,都会让 mysqli 表现得“有时行有时不行”,而问题往往不出在逻辑,出在连接初始化和参数绑定这些看似简单的环节。



















