Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】Pdo\Sqlite::FETCH_GROUP定数の使い方

FETCH_GROUP定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

FETCH_GROUP定数は、PHPのPdo\Sqlite拡張機能など、PDO(PHP Data Objects)を利用する際に、データベースから取得した結果セットを特定の形式で整形するために使用される定数です。この定数は、主にPDOStatementクラスのfetchAll()メソッドの引数であるfetch_styleとして指定されます。

この定数を指定してデータを取得すると、SQLクエリの結果は、最初に出現するカラムの値に基づいてグループ化された連想配列として返されます。具体的には、生成される配列の各キーは、結果セットの最初のカラムの値となり、そのキーに対応する値は、そのキーを持つすべての行を表す配列の集合となります。例えば、顧客IDと注文商品をクエリで取得する際に、FETCH_GROUPを使用すると、同じ顧客IDを持つすべての注文商品が、その顧客IDをキーとした一つの配列内にまとめられた形で手元に届きます。

このようにデータをグループ化する機能は、関連する複数のデータを効率的に処理したい場合や、特定の基準でデータを集約してレポートを作成する場面などで非常に役立ちます。例えば、特定のカテゴリに属するすべての商品を一覧表示したい場合などに、手動でデータを集約する手間を省き、整理された状態でデータを受け取ることが可能です。他のフェッチスタイルと組み合わせることで、さらに柔軟なデータ構造を得ることもできます。

構文(syntax)

1$results = $pdoStatement->fetchAll(PDO::FETCH_GROUP);

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

PDO::FETCH_GROUPは、PDOStatement::fetch()やPDOStatement::fetchAll()メソッドで、結果セットを列名とその値の連想配列の配列として取得する際に使用される定数です。

サンプルコード

PHP PDO FETCH_GROUP で結果をグループ化して取得する

1<?php
2
3/**
4 * PDO::FETCH_GROUP 定数を使用して、データベースの結果をグループ化してフェッチするサンプルコードです。
5 *
6 * この関数は、システムエンジニアを目指す初心者向けに、PDO (PHP Data Objects) の基本的な使い方と
7 * FETCH_GROUP の挙動を理解しやすいように設計されています。
8 * SQLite インメモリデータベースを使用し、メモリ上で一時的にテーブルを作成し、
9 * サンプルデータを挿入した後にデータをグループ化して取得する一連の流れを示します。
10 */
11function demonstratePdoFetchGroup(): void
12{
13    // データベース操作中のエラーを捕捉するための try-catch ブロック
14    try {
15        // SQLite インメモリデータベースに接続します。
16        // ':memory:' は、データがメモリ上にのみ存在し、スクリプト終了時に消滅することを示します。
17        $pdo = new PDO('sqlite::memory:');
18
19        // エラーモードを設定します。
20        // PDO::ATTR_ERRMODE を PDO::ERRMODE_EXCEPTION に設定することで、
21        // SQLエラーが発生した場合に PDOException がスローされ、catch ブロックで捕捉できるようになります。
22        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
23
24        echo "データベースに接続しました。\n\n";
25
26        // サンプルデータ用の 'products' テーブルを作成します。
27        // PRIMARY KEY AUTOINCREMENT は、id 列が自動的に増分される主キーであることを意味します。
28        $pdo->exec("
29            CREATE TABLE IF NOT EXISTS products (
30                id INTEGER PRIMARY KEY AUTOINCREMENT,
31                category TEXT NOT NULL,
32                name TEXT NOT NULL
33            );
34        ");
35        echo "products テーブルを作成しました。\n\n";
36
37        // サンプルデータをテーブルに挿入します。
38        // 同じカテゴリの製品が複数存在するようにデータを配置します。
39        $pdo->exec("INSERT INTO products (category, name) VALUES ('Fruits', 'Apple');");
40        $pdo->exec("INSERT INTO products (category, name) VALUES ('Fruits', 'Banana');");
41        $pdo->exec("INSERT INTO products (category, name) VALUES ('Vegetables', 'Carrot');");
42        $pdo->exec("INSERT INTO products (category, name) VALUES ('Vegetables', 'Spinach');");
43        $pdo->exec("INSERT INTO products (category, name) VALUES ('Dairy', 'Milk');");
44        echo "サンプルデータを挿入しました。\n\n";
45
46        // SQLクエリを実行し、結果をフェッチします。
47        // 'category' と 'name' 列を選択し、'category' で結果を並べ替えます。
48        $stmt = $pdo->query("SELECT category, name FROM products ORDER BY category, name");
49
50        // PDO::FETCH_GROUP を使用してデータをフェッチします。
51        // このフェッチスタイルは、結果セットの最初のカラムの値 (ここでは 'category') をキーとして、
52        // そのキーに属する行の配列を値としてグループ化します。
53        // PDO::FETCH_ASSOC を組み合わせることで、各グループ内の行が連想配列として取得されます。
54        $groupedProducts = $stmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);
55
56        echo "PDO::FETCH_GROUP を使用してデータをフェッチしました。\n";
57        echo "カテゴリごとに製品をグループ化して表示します:\n";
58
59        // フェッチした結果をループして表示します。
60        // $groupedProducts の構造は ['カテゴリ名' => [ ['name' => '製品名'], ... ], ...] となります。
61        foreach ($groupedProducts as $category => $products) {
62            echo "--- カテゴリ: " . htmlspecialchars($category) . " ---\n";
63            foreach ($products as $product) {
64                // $product は連想配列であり、'name' キーで製品名にアクセスできます。
65                echo "  - " . htmlspecialchars($product['name']) . "\n";
66            }
67        }
68
69    } catch (PDOException $e) {
70        // PDOException が発生した場合 (データベース関連のエラー) の処理
71        echo "データベースエラーが発生しました: " . $e->getMessage() . "\n";
72    } catch (Exception $e) {
73        // その他の予期せぬエラーが発生した場合の処理
74        echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n";
75    }
76}
77
78// 作成した関数を実行します。
79demonstratePdoFetchGroup();

PDO::FETCH_GROUPは、PHPでデータベースを操作するPDO (PHP Data Objects) が提供する定数の一つです。この定数は、データベースから取得した結果を、特定のカラムの値に基づいて自動的にグループ化して配列として受け取る際に使用します。定数であるため引数はなく、内部的に整数値を持ちます。

サンプルコードでは、SQLiteのインメモリデータベースに接続し、productsテーブルを作成してサンプルデータを挿入しています。その後、SELECT category, name FROM productsというSQLクエリを実行し、結果をPDO::FETCH_GROUP | PDO::FETCH_ASSOCというフェッチスタイルで取得しています。

このPDO::FETCH_GROUPを指定すると、取得した結果セットの最初のカラム(この例ではcategory)の値が最上位の配列のキーとなり、そのキーに属する全ての行がサブ配列としてまとめられます。さらにPDO::FETCH_ASSOCを組み合わせることで、各サブ配列内の行も連想配列として取得されるため、['Fruits' => [['name' => 'Apple'], ['name' => 'Banana']], ...] のような、カテゴリごとに製品が整理された扱いやすいデータ構造が得られます。これにより、データベースから取得したデータを特定の基準で整理し、リスト表示などの処理を簡潔に記述できるため、データ処理の効率化に非常に役立ちます。

このサンプルコードでは、PDO::FETCH_GROUP を利用して、データベースのクエリ結果を最初のカラム(例ではcategory)の値で自動的にグループ化する方法を示しています。意図した通りにデータをグループ化するには、SQLクエリでORDER BY句を用いてグループ化したいカラムでソートすることが重要です。また、PDO::FETCH_GROUP は単独ではなく、PDO::FETCH_ASSOCなどと組み合わせて、グループ内の各行を連想配列形式で取得するのが一般的です。

取得したデータをWebページなどに表示する際は、クロスサイトスクリプティング(XSS)攻撃を防ぐため、htmlspecialchars()関数などで必ずエスケープ処理を行ってください。データベース操作ではエラーが発生しやすいため、try-catchブロックによるエラーハンドリングと、PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTIONに設定することが安全なコード運用のために不可欠です。:memory:データベースはスクリプトの実行が終了するとデータが消滅するため、一時的なテスト用途に適しています。

関連コンテンツ