topic: db (PDO / SQL / マルチDB) / ch10 — DSN 比較 / 複数 DB 接続 / 演習 01

📝 ドリル 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)

採点

php scripts/grade.php topics/11-db/ch10-multi-db/drill/01-dsn-comparison/

採点ランナーは tests/setup.sql を一時 SQLite に流し込み、DOJO_DB_PATH を渡してきます。DOJO_DB_DRIVER は未指定なので、デフォルトの sqlite で動かす想定です。

ヒント

  • 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 を参照。

テストケース

期待される出力

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)

📄 starter.php(雛形)

このコードから書き始めてください。

<?php

// TODO:
// 1) $driver を環境変数 DOJO_DB_DRIVER から取得 (未設定なら 'sqlite')
// 2) 次の 5 行を順に出力する:
//      driver: <driver>
//      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=<ping テーブルの件数>)
// 3) SQLite に実接続するときは getenv('DOJO_DB_PATH') を使う
// 4) PDO::ATTR_ERRMODE は PDO::ERRMODE_EXCEPTION に設定する
✅ 解答例を見る(自分で解いてから)
<?php

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

echo "driver: {$driver}\n";
echo "sqlite DSN sample: sqlite:/path/to/file.sqlite\n";
echo "mysql  DSN sample: mysql:host=localhost;dbname=mydb;charset=utf8mb4\n";
echo "pgsql  DSN sample: pgsql:host=localhost;dbname=mydb\n";

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

$count = (int) $pdo->query("SELECT COUNT(*) FROM ping")->fetchColumn();
echo "connected: yes (rows={$count})\n";