mysqli_connect()报connection refused,首要排查mysql服务是否运行、端口3306是否监听、bind-address配置是否允连,再查认证插件兼容性及php mysqli扩展启用状态。

mysqli 连不上,八成不是代码写错,而是 MySQL 服务没跑、扩展没启、权限配错或认证插件不兼容。
mysqli_connect() 报 Connection refused 怎么查
这个错误不是 PHP 的锅,是根本没连上 MySQL 进程。别急着改用户名密码,先确认基础通路是否畅通:
- 运行
sudo systemctl status mysql(Linux)或检查 Windows 服务里mysql是否“正在运行” - 用
telnet localhost 3306或nc -zv localhost 3306测试端口是否可连;不通就不用往下试了 - 检查 MySQL 配置文件(如
/etc/mysql/mysql.conf.d/mysqld.cnf)中bind-address是否为127.0.0.1或0.0.0.0;设成127.0.0.1时,localhost可能走 socket,而mysqli_connect()强制走 TCP,就会被拒 - PHP 8.2 + MySQL 8.0+ 默认用
caching_sha2_password插件,老版 mysqli 扩展不认——执行ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass';切回兼容模式
new mysqli() 后为什么 fetch_assoc() 报 warning
因为 mysqli_query() 不一定返回结果集:SELECT/SHOW/DESCRIBE 才返回 mysqli_result 对象;INSERT/UPDATE/DELETE 只返回 true 或 false。直接对布尔值调 fetch_assoc() 必然报错。
- 必须先判断
$result !== false,再确认是不是查询类语句 - 查不到数据时
mysqli_num_rows($result)返回0,但若$result === false,说明 SQL 语法错或表不存在,得用$conn->error拿真实错误信息 - 字符集没设也会导致查不到中文数据:连接后立刻调
$conn->set_charset('utf8mb4'),别依赖配置文件或连接字符串里的charset
mysqli_real_escape_string() 还能用吗
能用,但不推荐单独依赖它防注入。它只对字符串内容转义,无法处理表名、字段名、ORDER BY 方向等动态部分,且容易漏掉类型转换(比如 ID 拼进 SQL 时没 intval())。
- 真正安全的做法是预处理:
$stmt = $conn->prepare("SELECT * FROM user WHERE id = ?"),再用$stmt->bind_param('i', $id) -
bind_param()第一个参数是类型标识:i(整数)、s(字符串)、d(浮点),类型错配不会报错但绑定失败,后续execute()返回false - 表名/字段名这类不能预处理的部分,必须白名单校验:
in_array($table, ['user', 'post', 'tag'], true),别信任何正则过滤
面向对象和过程式 mysqli 哪个更稳
面向对象写法更稳。过程式靠一堆独立函数(mysqli_connect()、mysqli_query()、mysqli_fetch_assoc())串联,漏判一次返回值就崩;而面向对象把状态封装在 $conn 实例里,错误更集中、链式调用也更自然。
- 过程式必须每次检查:
if (!$conn = mysqli_connect(...)) die(mysqli_connect_error()),少一次就埋雷 - 面向对象下,
$conn->connect_error和$conn->error是现成属性,$conn->query()失败直接返回false,不会静默吞错 - 想复用连接对象切换数据库?用
$conn->select_db('other_db'),比新建实例轻量,也避免连接数打满
最常被忽略的其实是字符集和认证插件——连得上不代表能读对数据,尤其涉及 emoji 或新装 MySQL 8.x 时,这两处一错,调试半天都卡在“查不到”“乱码”这种表层现象上。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











