背景:為什麼必須遷移到 Mysqli
mysql_* 系列函數自 PHP 5.5 棄用,PHP 7.0 完全移除。
- Mysqli 提供:**面向對象 + 面向過程** 雙 API、**預處理語句** 防注入、**事務控制**、性能更優、支援 MySQL 5.1+ 新特性。
安裝與驗證
# php.ini
extension=php_mysqli.dll
extension_dir = "C:/php/ext" # 指向 ext 目錄
# 重啟 Web 服務器後驗證
php -m | grep mysqli
# 或
php -r "var_dump(extension_loaded('mysqli'));"
面向對象核心類與方法速查
| 類 | 核心方法/屬性 | 說明 |
| mysqli | connect_errno, connect_error, set_charset(), query(), prepare(), begin_transaction(), commit(), rollback(), affected_rows, insert_id, close() | 連接對象 |
| mysqli_result | fetch_all(), fetch_assoc(), fetch_row(), fetch_object(), data_seek(), free(), num_rows | 結果集對象 |
| mysqli_stmt | bind_param(), bind_result(), execute(), fetch(), close() | 預處理語句對象 |
完整 CRUD 範例(面向對象風格)
connect_errno) {
throw new Exception("Connect Error: {$mysqli->connect_error}");
}
// 2. 設置字符集(防止中文亂碼)
$mysqli->set_charset('utf8mb4');
// 3. 查詢:返回 mysqli_result 對象
$sql = "SELECT id, title FROM test";
$result = $mysqli->query($sql);
if (!$result) {
throw new Exception("Query Error: {$mysqli->error}");
}
// 4. 獲取所有行為關聯數組(MYSQLI_ASSOC / MYSQLI_NUM / MYSQLI_BOTH)
$rows = $result->fetch_all(MYSQLI_ASSOC);
print_r($rows);
// 5. 指針移動與單行讀取
$result->data_seek(2); // 移至第 3 行(0 基)
$row = $result->fetch_assoc(); // 關聯數組
// $row = $result->fetch_row(); // 索引數組
// $row = $result->fetch_object(); // 對象
// 6. 釋放結果集
$result->free();
// 7. 寫入操作:INSERT / UPDATE / DELETE
$insertSql = "INSERT INTO test (title) VALUES (?)";
$stmt = $mysqli->prepare($insertSql);
$stmt->bind_param('s', $title); // s=string, i=integer, d=double, b=blob
$title = 'Mysqli 測試';
$stmt->execute();
echo "受影響行數: {$stmt->affected_rows}, 新增 ID: {$mysqli->insert_id}";
$stmt->close();
// 8. 事務控制
$mysqli->begin_transaction();
try {
$mysqli->query("UPDATE test SET title='A' WHERE id=1");
$mysqli->query("UPDATE test SET title='B' WHERE id=2");
$mysqli->commit();
} catch (Exception $e) {
$mysqli->rollback();
throw $e;
}
// 9. 關閉連接
$mysqli->close();
關鍵細節提示
query() 執行 SELECT/SHOW/DESCRIBE/EXPLAIN 返回 mysqli_result,其他返回 true/false。
fetch_all() 一次性讀取全部結果到內存,**大結果集慎用**,改用 fetch_assoc() 循環流式處理。
- 預處理
bind_param() 類型字符:i(int) d(double) s(string) b(blob),**必須與參數個數完全對應**。
affected_rows:-1 表示 SQL 錯誤,0 無影響行,>0 影響行數。
- 異常處理:建議啟用
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) 讓錯誤自動拋出異常。
進階主題預告
- 多語句執行:
multi_query() + next_result()。
- 預處理批量綁定:
bind_param 配合數組循環執行。
- 事務隔離級別設置:
$mysqli->query("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED")。