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

五大常見 PHP 資料庫問題與解決方案

     編輯:PHP 相關知識

前言

資料庫操作是 PHP 應用的核心,但錯誤的設計與存取模式往往導致安全漏洞、效能瓶頸與維護噩夢。本文剖析五大典型問題,並提供現代化的解決路徑。

問題一:直接使用已棄用的 mysql_* 函數

風險:PHP 7.0 移除此擴展;無預處理語句,極易遭 SQL 注入;硬編碼資料庫類型,遷移困難。

// 錯誤示範
$db = mysql_connect('localhost', 'root', 'password');
mysql_select_db('users');
$res = mysql_query("SELECT id FROM users WHERE login='$name'");

解決方案:改用 PDO 或 MySQLi,啟用預處理語句:

// PDO 範例
$dsn = 'mysql:host=localhost;dbname=users;charset=utf8mb4';
$pdo = new PDO($dsn, 'root', 'password', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
$stmt = $pdo->prepare('SELECT id FROM users WHERE login = ?');
$stmt->execute([$name]);
$user = $stmt->fetch();
  • 參數綁定自動防禦 SQL 注入。
  • 資料庫抽象層便於未來切換 PostgreSQL、SQLite 等。

問題二:缺乏索引導致全表掃描

現象:查詢緩慢,EXPLAIN 顯示 type: ALL。

對策:

  1. 為 WHERE、JOIN、ORDER BY 條件欄位建立索引。
  2. 使用複合索引匹配多欄位查詢(注意最左前綴原則)。
  3. 定期 ANALYZE TABLE 更新統計資訊。
  4. 避免在索引欄位上使用函數(如 WHERE YEAR(created_at) = 2023)。

問題三:N+1 查詢問題

場景:迴圈中重複查詢關聯資料。

// 錯誤:N+1
$posts = $pdo->query('SELECT * FROM posts')->fetchAll();
foreach ($posts as $post) {
    $author = $pdo->query("SELECT * FROM users WHERE id = {$post['user_id']}")->fetch();
}
// 正確:Eager Loading / JOIN
$posts = $pdo->query('
    SELECT p.*, u.name AS author_name
    FROM posts p
    JOIN users u ON p.user_id = u.id
')->fetchAll();

問題四:未使用事務保證資料一致性

風險:多表寫入局部失敗導致資料不一致。

$pdo->beginTransaction();
try {
    $pdo->exec("INSERT INTO orders ... ");
    $pdo->exec("UPDATE inventory SET qty = qty - 1 WHERE product_id = ?", [$pid]);
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}

問題五:硬編碼 SQL 分散在業務邏輯中

後果:難以測試、重構、審計。

建議:

  • 採用 Repository 模式 封裝資料存取。
  • 或使用 ORM(如 Doctrine, Eloquent, Laravel Eloquent)提升抽象層級。
  • 複雜查詢集中管理,便於優化與審計。

總結檢查清單

  • [ ] 已棄用 mysql_* 函數
  • [ ] 所有用戶輸入經參數綁定
  • [ ] 關鍵查詢有 EXPLAIN 驗證索引
  • [ ] 關聯資料採用 JOIN 或批次載入
  • [ ] 多步寫入包裹在事務中
  • [ ] SQL 集中管理,業務層不直接寫 SQL
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved