<p>PHP 5.6 升级到 7.0 后,mysql_* 函数被彻底移除,调用即报 Fatal error;不能只改函数名,因 mysqli/PDO 的连接管理、参数顺序、字符集设置、错误模式及资源生命周期均不同,须重构数据访问层。</p>

PHP 5.6 升级到 7.0 后,mysql_* 系列函数**被彻底移除**,不是警告、不是弃用,是直接 fatal error——调用 mysql_connect() 就会报 Fatal error: Uncaught Error: Call to undefined function mysql_connect()。必须替换,没有绕过选项。
为什么不能只改函数名?
单纯把 mysql_connect() 换成 mysqli_connect() 只是第一步。mysql_* 是面向过程 API,而 mysqli 支持面向过程和面向对象两种风格,且参数顺序、错误处理、资源管理逻辑完全不同。更关键的是:mysql_real_escape_string() 没有“一对一”替代函数,强行套用 mysqli_escape_string() 会漏掉连接上下文,导致 SQL 注入风险。
-
mysql_connect($host, $user, $pass)→ 必须带连接句柄传给后续函数(如mysql_query($conn, $sql)) -
mysqli_connect($host, $user, $pass)返回连接对象,但mysqli_query()可以不传句柄(使用最近一次连接),这容易掩盖多连接场景下的 bug -
mysql_real_escape_string($str, $conn)依赖当前连接的字符集;mysqli_real_escape_string($conn, $str)参数顺序反了,且必须显式传入有效连接
推荐迁移路径:优先用 PDO,其次用 mysqli 面向对象
PDO 更抽象、更安全、更易测试,且能平滑支持未来换数据库。mysqli 面向对象写法也比过程式更清晰。避免混用过程式 mysqli_* 函数——它保留了旧习惯,反而增加出错概率。
- 统一入口初始化连接:
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', $user, $pass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); - 查询直接用预处理(杜绝拼接):
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ? AND status = ?'); $stmt->execute([$id, $status]); $user = $stmt->fetch(); - 若坚持用 mysqli,强制用对象式:
$mysqli = new mysqli($host, $user, $pass, $db); $stmt = $mysqli->prepare('INSERT INTO log (msg) VALUES (?)'); $stmt->bind_param('s', $msg); $stmt->execute();
最容易被忽略的三个细节
很多项目改完函数就上线,结果第二天数据库乱码、登录失败、搜索失灵——问题往往藏在这三处:
立即学习“PHP免费学习笔记(深入)”;
-
字符集没显式声明:PHP 7.0+ 默认不继承 MySQL 服务端配置。PDO DSN 必须加
charset=utf8mb4,mysqli 构造后必须立刻调用$mysqli->set_charset('utf8mb4'),否则中文存取全乱 -
错误模式未开启:默认
PDO::ERRMODE_SILENT,SQL 错误静默失败。必须设为PDO::ERRMODE_EXCEPTION,否则你永远不知道哪条语句没执行 -
资源未释放或连接未关闭:
mysql_close()是显式调用的,但 PDO 连接在对象销毁时自动关闭——如果长期持有$pdo实例又没做连接池,高并发下可能耗尽 MySQL 连接数
迁移不是函数替换练习,而是数据访问层的重构。哪怕只改一个 mysql_query(),也要同步检查它的连接来源、字符集、错误处理、资源生命周期——漏掉任意一环,都可能让 PHP 7.0 的性能优势变成线上事故的加速器。



















