首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP 操作 MySQL 必知必會的 5 大陷阱與最佳實踐

     編輯:MySQL 資料庫相關知識

前言

PHP 與 MySQL 是經典黃金搭檔,但細節不慎極易踩坑。本文歸納 5 類高頻問題:分號處理、數據類型誤區、通配符用法、NULL 值陷阱、編碼亂碼,並給出現代最佳實踐(PDO/預處理/嚴格模式)。

一、分號的「例外」規則

1. PHP 代碼中嵌入 SQL 省略分號

// 錯誤示範:雙重分號導致解析錯誤
mysqli_query($conn, "INSERT INTO t (c) VALUES ('v');");

// 正確:PHP 端以分號結束,SQL 字串內不加分號
mysqli_query($conn, "INSERT INTO t (c) VALUES ('v')");

PHP 會自動為 SQL 語句補全終止符。

2. \G 結尾垂直顯示結果(僅限 MySQL 客戶端)

SELECT * FROM users WHERE id = 1\G

適用於命令行調試,程式碼中不可用。

二、數據類型常見誤區

誤區正確認知
TEXT 是獨立類型TEXT 實為 LONG VARCHAR / MEDIUMTEXT 別名
DATE 格式任意嚴格為 YYYY-MM-DD,PHP 用 date('Y-m-d') 生成
DATE 可直接相減得天數MySQL 需用 DATEDIFF(),PHP 端用 strtotime 計算
SET/ENUM 無上限SET 最多 64 個成員,ENUM 最多 65535 個;超限需拆多欄位

三、通配符與 LIKE 的正確姿勢

  • %:匹配任意長度字符,**必須搭配 LIKE** 使用。
  • _:匹配**單個**字符,同樣需配合 LIKE。
  • *:僅用於 SELECT * 選擇所有欄位,不屬於模糊匹配運算子。
-- 正確:查找姓名含「張」的用戶
SELECT * FROM users WHERE name LIKE '%張%';

-- 錯誤:WHERE name = '%張%'  -- 不會觸發模糊匹配

四、NOT NULL 與空值的微妙關係

  • 未聲明 NOT NULL:插入空值 → 存儲 NULL。
  • 聲明 NOT NULL:插入空值 → 報錯(嚴格模式)或存儲該類型的「零值」(非嚴格模式:數值 0、字串 ''、日期 '0000-00-00')。
  • ENUM 欄位聲明 NOT NULL 且無默認值時,插入空值會存儲第一個枚舉值(而非報錯)。

最佳實踐: 開啟 sql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,強制嚴格檢查。

五、編碼亂碼終極解決方案

  1. 資料庫/表/欄位統一 utf8mb4(支援 Emoji)。
  2. 連接建立後立即執行:SET NAMES utf8mb4(PDO 可在 DSN 指定 charset=utf8mb4)。
  3. PHP 檔案儲存為 UTF-8 無 BOM。
  4. HTML 頁面 <meta charset="utf-8">。

六、現代化開發建議:棄用 mysql_*,擁抱 PDO

$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,  // 真預處理
]);

$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
$stmt->execute([$name, $email]);

預處理徹底解決 SQL 注入、特殊字符轉義、分號干擾等歷史包袱。

七、總結

掌握分號規則、數據類型本質、通配符語法、NULL 語義、編碼鏈路五大核心,並全面遷移至 PDO + 預處理 + 嚴格模式,即可避開 90% 的 PHP-MySQL 開發坑點,寫出安全、高效、可維護的代碼。

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