萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 連接 MySQL 完整指南:從 mysql_* 到 mysqli 與 PDO

PHP 操作 MySQL 經歷了三個時代:已棄用的 mysql_*、改進的 mysqli、以及統一介面的 PDO。本文梳理演進脈絡,重點推薦現代最佳實踐。

歷史回顧:為何棄用 mysql_*

  • PHP 5.5 棄用,PHP 7.0 移除。
  • 不支持預處理語句,極易 SQL 注入。
  • 無面向對象介面,不支持事務、多語句、預處理等現代特性。

mysqli:MySQL 專用增強擴展

過程式風格

<?php
$mysqli = mysqli_connect('localhost', 'root', 'password', 'test_db');
if (mysqli_connect_errno()) {
    die('Connect Error: ' . mysqli_connect_error());
}
$result = mysqli_query($mysqli, "SELECT * FROM users WHERE id = 1");
$row = mysqli_fetch_assoc($result);
mysqli_free_result($result);
mysqli_close($mysqli);

面向對象風格(推薦)

$mysqli = new mysqli('localhost', 'root', 'password', 'test_db');
if ($mysqli->connect_errno) {
    die('Connect Error: ' . $mysqli->connect_error);
}

// 預處理語句(防注入核心)
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$email = 'test@example.com';
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) { /* ... */ }
$stmt->close();

PDO:資料庫抽象層(首選)

PDO 支持 12+ 資料庫驅動,統一 API,便於切換底層資料庫。

<?php
$dsn = 'mysql:host=localhost;dbname=test_db;charset=utf8mb4';
$opt = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false, // 使用真實預處理
];
$pdo = new PDO($dsn, 'root', 'password', $opt);

// 查詢
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
$users = $stmt->fetchAll();

// 事務
$pdo->beginTransaction();
try {
    $pdo->exec("INSERT ...");
    $pdo->exec("UPDATE ...");
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}

配置分離最佳實踐

<?php // config/database.php
return [
    'dsn'      => 'mysql:host=localhost;dbname=test_db;charset=utf8mb4',
    'username' => 'root',
    'password' => 'password',
    'options'  => [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ],
];
<?php // bootstrap.php
$config = require 'config/database.php';
$pdo = new PDO($config['dsn'], $config['username'], $config['password'], $config['options']);

關鍵避坑指南

  • 字符集:DSN 指定 charset=utf8mb4,支援 emoji。
  • 錯誤模式:PDO::ERRMODE_EXCEPTION 讓錯誤拋出異常,避免靜默失敗。
  • 真實預處理:ATTR_EMULATE_PREPARES => false 強制使用 MySQL 原生預處理,防注入更可靠。
  • 連接池:PHP-FPM 無原生連接池,可用 Swoole/RoadRunner 或 PgBouncer(PostgreSQL)解決高並發連接壓力。

結語

新專案直接使用 PDO,配合預處理語句、異常模式、配置分離,是現代 PHP 資料庫開發的標準姿勢。舊專案若仍在用 mysql_*,請盡快遷移至 mysqli 或 PDO。

copyright © 萬盛學電腦網 all rights reserved