概要
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 を起動する手順)。
📝 演習: ドリル 01 — DSN を 3 種類並べて、SQLite に実接続する
問題
環境変数 DOJO_DB_DRIVER を読み取り (未設定なら sqlite 扱い)、次の順で標準出力に表示する。
- 採用ドライバ名
- SQLite の DSN サンプル文字列
- MySQL の DSN サンプル文字列
- PostgreSQL の DSN サンプル文字列
- 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 pingをfetchColumn()で取得 mysql/pgsqlの後ろのスペースは 2 つ。出力フォーマットを揃えるため
なぜ DSN サンプルを直接書くのか
MySQL / PostgreSQL は今回の採点環境では起動していないので、実接続はせず DSN 文字列を出力するだけ にしている。実際にコンテナを立てて接続したい場合は、リポジトリ直下の docker/README.md を参照。