topic: db (PDO / SQL / マルチDB) / ch11 — MySQL 固有の文法と運用 / 演習 02
📝 ドリル 02 — テーブル一覧を取得する (driver 別の SHOW TABLES 相当)
問題
採点ランナーが users と posts の 2 テーブルを用意する。これらのテーブル名を アルファベット順 で 1 行ずつ出力する。
DB ごとにテーブル一覧の取り方が違うので、DOJO_DB_DRIVER (sqlite / mysql / pgsql) で分岐する。
| driver | 取り方 |
|---|---|
| sqlite | SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name |
| mysql | SHOW TABLES |
| pgsql | SELECT tablename FROM pg_tables WHERE schemaname = current_schema() ORDER BY tablename |
期待される出力
posts
users
ヒント
getenv('DOJO_DB_DRIVER') ?: 'sqlite'で driver 取得- PHP 8 の
match式で driver ごとに SQL を切り替えると見通しが良い SHOW TABLESは 1 列だけ返るのでFETCH_NUMで[0]を取り出すと簡単- MySQL/PostgreSQL は連想配列のキー名が DB によって変わる (e.g.
Tables_in_<dbname>) ので、列インデックス取得が無難 - アルファベット順なので
posts→usersの順 (採点ランナーは MySQL の SHOW TABLES もこの順で返す)
採点
php scripts/grade.php topics/11-db/ch11-mysql-specific/drill/02-show-tables/
学ぶこと
- 「DB 内のテーブル一覧」は PDO で標準化されていない。DB ごとに違うクエリを叩く必要がある
- 逆に言えば、PDO のレイヤを抜けると DB 固有のメタデータ操作にすぐ手が届く
テストケース
期待される出力
posts
users
📄 starter.php(雛形)
このコードから書き始めてください。
<?php
require __DIR__ . '/../../../../../scripts/shared/db-connect.php';
$pdo = dojo_db_connect();
$driver = getenv('DOJO_DB_DRIVER') ?: 'sqlite';
// TODO:
// 1) $driver の値で SQL を分岐:
// sqlite -> SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name
// mysql -> SHOW TABLES
// pgsql -> SELECT tablename FROM pg_tables WHERE schemaname = current_schema() ORDER BY tablename
// 2) クエリを実行し、テーブル名の配列を作る
// 3) 1 行ずつ echo して出力 (アルファベット順)
✅ 解答例を見る(自分で解いてから)
<?php
require __DIR__ . '/../../../../../scripts/shared/db-connect.php';
$pdo = dojo_db_connect();
$driver = getenv('DOJO_DB_DRIVER') ?: 'sqlite';
$tables = match ($driver) {
'sqlite' => array_column(
$pdo->query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
->fetchAll(PDO::FETCH_ASSOC),
'name'
),
'mysql' => array_column(
$pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_NUM),
0
),
'pgsql' => array_column(
$pdo->query("SELECT tablename FROM pg_tables WHERE schemaname = current_schema() ORDER BY tablename")
->fetchAll(PDO::FETCH_ASSOC),
'tablename'
),
};
sort($tables);
foreach ($tables as $t) {
echo "{$t}\n";
}