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

PHP MySQL 插入資料完整指南:INSERT 語法、MySQLi/PDO 實作與安全最佳實務

     編輯:PHP 入門

PHP MySQL 插入資料深度解析:INSERT 語法規則、雙介面實作、自動遞增處理與安全防護

資料插入是資料庫操作最基礎也最關鍵的環節。本文系統性介紹 INSERT 語法規則、MySQLi (物件導向/程序式) 與 PDO 完整實作、AUTO_INCREMENT/TIMESTAMP 自動欄位處理、SQL 注入防護、錯誤處理與最佳實務。

INSERT 語法核心規則

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

自動處理欄位:AUTO_INCREMENT 與 TIMESTAMP

定義表結構時:

CREATE TABLE MyGuests (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    firstname VARCHAR(30) NOT NULL,
    lastname VARCHAR(30) NOT NULL,
    email VARCHAR(50),
    reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • id:插入時不指定,MySQL 自動產生唯一遞增值
  • reg_date:插入時不指定,自動填入當前時間戳
  • 也可明確指定 DEFAULT 關鍵字:INSERT ... VALUES (DEFAULT, 'John', ...)

MySQLi 物件導向實作

<?php
$host = 'localhost'; $user = 'username'; $pass = 'password'; $db = 'myDB';

$mysqli = new mysqli($host, $user, $pass, $db);
if ($mysqli->connect_error) {
    die("連線失敗: " . $mysqli->connect_error);
}

$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')";

if ($mysqli->query($sql) === true) {
    echo "新記錄插入成功";
    echo "自動產生 ID: " . $mysqli->insert_id; // 獲取 AUTO_INCREMENT 值
} else {
    echo "錯誤: " . $sql . "<br>" . $mysqli->error;
}

$mysqli->close();

MySQLi 程序式實作

$conn = mysqli_connect($host, $user, $pass, $db);
if (!$conn) {
    die("連線失敗: " . mysqli_connect_error());
}

$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')";

if (mysqli_query($conn, $sql)) {
    echo "新記錄插入成功";
    echo "自動產生 ID: " . mysqli_insert_id($conn);
} else {
    echo "錯誤: " . $sql . "<br>" . mysqli_error($conn);
}

mysqli_close($conn);

PDO 實作 (推薦)

<?php
$host = 'localhost'; $user = 'username'; $pass = 'password'; $db = 'myDBPDO';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 真實預處理

    $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com')";
    
    // exec() 用於無結果集的 INSERT/UPDATE/DELETE
    $affected = $pdo->exec($sql);
    echo "新記錄插入成功,影響行數: $affected";
    echo "自動產生 ID: " . $pdo->lastInsertId();
} catch (PDOException $e) {
    echo "錯誤: " . $sql . "<br>" . $e->getMessage();
}
$pdo = null;

安全插入:預處理語句 (必要實務)

絕不直接拼接變數到 SQL 字串。所有使用者輸入、外部資料必須使用參數綁定:

MySQLi 預處理插入

$stmt = $mysqli->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param('sss', $firstname, $lastname, $email);

$firstname = $_POST['firstname'] ?? '';
$lastname = $_POST['lastname'] ?? '';
$email = $_POST['email'] ?? '';

$stmt->execute();
echo "ID: " . $stmt->insert_id;
$stmt->close();

PDO 預處理插入 (命名佔位符)

$stmt = $pdo->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (:fn, :ln, :em)");
$stmt->bindValue(':fn', $firstname);
$stmt->bindValue(':ln', $lastname);
$stmt->bindValue(':em', $email);

$stmt->execute();
echo "ID: " . $pdo->lastInsertId();

進階插入模式

1. INSERT IGNORE:忽略重複鍵錯誤

INSERT IGNORE INTO users (email, name) VALUES ('a@b.com', 'John');
// email 有 UNIQUE 索引時,重複不報錯、不插入、不影響 auto_increment

2. ON DUPLICATE KEY UPDATE:衝突時更新 (Upsert)

INSERT INTO users (email, name, login_count) VALUES ('a@b.com', 'John', 1)
ON DUPLICATE KEY UPDATE login_count = login_count + 1, name = VALUES(name);

3. REPLACE INTO:刪除舊行插入新行

REPLACE INTO users (id, email, name) VALUES (1, 'a@b.com', 'John');
// 若 id=1 存在,先 DELETE 再 INSERT (auto_increment 不變)

4. 批次插入多筆 (單條 SQL)

$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ";
$values = [];
$params = [];
foreach ($guests as $g) {
    $values[] = "(?, ?, ?)";
    $params[] = $g['firstname'];
    $params[] = $g['lastname'];
    $params[] = $g['email'];
}
$sql .= implode(', ', $values);

$stmt = $mysqli->prepare($sql);
// 動態綁定參數需 call_user_func_array 或迴圈 bindParam
// PDO 較簡單:
$stmt = $pdo->prepare($sql);
$stmt->execute($params);

錯誤處理與除錯

規則說明
字串值必須用單引號包裹 'value'
數值不需引號 123, 45.67
NULL不需引號 NULL
日期時間字串格式 'YYYY-MM-DD HH:MM:SS'
欄位清單建議明確指定,避免結構變更導致錯誤
多筆插入VALUES (...), (...), (...) (單條 SQL)

最佳實務總結

  1. 永遠使用預處理語句:防注入、型別安全、計畫重用
  2. 明確指定欄位清單:INSERT INTO t (a,b) VALUES (...) 而非 INSERT INTO t VALUES (...)
  3. 交易包裹多筆操作:確保原子性、大幅提升效能
  4. 檢查影響行數:$stmt->affected_rows / $stmt->rowCount() 驗證預期結果
  5. 獲取自動 ID:insert_id / lastInsertId() 立即取得
  6. 錯誤模式設為例外:PDO ERRMODE_EXCEPTION,MySQLi 自行檢查或自定義例外包裝
  7. 關閉連線:腳本結束自動關閉,長執行程序手動 close()

總結

PHP MySQL 資料插入的核心在於安全參數化與正確錯誤處理。PDO 提供更現代、統一、例外導向的介面,是新專案首選。掌握 INSERT 變體 (IGNORE, ON DUPLICATE KEY UPDATE, REPLACE)、批次優化、交易控制,能應對從簡單表單提交到高併發資料寫入的各種場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤類型檢查方式常見原因
連線失敗$mysqli->connect_error / PDOException主機、帳號、密碼、資料庫名稱錯誤、防火牆
SQL 語法錯誤$mysqli->error / $e->getMessage()引號不匹配、保留字未跳脫、欄位名拼錯
重複鍵衝突錯誤碼 1062 (MySQLi) / 23000 (PDO)PRIMARY KEY/UNIQUE 重複
外鍵約束失敗錯誤碼 1452參考資料不存在
資料過長錯誤碼 1406VARCHAR 長度超限
NOT NULL 違反錯誤碼 1048必填欄位未提供