[PHPのはじめ方] Part23: SELECT, INSERT, UPDATE, DELETEの実行

PHP

こんにちは!PHPでのデータベース操作のステップへようこそ。前の記事ではPDOを使ってデータベースに接続する方法を学びましたね。今回は、その接続を使って実際にデータを操作する基本的な方法、いわゆるCRUD操作(Create, Read, Update, Delete)を見ていきましょう。具体的には、SELECT(読み取り)、INSERT(作成)、UPDATE(更新)、DELETE(削除)の使い方を学びます。準備はいいですか? 🚀

この記事では、前回のステップで作成したデータベース接続オブジェクト $pdo がすでに存在することを前提として進めます。

SELECT: データの取得 🔍

データベースから情報を取得するには SELECT 文を使います。最も基本的な操作ですね。PDOでは主に query() メソッドや prepare()/execute() メソッドを使います。

単純な全件取得

テーブル内の全てのデータを取得する簡単な例を見てみましょう。ここでは `users` テーブルから全てのユーザーを取得します。

<?php
// 前提: $pdo が PDO インスタンスとして初期化済みであること

// SQL文を準備
$sql = "SELECT id, name, email FROM users";

// SQLを実行し、結果セット (PDOStatement オブジェクト) を取得
$stmt = $pdo->query($sql);

// 結果セットから全ての行を連想配列として取得
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);

// 結果を表示(例)
foreach ($users as $user) {
    echo "ID: " . htmlspecialchars($user['id'], ENT_QUOTES, 'UTF-8') . 
         ", Name: " . htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') . 
         ", Email: " . htmlspecialchars($user['email'], ENT_QUOTES, 'UTF-8') . "<br>";
}
?>

query() はSQL文を直接実行し、結果セットを表す PDOStatement オブジェクトを返します。fetchAll(PDO::FETCH_ASSOC) は、結果セットの全ての行を、カラム名をキーとする連想配列の配列として取得します。

条件を指定して取得 (WHERE句)

特定の条件に一致するデータだけを取得したい場合は WHERE 句を使います。ユーザーからの入力など、外部の値に基づいて条件を指定する場合は、プリペアドステートメントを使うことが非常に重要です。これはSQLインジェクション攻撃を防ぐための基本的な対策です(詳細は次回!)。

<?php
// 前提: $pdo が PDO インスタンスとして初期化済みであること

// 取得したいユーザーID (例: 外部からの入力)
$userId = 1; 

// SQL文を準備 (プレースホルダ :id を使用)
$sql = "SELECT id, name, email FROM users WHERE id = :id";

// ステートメントを準備
$stmt = $pdo->prepare($sql);

// プレースホルダに値をバインド
$stmt->bindValue(':id', $userId, PDO::PARAM_INT); // 型を指定 (整数)

// SQLを実行
$stmt->execute();

// 結果を1行だけ取得 (連想配列)
$user = $stmt->fetch(PDO::FETCH_ASSOC);

// 結果を表示(例)
if ($user) {
    echo "ID: " . htmlspecialchars($user['id'], ENT_QUOTES, 'UTF-8') . 
         ", Name: " . htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') . 
         ", Email: " . htmlspecialchars($user['email'], ENT_QUOTES, 'UTF-8');
} else {
    echo "ユーザーが見つかりませんでした。";
}
?>

ここでは prepare() でSQL文のテンプレートを準備し、bindValue() でプレースホルダ(:id)に安全な形で値を割り当て、execute() で実行しています。結果が1行だけの場合は fetch() を使うのが一般的です。

INSERT: データの挿入 ➕

新しいデータをテーブルに追加するには INSERT 文を使います。ユーザー登録や新しい投稿の保存などで頻繁に使用します。ここでもプリペアドステートメントの使用が必須です!

<?php
// 前提: $pdo が PDO インスタンスとして初期化済みであること

// 挿入するデータ (例: フォームからの入力)
$newName = "Taro Yamada";
$newEmail = "taro@example.com";

// SQL文を準備 (プレースホルダを使用)
$sql = "INSERT INTO users (name, email) VALUES (:name, :email)";

// ステートメントを準備
$stmt = $pdo->prepare($sql);

// プレースホルダに値をバインド
$stmt->bindValue(':name', $newName, PDO::PARAM_STR); // 文字列型
$stmt->bindValue(':email', $newEmail, PDO::PARAM_STR); // 文字列型

// SQLを実行
$success = $stmt->execute();

// 結果を確認
if ($success) {
    $lastId = $pdo->lastInsertId(); // 最後に挿入された行のIDを取得
    echo "新しいユーザーが追加されました。ID: " . htmlspecialchars($lastId, ENT_QUOTES, 'UTF-8') . " ✅";
} else {
    echo "ユーザーの追加に失敗しました。 ❌";
    // エラー情報を確認する場合
    // print_r($stmt->errorInfo());
}
?>

INSERT 文でも prepare(), bindValue(), execute() の流れは同じです。execute() は成功した場合に true、失敗した場合に false を返します。lastInsertId() メソッドを使うと、AUTO_INCREMENTなどで自動的に割り振られた主キーの値を取得できます。

UPDATE: データの更新 🔄

既存のデータを変更するには UPDATE 文を使います。ユーザー情報の編集などで使われます。UPDATE 文では、どのデータを更新するかを指定する WHERE 句が非常に重要です。忘れるとテーブル内の全ての行が更新されてしまう可能性があります!😱

⚠️ 注意: UPDATE 文や DELETE 文で WHERE 句を省略すると、意図せず全てのデータが変更・削除される可能性があります。必ず条件を指定してください。

<?php
// 前提: $pdo が PDO インスタンスとして初期化済みであること

// 更新するデータ (例: フォームからの入力)
$userIdToUpdate = 1;
$updatedName = "Jiro Suzuki";
$updatedEmail = "jiro@example.com";

// SQL文を準備 (プレースホルダを使用)
$sql = "UPDATE users SET name = :name, email = :email WHERE id = :id";

// ステートメントを準備
$stmt = $pdo->prepare($sql);

// プレースホルダに値をバインド
$stmt->bindValue(':name', $updatedName, PDO::PARAM_STR);
$stmt->bindValue(':email', $updatedEmail, PDO::PARAM_STR);
$stmt->bindValue(':id', $userIdToUpdate, PDO::PARAM_INT);

// SQLを実行
$success = $stmt->execute();

// 結果を確認
if ($success) {
    $rowCount = $stmt->rowCount(); // 影響を受けた行数を取得
    if ($rowCount > 0) {
        echo htmlspecialchars($rowCount, ENT_QUOTES, 'UTF-8') . " 件のユーザー情報が更新されました。 ✅";
    } else {
        echo "更新対象のユーザーが見つからないか、データに変更がありませんでした。";
    }
} else {
    echo "ユーザー情報の更新に失敗しました。 ❌";
    // print_r($stmt->errorInfo());
}
?>

UPDATE 文でもプリペアドステートメントを使います。execute() の成功後、rowCount() メソッドを使うと、実際に更新された行数を取得できます。更新対象が見つからなかった場合や、更新内容が元のデータと同じだった場合は 0 が返ることがあります。

DELETE: データの削除 🗑️

データをテーブルから削除するには DELETE 文を使います。ユーザーの退会処理などで利用します。DELETE 文でも WHERE 句は非常に重要です。指定しないと全てのデータが削除されてしまいます!

🚨 警告: DELETE 文の WHERE 句は絶対に省略しないでください!データの完全削除につながる可能性があります。

<?php
// 前提: $pdo が PDO インスタンスとして初期化済みであること

// 削除するユーザーID (例: 外部からの入力)
$userIdToDelete = 2; 

// SQL文を準備 (プレースホルダを使用)
$sql = "DELETE FROM users WHERE id = :id";

// ステートメントを準備
$stmt = $pdo->prepare($sql);

// プレースホルダに値をバインド
$stmt->bindValue(':id', $userIdToDelete, PDO::PARAM_INT);

// SQLを実行
$success = $stmt->execute();

// 結果を確認
if ($success) {
    $rowCount = $stmt->rowCount(); // 影響を受けた行数を取得
    if ($rowCount > 0) {
        echo htmlspecialchars($rowCount, ENT_QUOTES, 'UTF-8') . " 件のユーザーが削除されました。 ✅";
    } else {
        echo "削除対象のユーザーが見つかりませんでした。";
    }
} else {
    echo "ユーザーの削除に失敗しました。 ❌";
    // print_r($stmt->errorInfo());
}
?>

DELETE 文も同様にプリペアドステートメントを使用します。WHERE 句で削除対象を正確に指定することが極めて重要です。rowCount() で実際に削除された行数を確認できます。

今回はPDOを使ったデータベース操作の基本、CRUD(SELECT, INSERT, UPDATE, DELETE)について学びました。これらの操作はWebアプリケーション開発の根幹をなすものです。

  • SELECT データを取得する (query, prepare/execute, fetch, fetchAll)
  • INSERT 新しいデータを追加する (prepare/execute, lastInsertId)
  • UPDATE 既存データを更新する (prepare/execute, rowCount, WHERE句必須!)
  • DELETE データを削除する (prepare/execute, rowCount, WHERE句必須!)

特に重要なのは、INSERT, UPDATE, DELETE や、WHERE 句で外部からの値を使う場合にプリペアドステートメントを利用することです。これにより、危険なSQLインジェクション攻撃を防ぐことができます。

次のステップでは、このプリペアドステートメントとSQLインジェクション対策について、さらに詳しく掘り下げていきます。お楽しみに! 😉

コメント

タイトルとURLをコピーしました