PDOでMySQLへ接続する前の準備
この記事の例では、PHP 8.xとMySQL 8.0を想定します。環境によって設定や利用できる機能が異なるため、実際のバージョンと権限を確認してください。接続には、ホスト名、データベース名、ユーザー名、パスワードが必要です。次のSQLで、識別子・名前・メールアドレスを持つサンプルテーブルを作成します。文字コードにはutf8mb4を指定します。
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
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(更新) | UPDATE | WHERE句で対象行を限定する |
| Delete(削除) | DELETE | 条件を指定し、意図しない全件削除を防ぐ |
CRUD処理で確認したいエラー処理と安全対策
PDOExceptionの詳細は画面に表示せず、開発者向けのログへ記録します。画面には利用者が理解できる一般的なメッセージだけを返してください。複数のSQLを一連の処理として扱う場合は、beginTransaction()、commit()、rollBack()を使ったトランザクションを検討します。Webアプリケーションでは、認証・認可、CSRF対策、出力時のエスケープも別途必要です。
CRUD処理の動作を確認する
- テスト用の名前とメールアドレスを登録し、取得結果を確認します。
- 登録時に得たidを使って名前を更新し、再度SELECTして変更を確認します。
- 同じidを条件に削除し、削除後に取得できないことを確認します。
- 存在しないid、不正なメールアドレス、重複したメールアドレスを指定した場合のエラーも確認します。