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

PHP MySQL INSERT 插入資料完整教學:從基礎到安全實踐

     編輯:PHP 綜合知識

INSERT 基礎語法

-- 指定欄位插入(推薦,順序不綁定表結構)
INSERT INTO table_name (column1, column2, column3) 
VALUES (value1, value2, value3);

-- 不指定欄位(需按表定義順序,不推薦生產用)
INSERT INTO table_name VALUES (value1, value2, value3);

-- 批次插入(單次 SQL,效能遠優於迴圈執行)
INSERT INTO table_name (col1, col2) VALUES
('a', 1), ('b', 2), ('c', 3);

-- 插入或更新(唯一鍵衝突時更新)
INSERT INTO table_name (id, name, email) VALUES (1, 'John', 'john@example.com')
ON DUPLICATE KEY UPDATE name=VALUES(name), email=VALUES(email);

PHP PDO 安全插入實作

單筆插入

<?php
$pdo = new PDO($dsn, $user, $pass, $options);

$stmt = $pdo->prepare("INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)");
$stmt->execute(['john_doe', 'john@example.com', password_hash('secret123', PASSWORD_DEFAULT)]);

$userId = $pdo->lastInsertId();
echo "新用戶 ID: $userId";

批次插入(交易 + 預處理)

<?php
$users = [
    ['alice', 'alice@example.com'],
    ['bob', 'bob@example.com'],
    ['charlie', 'charlie@example.com'],
];

$pdo->beginTransaction();
try {
    $stmt = $pdo->prepare("INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)");
    foreach ($users as $u) {
        $stmt->execute([$u[0], $u[1], password_hash('default_pass', PASSWORD_DEFAULT)]);
    }
    $pdo->commit();
    echo "批次插入成功,共 " . count($users) . " 筆";
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}

HTML 表單處理插入(完整範例)

<?php
// insert.php
require_once 'config.php';

$errors = [];
$success = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // CSRF 驗證(略)
    
    $firstName = trim($_POST['firstname'] ?? '');
    $lastName = trim($_POST['lastname'] ?? '');
    $age = (int)($_POST['age'] ?? 0);

    if ($firstName === '') $errors[] = '請輸入名字';
    if ($lastName === '') $errors[] = '請輸入姓氏';
    if ($age < 1 || $age > 120) $errors[] = '年齡需在 1-120 之間';

    if (empty($errors)) {
        try {
            $stmt = $pdo->prepare("INSERT INTO persons (first_name, last_name, age) VALUES (?, ?, ?)");
            $stmt->execute([$firstName, $lastName, $age]);
            $success = true;
            // PRG 模式重導向
            header('Location: insert.php?success=1');
            exit;
        } catch (PDOException $e) {
            error_log("Insert error: " . $e->getMessage());
            $errors[] = '資料庫錯誤,請稍後再試';
        }
    }
}
?>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>新增人員</title></head><body>
<h1>新增人員記錄</h1>

<?php if ($success || isset($_GET['success'])): ?>
    <div style="color:green">資料新增成功!</div>
<?php endif; ?>

<?php if ($errors): ?>
    <ul style="color:red"><?php foreach($errors as $e) echo "<li>".htmlspecialchars($e)."</li>"; ?></ul>
<?php endif; ?>

<form method="POST">
    <div><label>名字:<input type="text" name="firstname" required></label></div>
    <div><label>姓氏:<input type="text" name="lastname" required></label></div>
    <div><label>年齡:<input type="number" name="age" min="1" max="120" required></label></div>
    <button type="submit">送出</button>
</form>

<p><a href="list.php">查看所有記錄</a></p>
</body></html>

關鍵安全與最佳實踐

實踐說明
預處理語句prepare() + execute() 完全分離 SQL 邏輯與資料,防 SQL 注入
輸入驗證型別檢查、長度限制、格式驗證(Email、電話等)
輸出轉義HTML 輸出用 htmlspecialchars() 防 XSS
PRG 模式Post-Redirect-Get 避免重新整理重複提交
交易控制批次操作用 beginTransaction/commit/rollBack 保證原子性
錯誤處理捕捉 PDOException,記錄詳細錯誤,用戶端顯示友善訊息
字符集連接 DSN 指定 charset=utf8mb4

常見錯誤避坑

  • ❌ 直接拼接變數:"INSERT ... VALUES ('$_POST[name]')" → SQL 注入漏洞
  • ❌ 未驗證型別:年齡欄位存入字串導致資料髒汙
  • ❌ 忽略唯一約束錯誤:重複 Email 導致 23000 錯誤碼未處理
  • ❌ 自增 ID 依賴 mysql_insert_id() 舊函數 → 改用 $pdo->lastInsertId()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved