ch10 12章中 10章目

ch10 — DSN 比較 / 複数 DB 接続

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch10 — DSN 比較 / 複数 DB 接続」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch10 — DSN 比較 / 複数 DB 接続」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch10 — DSN 比較 / 複数 DB 接続」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

PDO の真価は、「同じ PHP コードで複数の DB を扱える」 ところにある。SELECT / INSERT / prepare / execute はすべて DB 種類に依存しない API なので、接続時の DSN を切り替えるだけ で SQLite / MySQL / PostgreSQL を行き来できる。開発は SQLite で気軽に動かし、本番では MySQL や PostgreSQL に切り替える運用が当たり前にできる。

DSN は DB ごとに記法が違う: sqlite:/path/to.db / mysql:host=...;dbname=...;charset=utf8mb4 / pgsql:host=...;dbname=...。実務では DSN・ユーザ名・パスワードを 環境変数 で外出しし、コードに DB 種類を埋め込まない設計にする。

ただし「DSN だけで動く」のは 標準 SQL の範囲のみAUTO_INCREMENT / SERIAL / RETURNING / JSONB のような DB 固有の文法 は移植性が無く、複数 DB を真面目にサポートするなら driver 分岐や Doctrine / Eloquent のような ORM に吸収させる。この章で「切り替わる範囲」を体感し、ch11 / ch12 で「切り替わらない部分」を見る。

学習目標

  • SQLite / MySQL / PostgreSQL の DSN 文字列の違いを読み分けられる
  • PDO は DSN を切り替えるだけ で同じコードが 3 DB で動くと理解する
  • 環境変数で接続先を切り替える発想を身につける

ドリル

no 内容
01 3 種類の DSN サンプルを出力し、SQLite で実接続して件数を表示

採点用 DB について

採点ランナーは tests/setup.sql を一時 SQLite に流し込み、そのファイルパスを環境変数 DOJO_DB_PATH で渡してきます。SQLite だけが実接続対象です。

$pdo = new PDO('sqlite:' . getenv('DOJO_DB_PATH'));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

MySQL / PostgreSQL は DSN サンプル文字列を出力するだけ で OK。実際の接続テストは Docker 環境を用意したときに行う。

Docker で MySQL / PostgreSQL を試したい場合

実際の MySQL / PostgreSQL コンテナに接続して動作確認したい場合は、リポジトリ直下の docker/README.md を参照してください (docker compose で MySQL/PostgreSQL を起動する手順)。

解説スライド 全 8 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. DSN 比較 / 複数 DB 接続

    Lesson 11 / Chapter 10

  2. PDO は「DSN だけ」で接続先を切り替えられる

    <?php
    $pdo = new PDO($dsn, $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    • DSN (Data Source Name) = どの DB のどこに繋ぐかを表す文字列
    • DSN 以外の SQL コード (SELECT / INSERT / prepare / fetch) は 3 DB で同じ
    • → 「アプリは PHP のまま、DB だけ差し替える」が成立する
  3. SQLite の DSN

    <?php
    $dsn = "sqlite:/path/to/file.sqlite";
    $pdo = new PDO($dsn);
    • ファイルパスを直接書くだけ
    • ユーザ / パスワード不要 (ローカルファイル)
    • 学習や軽い実験に向いている
  4. MySQL の DSN

    <?php
    $dsn = "mysql:host=localhost;dbname=mydb;charset=utf8mb4";
    $pdo = new PDO($dsn, "root", "secret");
    • host / dbname / charset; で並べる
    • ユーザ・パスワードは PDO の 2,3 番目の引数
    • charset=utf8mb4 を必ず付ける (絵文字含む UTF-8 のため)
  5. PostgreSQL の DSN

    <?php
    $dsn = "pgsql:host=localhost;dbname=mydb";
    $pdo = new PDO($dsn, "postgres", "secret");
    • 書式は MySQL と似ているが先頭が pgsql:
    • charset は SQL レイヤで決まる (DSN で指定しない)
    • ポート指定が必要なら ;port=5432 を追加
  6. DSN 一覧 (横並び比較)

    DB DSN 例
    SQLite sqlite:/path/to/file.sqlite
    MySQL mysql:host=localhost;dbname=mydb;charset=utf8mb4
    PostgreSQL pgsql:host=localhost;dbname=mydb
    • 共通: ドライバ名: で始まる
    • 共通: ; 区切りで key=value
    • 違い: ファイルパス vs ホスト+DB 名
  7. 環境変数で切り替える

    <?php
    $driver = getenv('DOJO_DB_DRIVER') ?: 'sqlite';
    
    $dsn = match ($driver) {
        'sqlite' => "sqlite:" . getenv('DOJO_DB_PATH'),
        'mysql'  => "mysql:host=localhost;dbname=mydb;charset=utf8mb4",
        'pgsql'  => "pgsql:host=localhost;dbname=mydb",
    };
    
    $pdo = new PDO($dsn);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    → コードはこのままで、DOJO_DB_DRIVER=mysql にすれば MySQL に繋がる。

  8. このチャプターでできるようになること

    ✅ SQLite / MySQL / PostgreSQL の DSN 書式を読み分けられる ✅ PDO は DSN を差し替えるだけで複数 DB に対応できると説明できる ✅ 環境変数で接続先を切り替える発想が持てる ✅ mysql: には charset=utf8mb4 を付ける習慣

    → ドリルへ (実接続は SQLite で行い、MySQL/PostgreSQL は DSN サンプル出力で確認)

1 / 8
📜 スライドを全部一気に読む(縦表示)

Lesson 11 / Chapter 10


PDO は「DSN だけ」で接続先を切り替えられる

<?php
$pdo = new PDO($dsn, $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  • DSN (Data Source Name) = どの DB のどこに繋ぐかを表す文字列
  • DSN 以外の SQL コード (SELECT / INSERT / prepare / fetch) は 3 DB で同じ
  • → 「アプリは PHP のまま、DB だけ差し替える」が成立する

SQLite の DSN

<?php
$dsn = "sqlite:/path/to/file.sqlite";
$pdo = new PDO($dsn);
  • ファイルパスを直接書くだけ
  • ユーザ / パスワード不要 (ローカルファイル)
  • 学習や軽い実験に向いている

MySQL の DSN

<?php
$dsn = "mysql:host=localhost;dbname=mydb;charset=utf8mb4";
$pdo = new PDO($dsn, "root", "secret");
  • host / dbname / charset; で並べる
  • ユーザ・パスワードは PDO の 2,3 番目の引数
  • charset=utf8mb4 を必ず付ける (絵文字含む UTF-8 のため)

PostgreSQL の DSN

<?php
$dsn = "pgsql:host=localhost;dbname=mydb";
$pdo = new PDO($dsn, "postgres", "secret");
  • 書式は MySQL と似ているが先頭が pgsql:
  • charset は SQL レイヤで決まる (DSN で指定しない)
  • ポート指定が必要なら ;port=5432 を追加

DSN 一覧 (横並び比較)

DB DSN 例
SQLite sqlite:/path/to/file.sqlite
MySQL mysql:host=localhost;dbname=mydb;charset=utf8mb4
PostgreSQL pgsql:host=localhost;dbname=mydb
  • 共通: ドライバ名: で始まる
  • 共通: ; 区切りで key=value
  • 違い: ファイルパス vs ホスト+DB 名

環境変数で切り替える

<?php
$driver = getenv('DOJO_DB_DRIVER') ?: 'sqlite';

$dsn = match ($driver) {
    'sqlite' => "sqlite:" . getenv('DOJO_DB_PATH'),
    'mysql'  => "mysql:host=localhost;dbname=mydb;charset=utf8mb4",
    'pgsql'  => "pgsql:host=localhost;dbname=mydb",
};

$pdo = new PDO($dsn);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

→ コードはこのままで、DOJO_DB_DRIVER=mysql にすれば MySQL に繋がる。


このチャプターでできるようになること

✅ SQLite / MySQL / PostgreSQL の DSN 書式を読み分けられる ✅ PDO は DSN を差し替えるだけで複数 DB に対応できると説明できる ✅ 環境変数で接続先を切り替える発想が持てる ✅ mysql: には charset=utf8mb4 を付ける習慣

→ ドリルへ (実接続は SQLite で行い、MySQL/PostgreSQL は DSN サンプル出力で確認)

この章で取り組む 演習問題の流れ (1ステップ)
  1. 01 ドリル 01 — DSN を 3 種類並べて、SQLite に実接続する README.md starter.php answer.php

演習問題の詳細

この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。

ドリル 01 — DSN を 3 種類並べて、SQLite に実接続する

問題

環境変数 DOJO_DB_DRIVER を読み取り (未設定なら sqlite 扱い)、次の順で標準出力に表示する。

  1. 採用ドライバ名
  2. SQLite の DSN サンプル文字列
  3. MySQL の DSN サンプル文字列
  4. PostgreSQL の DSN サンプル文字列
  5. SQLite (DOJO_DB_PATH) に実接続し、ping テーブルの行数を出力

期待される出力

driver: sqlite
sqlite DSN sample: sqlite:/path/to/file.sqlite
mysql  DSN sample: mysql:host=localhost;dbname=mydb;charset=utf8mb4
pgsql  DSN sample: pgsql:host=localhost;dbname=mydb
connected: yes (rows=1)

ヒント

  • getenv('DOJO_DB_DRIVER') ?: 'sqlite' でデフォルト値
  • DSN サンプルは 固定文字列を直接 echo する (実環境のパスではなく /path/to/file.sqlite で OK)
  • SQLite への実接続は new PDO('sqlite:' . getenv('DOJO_DB_PATH'))
  • 行数は SELECT COUNT(*) FROM pingfetchColumn() で取得
  • mysql / pgsql の後ろのスペースは 2 つ。出力フォーマットを揃えるため

なぜ DSN サンプルを直接書くのか

MySQL / PostgreSQL は今回の採点環境では起動していないので、実接続はせず DSN 文字列を出力するだけ にしている。実際にコンテナを立てて接続したい場合は、リポジトリ直下の docker/README.md を参照。

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

演習問題(1問)

  1. ドリル 01 — DSN を 3 種類並べて、SQLite に実接続する

    README.md starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。

完了にすると進捗に反映されます