PHP

PHPのPDOでMySQLに接続してCRUD処理を実装する

PHPのPDOを使ってMySQLへ接続し、データの登録・取得・更新・削除を実装する基本手順を、初心者向けに整理します。

この記事でわかること

  • PDOを使ったPHPからMySQLへの接続方法がわかる
  • SQLインジェクションを防ぐ基本としてプリペアドステートメントを使える
  • 登録・取得・更新・削除のCRUD処理を実装する流れを理解できる

PDOでMySQLへ接続する前の準備

この記事の例では、PHP 8.xとMySQL 8.0を想定します。環境によって設定や利用できる機能が異なるため、実際のバージョンと権限を確認してください。接続には、ホスト名、データベース名、ユーザー名、パスワードが必要です。次のSQLで、識別子・名前・メールアドレスを持つサンプルテーブルを作成します。文字コードにはutf8mb4を指定します。

SQL
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- usersテーブルが作成されます。

PHPからPDOでMySQLへ接続する

PDOでは、DSNに接続先と文字コードを指定します。例外を利用する設定にすると、接続やSQL実行時の失敗をcatchで処理できます。パスワードなどの接続情報は、実運用では環境変数や安全な設定ファイルで管理してください。

PHP
<?php
declare(strict_types=1);

$dsn = 'mysql:host=127.0.0.1;dbname=sample_db;charset=utf8mb4';
$user = getenv('DB_USER') ?: 'app_user';
$password = getenv('DB_PASSWORD') ?: 'change_me';

try {
    $pdo = new PDO($dsn, $user, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]);

    // Create: 登録
    $stmt = $pdo->prepare(
        'INSERT INTO users (name, email) VALUES (:name, :email)'
    );
    $stmt->execute([
        'name' => '山田太郎',
        'email' => 'taro@example.com',
    ]);
    $userId = (int) $pdo->lastInsertId();

    // Read: 取得
    $stmt = $pdo->prepare(
        'SELECT id, name, email FROM users WHERE id = :id'
    );
    $stmt->execute(['id' => $userId]);
    $userData = $stmt->fetch();

    // Update: 更新
    $stmt = $pdo->prepare(
        'UPDATE users SET name = :name WHERE id = :id'
    );
    $stmt->execute(['name' => '山田次郎', 'id' => $userId]);

    // Delete: 削除
    $stmt = $pdo->prepare('DELETE FROM users WHERE id = :id');
    $stmt->execute(['id' => $userId]);

    // 期待される状態: INSERT、SELECT、UPDATE、DELETEが順に実行される
} catch (PDOException $e) {
    error_log($e->getMessage());
    // 利用者には接続情報やSQLの詳細を表示しない
    echo 'データベース処理に失敗しました。';
}

データを登録・取得する処理を実装する

INSERTでは、SQL文にユーザー入力を直接連結せず、名前付きプレースホルダーへ値を渡します。SELECTの結果を複数行取得する場合はfetchAll()、1行だけ取得する場合はfetch()を使い分けます。メールアドレスの形式や必須項目は、SQL実行前にPHP側でも検証してください。データベース側のNOT NULLやUNIQUE制約も、最後の安全策として機能します。

データを更新・削除する処理を実装する

UPDATEとDELETEでは、WHERE句に識別子などの条件を必ず指定します。条件を省略すると、テーブル内の全行が対象になる可能性があります。execute()後にrowCount()を確認すれば、処理の対象になった行数を確認できます。

処理SQL主な注意点
Create(登録)INSERT入力値をプレースホルダーへ渡す
Read(取得)SELECT取得件数や表示時のエスケープを確認する
Update(更新)UPDATEWHERE句で対象行を限定する
Delete(削除)DELETE条件を指定し、意図しない全件削除を防ぐ
CRUD処理の対応関係

CRUD処理で確認したいエラー処理と安全対策

PDOExceptionの詳細は画面に表示せず、開発者向けのログへ記録します。画面には利用者が理解できる一般的なメッセージだけを返してください。複数のSQLを一連の処理として扱う場合は、beginTransaction()、commit()、rollBack()を使ったトランザクションを検討します。Webアプリケーションでは、認証・認可、CSRF対策、出力時のエスケープも別途必要です。

CRUD処理の動作を確認する

  1. テスト用の名前とメールアドレスを登録し、取得結果を確認します。
  2. 登録時に得たidを使って名前を更新し、再度SELECTして変更を確認します。
  3. 同じidを条件に削除し、削除後に取得できないことを確認します。
  4. 存在しないid、不正なメールアドレス、重複したメールアドレスを指定した場合のエラーも確認します。

参考