PHP 5.5+ 棄用、PHP 7.0+ 移除 mysql_* 系列函數(mysql_connect、mysql_query 等),升級 MySQL 5.5 後出現 Deprecated: mysql_connect(): The mysql extension is deprecated... 警告。本文提供三級遷移方案。
Deprecated: mysql_connect(): The mysql extension is deprecated
and will be removed in the future: use mysqli or PDO instead
<?php
// 代碼開頭
error_reporting(E_ALL & ~E_DEPRECATED);
或修改 php.ini:
error_reporting = E_ALL & ~E_DEPRECATED
display_errors = Off # 生產環境建議關閉顯示
缺點:掩蓋問題,PHP 7+ 直接報致命錯誤,必須遷移。
<?php
// 連接
$mysqli = mysqli_connect('localhost', 'root', 'root', 'dbname')
or die('連接失敗: ' . mysqli_connect_error());
// 字符集(關鍵)
mysqli_set_charset($mysqli, 'utf8mb4');
// 查詢
$sql = "SELECT * FROM users WHERE status = 1";
$result = mysqli_query($mysqli, $sql) or die(mysqli_error($mysqli));
// 遍歷
while ($row = mysqli_fetch_assoc($result)) {
echo $row['name'] . '<br>';
}
// 釋放/關閉
mysqli_free_result($result);
mysqli_close($mysqli);
<?php
$mysqli = new mysqli('localhost', 'root', 'root', 'dbname');
if ($mysqli->connect_errno) die('連接失敗: ' . $mysqli->connect_error);
$mysqli->set_charset('utf8mb4');
// 預處理(防注入)
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param('i', $uid);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) { ... }
$stmt->close();
$mysqli->close();
<?php
$dsn = 'mysql:host=localhost;dbname=dbname;charset=utf8mb4';
$pdo = new PDO($dsn, 'root', 'root', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 真正預處理
]);
// 查詢
$stmt = $pdo->query("SELECT * FROM users WHERE status = 1");
foreach ($stmt as $row) { echo $row['name'] . '<br>'; }
// 預處理
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute(['張三', 'zhangsan@example.com']);
$lastId = $pdo->lastInsertId();
// 事務
$pdo->beginTransaction();
try {
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
throw $e;
}
| 特性 | mysqli | PDO |
|---|---|---|
| API 風格 | 雙模式 | 純 OO |
| 多数據庫支援 | 僅 MySQL | 12+ 驅動 |
| 預處理 | 支援 | 支援(模擬/原生可選) |
| 命名參數 | 不支援 | 支援 :name |
| 異步查詢 | 支援 | 不支援 |
| 學習曲線 | 低(兼容舊代碼) | 中 |
mysql_ 替換為 mysqli_ 或 PDOutf8mb4mysqli_begin_transaction / PDO::beginTransactionmysql_insert_id() → mysqli_insert_id($link) / $pdo->lastInsertId()mysql_num_rows() → mysqli_num_rows($result) / $stmt->rowCount()(僅對 SELECT 可靠)mysql_real_escape_string() → 棄用,改用預處理mysql_free_result() → mysqli_free_result() / 自動釋放mysql_* 已成歷史。新項目直接用 PDO;存量項目優先改 mysqli 面向過程風格,漸進式引入預處理。遷移核心是「預處理替代拼接,異常替代錯誤碼」,不僅修復棄用警告,更從根本上消除 SQL 注入風險。