PHPでSELECT文で読み込んで、UPDATE文で更新しよう

フォルダとファイル名

php-db フォルダに db04.php を作成します。
この回では、既存データの更新(UPDATE)を学びます。

基本コード(db04.php)

このファイルでは、データベースにあるユーザー情報(users テーブル)の中から、選択された ID に一致するレコードを 名前・メールアドレスの2つの内容で更新します。

  1. 最初に、すべてのユーザー一覧を SELECT して表示します。
  2. 下部にある フォームにID・名前・メールを入力して送信します。
  3. POSTされた内容を元に、該当IDのデータを UPDATE します。
<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'root';
$password = '';

function h($str)
{
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

// 接続と初期化
try {
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $msg = '';

    // フォームから更新が送信された場合
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $id = $_POST['id'] ?? '';
        $name = $_POST['name'] ?? '';
        $email = $_POST['email'] ?? '';

        $stmt = $pdo->prepare("UPDATE users SET name = ?, email = ? WHERE id = ?");
        $stmt->execute([$name, $email, $id]);
        $msg = "ID {$id} を更新しました。";
    }

    // 一覧を取得
    $stmt = $pdo->query("SELECT * FROM users ORDER BY id ASC");
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    echo "エラー:" . $e->getMessage();
    exit;
}
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>ユーザー一覧(更新機能付き)</title>
    <style>
        table {
            border-collapse: collapse;
            margin-bottom: 1em;
        }

        th,
        td {
            border: 1px solid #666;
            padding: .5em 1em;
        }

        form {
            margin-top: 2em;
        }
    </style>
</head>

<body>
    <h1>ユーザー一覧</h1>

    <?php if ($msg): ?>
        <p><strong><?= h($msg) ?></strong></p>
    <?php endif; ?>

    <table>
        <tr>
            <th>ID</th>
            <th>名前</th>
            <th>メール</th>
            <th>登録日</th>
        </tr>
        <?php foreach ($rows as $row): ?>
            <tr>
                <td><?= h($row['id']) ?></td>
                <td><?= h($row['name']) ?></td>
                <td><?= h($row['email']) ?></td>
                <td><?= h($row['created_at']) ?></td>
            </tr>
        <?php endforeach; ?>
    </table>

    <h2>IDを指定して更新</h2>
    <form method="post">
        <label>ID:
            <input type="number" name="id" required value="1">
        </label><br>
        <label>名前:
            <input type="text" name="name" required>
        </label><br>
        <label>メール:
            <input type="email" name="email" required>
        </label><br>
        <button type="submit">更新する</button>
    </form>
</body>

</html>

更新用のフォーム(POST)

<form action="" method="post">
  <input type="number" name="id" placeholder="更新するID" required>
  <input type="text" name="name" placeholder="名前" required>
  <input type="email" name="email" placeholder="メールアドレス" required>
  <button type="submit">更新する</button>
</form>
  • ID でどのレコードを更新するかを指定します。
  • 名前・メールは新しい内容に変更する値です。
  • このフォームから送られるデータが $_POST に入ります。

UPDATE処理

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $id    = (int)($_POST['id'] ?? 0);
    $name  = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');

    if ($id > 0 && $name !== '' && $email !== '') {
        $stmt = $pdo->prepare("UPDATE users SET name = ?, email = ? WHERE id = ?");
        $stmt->execute([$name, $email, $id]);

        echo "ID {$id} を更新しました(更新件数:" . $stmt->rowCount() . " 件)<br>";
    } else {
        echo "入力内容に不備があります。<br>";
    }
}
  • POSTが送られた時だけ処理が動きます。
  • name, email, id の3つをバインドして SQL を実行。
  • rowCount() で、実際に更新された件数を表示します。
  • id が存在しない場合は「0件」となり、更新されません。

最初のSELECTの役割

$stmt = $pdo->query("SELECT * FROM users ORDER BY id ASC");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  • ページ読み込み時、常に全ユーザーの一覧を表示。
  • どのIDを更新するか、確認しやすくなっています。

注意点・ポイント

項目解説
WHERE句の使用UPDATE文には必ず WHERE id = ? を付けましょう。全件更新を防ぎます。
バリデーション空文字チェックや id > 0 などの簡易チェックは重要です。
rowCount()更新件数の確認に使えます。0件なら「該当IDなし」の可能性も。
htmlspecialchars()表示時には必ず h() 関数でエスケープしましょう。

大事なまとめ

  • UPDATEDELETEWHERE が命。付け忘れは致命傷。
  • 値は プレースホルダ + execute で安全に渡す。
  • 実行後は rowCount() で結果を確認。
  • 更新・削除前に SELECTで対象を確認するのが安全な手順。