PHP

データベース

PDOを使ってデータを安全に保存・検索・更新しましょう。

01

データベースとは

データベースは、決まった構造で大量のデータを保存し、必要なデータを検索できる仕組みです。PHPではPDOという共通インターフェースからMySQLやSQLiteなどを操作できます。

SQL役割
INSERTデータを追加する
SELECTデータを取得する
UPDATEデータを更新する
DELETEデータを削除する
02

PDOで接続する

まずはセットアップが簡単なSQLiteへ接続します。PDOのエラーモードを例外に設定すると、失敗を見逃しにくくなります。

接続とテーブル作成PHP
$pdo = new PDO('sqlite:' . __DIR__ . '/app.sqlite', null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

$pdo->exec(
    'CREATE TABLE IF NOT EXISTS tasks (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        created_at TEXT NOT NULL
    )'
);
データベースによる違い このSQLはSQLite向けです。PDOの基本的な操作方法は共通でもSQLの一部は異なり、MySQLで自動採番する列は、たとえば id INT AUTO_INCREMENT PRIMARY KEY のように定義します。接続先のデータベースに合ったSQLを確認してください。
03

データを追加する

入力値をSQLへ埋め込まず、プレースホルダーを使ったプリペアドステートメントで渡します。

INSERTPHP
$title = 'PHPを復習する';
$statement = $pdo->prepare(
    'INSERT INTO tasks (title, created_at) VALUES (:title, :created_at)'
);
$statement->execute([
    ':title' => $title,
    ':created_at' => date('Y-m-d H:i:s'),
]);
重要 SQLと値を文字列連結するとSQLインジェクションの原因になります。値は必ずプレースホルダーで渡します。
04

データを取得する

SELECTPHP
$statement = $pdo->query(
    'SELECT id, title, created_at FROM tasks ORDER BY id DESC'
);
$tasks = $statement->fetchAll();

foreach ($tasks as $task) {
    echo htmlspecialchars($task['title'], ENT_QUOTES, 'UTF-8');
}

1件だけ取得する場合は fetch()、複数件なら fetchAll() を使います。

05

更新・削除する

UPDATE / DELETEPHP
$statement = $pdo->prepare(
    'UPDATE tasks SET title = :title WHERE id = :id'
);
$statement->execute([':title' => 'PDOを復習する', ':id' => 1]);

$statement = $pdo->prepare('DELETE FROM tasks WHERE id = :id');
$statement->execute([':id' => 1]);
注意 UPDATEDELETEWHERE を忘れると全行が対象になります。
06

トランザクション

複数の更新を「すべて成功」または「すべて取り消し」にしたい場合は、トランザクションを使います。

トランザクションPHP
try {
    $pdo->beginTransaction();
    // 複数のINSERTやUPDATE
    $pdo->commit();
} catch (Throwable $error) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    throw $error;
}
PRACTICE

ミニ課題:ToDoリスト

タスクの追加・一覧・編集・削除ができるページを作りましょう。入力確認、プリペアドステートメント、表示時のエスケープをすべて行ってください。