首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 連接 MySQL 資料庫:從 mysql_connect 到 PDO 的完整遷移指南

     編輯:PHP 綜合知識

學習目標

  • 理解資料庫連線的三要素:DSN、認證、選項
  • 掌握 PDO 連線建立、錯誤處理、字元集設定
  • 認識舊版 mysql_connect/mysql_select_db 的棄用時間線與替代方案

舊版寫法 (PHP 4/5 早期)

<?php
$conn = mysql_connect("127.0.0.1", "user", "pass");
mysql_select_db("shop", $conn);
// 執行查詢...
mysql_close($conn);
?>

狀態: PHP 5.5 起棄用,PHP 7.0 完全移除。嚴禁用於新專案。

過渡版:MySQLi 程序風格 (相容舊習慣)

<?php
$mysqli = mysqli_connect("127.0.0.1", "user", "pass", "shop");
if (!$mysqli) {
    die("連線失敗: " . mysqli_connect_error());
}
mysqli_set_charset($mysqli, "utf8mb4");
// 查詢: mysqli_query($mysqli, $sql)
// 關閉: mysqli_close($mysqli);
?>

優點:函式風格熟悉、支援預備陳述式。缺點:非物件導向、錯誤處理分散。

現代標準:PDO (PHP Data Objects) —— 強烈推薦

1. DSN (Data Source Name) 格式

mysql:host=127.0.0.1;port=3306;dbname=shop_db;charset=utf8mb4
  • host:主機 IP 或域名
  • port:連接埠 (預設 3306,可省略)
  • dbname:資料庫名稱
  • charset:關鍵,直接在 DSN 設定避免後續 SET NAMES 注入風險

2. 連線選項 (第四參數) —— 專業級配置

$options = [
    // 錯誤模式:拋出 PDOException,統一 try-catch 處理
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    
    // 預設擷取模式:關聯陣列 (FETCH_ASSOC),也可用 FETCH_OBJ
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    
    // 關閉模擬預備陳述式,使用 MySQL 原生 Prepared Statement (安全、效能)
    PDO::ATTR_EMULATE_PREPARES => false,
    
    // 持久連線 (視架構評估,預設 false)
    // PDO::ATTR_PERSISTENT => true,
    
    // 例外情況下自動回滾 (需搭配交易使用)
    // PDO::ATTR_STRINGIFY_FETCHES => false,
];

3. 完整連線範本 (生產環境就緒)

<?php
// config/database.php
return [
    'dsn'      => 'mysql:host=127.0.0.1;dbname=shop_db;charset=utf8mb4',
    'username' => 'app_user',
    'password' => 'secure_password',
    'options'  => [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ],
];

// bootstrap/db.php
$config = require __DIR__ . '/../config/database.php';
try {
    $pdo = new PDO(
        $config['dsn'],
        $config['username'],
        $config['password'],
        $config['options']
    );
    // 可選:設定時區
    $pdo->exec("SET time_zone = '+08:00'");
    return $pdo;
} catch (PDOException $e) {
    // 記錄完整錯誤到日誌系統
    error_log("[DB] Connection failed: " . $e->getMessage());
    // 使用者端顯示友善訊息
    if (php_sapi_name() !== 'cli') {
        http_response_code(503);
        exit('服務暫時不可用,請稍後再試');
    }
    throw $e;
}
?>

常見問題與解決方案

錯誤現象原因解決
SQLSTATE[HY000] [2002] Connection refusedMySQL 服務未啟動/host/port 錯誤/防火牆阻擋檢查服務狀態、netstat -an | grep 3306、安全組規則
SQLSTATE[HY000] [1045] Access denied帳號密碼錯誤/權限不足/主機白名單限制確認 user@host 權限、FLUSH PRIVILEGES
亂碼 / 儲存 ???字元集不一致DSN 加 charset=utf8mb4、資料表/欄位 CHARSET=utf8mb4、連線選項 SET NAMES
PDOException: could not find driverPHP 未安裝 pdo_mysql 擴充套件安裝 php-pdo_mysql (Linux) / 開啟 extension=pdo_mysql (Windows php.ini)

最佳實踐清單

  1. 單一進入點:全專案共用一個 getPdo() 工廠函式/容器綁定,避免重複連線。
  2. 設定外部化:DSN、帳密放入 .env 或 config/,絕不寫死在程式碼。
  3. 最小權限原則:應用程式帳號僅擁有必要資料庫的 SELECT/INSERT/UPDATE/DELETE,無 DROP/ALTER/GRANT。
  4. 連線池/持久連線評估:PHP-FPM + 持久連線易導致「Too many connections」,高併發建議搭配 ProxySQL 或應用層連線池。
  5. 錯誤不外露:生產環境 display_errors=Off,例外內容僅寫入日誌。

結語

資料庫連線是應用程式的生命線。採用 PDO + 完善的錯誤處理 + 設定外部化 + 最小權限,能為後續開發奠定穩固、安全、可維護的基礎。下一課將進入「資料庫讀取與預備陳述式」實戰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved