PHP 7.0+ 必须用 mysqli 或 PDO 连接 MySQL;mysqli_connect() 需判错并设 utf8mb4 字符集,PDO 需开启异常模式与正确 DSN;连接失败多因环境/权限问题,字符集和错误模式易被忽略却致乱码或静默失败。

用 mysqli_connect() 建立基础连接
PHP 7.0+ 已彻底移除 mysql_* 系列函数,必须改用 mysqli 或 PDO。最直接的方式是调用 mysqli_connect(),它返回一个连接资源或 false。
常见错误:连不上却没报错——因为默认关闭了错误提示。务必在连接后加判断:
if (!$conn = mysqli_connect('localhost', 'user', 'pass', 'db_name', 3306)) {
die('连接失败:' . mysqli_connect_error());
}
- 第 5 个参数(端口)可省略,默认 3306;但若 MySQL 运行在非标端口(如 Docker 映射为 3307),必须显式传入
3307 - 连接成功后建议立即设置字符集,避免中文乱码:
mysqli_set_charset($conn, 'utf8mb4') - 不要把密码硬编码在代码里,尤其上线后;应从环境变量或配置文件读取
用 PDO 实现更安全、可移植的连接
PDO 是面向对象方式,支持预处理语句、异常模式、多数据库切换,更适合现代项目。连接失败时默认静默,需手动开启异常模式:
$dsn = 'mysql:host=localhost;dbname=db_name;charset=utf8mb4';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, 'user', 'pass', $options);
} catch (PDOException $e) {
die('PDO 连接失败:' . $e->getMessage());
}
-
charset=utf8mb4必须写在$dsn里,仅靠setCharset()不保证连接初始化阶段的字符集正确 -
PDO::ATTR_ERRMODE设为EXCEPTION才能捕获连接/查询错误;默认是SILENT,出错只返回false - 若使用 Unix socket(如 MAMP、某些云服务),
$dsn应写成:mysql:unix_socket=/tmp/mysql.sock;dbname=db_name
连接失败的典型现象和排查点
不是代码写错,而是环境或权限问题导致连接中断,这类错误往往不报具体原因:
1.) 将所有文件解压到php环境中,本程序才用smarty+php+mysql设计。如果运行不了,请修改hhy文件夹下的smarty.php文件改法请看说明2.) 修改configs下的config.inc.php下的连接数据库的密码和用户名3.) 本程序没有做安全页面,人工导入sql.inc到mysql数据库。管理员初始化帐号为admin,密码为hhy。后台地址:http://你的网站地址/h
立即学习“PHP免费学习笔记(深入)”;
- 报错
Connection refused:MySQL 服务未运行,或bind-address配置为127.0.0.1却尝试用localhost连(注意:PHP 中localhost会走 socket,而127.0.0.1走 TCP) - 报错
Access denied for user:用户名密码错、用户无远程访问权限(检查GRANT是否含@'%'或对应 IP)、或 MySQL 8 默认认证插件是caching_sha2_password,旧版 PHP 不兼容(需改用mysql_native_password) - 超时无响应:防火墙拦截、云服务器安全组未放行 3306、或连接池耗尽(尤其短连接高频请求时)
别忽略连接生命周期管理
PHP 脚本结束时连接自动释放,但显式关闭更可控,尤其在长脚本或 CLI 场景下:
- 对
mysqli:用mysqli_close($conn);不关也不会泄漏,但高并发下可能提前触达连接数上限 - 对
PDO:设$pdo = null或让对象超出作用域即可;调用$pdo = null后再访问会报致命错误,适合强制清理 - 如果用连接池(如 Swoole、RoadRunner),不能依赖脚本结束自动释放,必须手动
close()或归还到池中
真正容易被忽略的是字符集和错误模式——它们不报错,但会让后续查询结果错位、乱码或静默失败,调试成本远高于写两行初始化代码。










