PHP-DB - 8. レコードのフェッチ
それではPDOライブラリについて詳細に学習していきましょう。まずはじめにレコードのフェッチについて取り上げます。
プログラミングの文脈においてこのフェッチ( fetch
)という言葉には「データを取りに行く(引き出す)」という意味合いがあります。ここではデータベースに対して select
文を発行し、その結果であるデータを取りに行くという具合です。
これまでに学習してきたとおり、 select
文を実行するには PDO
クラスの query
メソッドを呼び出して、 PDOStatement
インスタンスを取得し、 PDOStatement
クラスの fetch
メソッドや fetchAll
メソッドによって検索結果をフェッチします。このとき fetch
メソッド( fetchAll
メソッド)の引数に、 PDO
クラスの定数(フェッチモード)を指定することで、でデータの取得方法をカスタマイズできます。
PDOのフェッチモード
フェッチモード | 意味 |
---|---|
PDO::FETCH_NUM |
要素番号によるアクセスのみ |
PDO::FETCH_ASSOC |
カラム名によるアクセスのみ |
PDO::FETCH_BOTH |
要素番号、カラム名の両方のアクセス(引数を省略した場合のデフォルト) |
PDO::FETCH_OBJ |
戻り値を配列ではなくオブジェクトで返却する |
ここではフェッチモードの仕組みを学習するために、次のプログラム( pdo6.php
)を作成してみましょう。
<?php
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories";
$st = $pdo->query($sql);
$row = $st->fetch();
// $row = $st->fetch(PDO::FETCH_NUM);
// $row = $st->fetch(PDO::FETCH_ASSOC);
// $row = $st->fetch(PDO::FETCH_BOTH);
// $row = $st->fetch(PDO::FETCH_OBJ);
var_dump($row);
ここではいくつかのステートメントをコメントアウトしています。コメントアウトしている部分では fetch
メソッドの引数にフェッチモードを指定しています。まずは fetch
メソッドの引数を省略した場合のデフォルトの振る舞いについて確認してみましょう。
コマンドラインからプログラムを実行します。
$ php pdo6.php
array(4) {
["id"]=>
string(1) "1"
[0]=>
string(1) "1"
["title"]=>
string(11) "Programming"
[1]=>
string(11) "Programming"
}
実行結果はこれまでに学習してきたとおりです。 $st->fetch()
の戻り値は連想配列となっており、列名と列番号(要素番号)がキーとなっているのがわかります。
PDO::FETCH_NUM
を指定した場合
続いてフェッチモードに PDO::FETCH_NUM
を指定してみましょう。プログラム( pdo6.php
)を修正します。
<?php
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories";
$st = $pdo->query($sql);
// $row = $st->fetch();
$row = $st->fetch(PDO::FETCH_NUM);
// $row = $st->fetch(PDO::FETCH_ASSOC);
// $row = $st->fetch(PDO::FETCH_BOTH);
// $row = $st->fetch(PDO::FETCH_OBJ);
var_dump($row);
fetch
メソッド引数に PDO::FETCH_NUM
を指定すると、戻り値に列番号(要素番号)だけをキーに持つ配列を取得できます。プログラムを実行すると次のようになります。
$ php pdo6.php
array(2) {
[0]=>
string(1) "1"
[1]=>
string(11) "Programming"
}
PDO::FETCH_ASSOC
を指定した場合
続いてフェッチモードに PDO::FETCH_ASSOC
を指定してみましょう。プログラム( pdo6.php
)を修正します。
<?php
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories";
$st = $pdo->query($sql);
// $row = $st->fetch();
// $row = $st->fetch(PDO::FETCH_NUM);
$row = $st->fetch(PDO::FETCH_ASSOC);
// $row = $st->fetch(PDO::FETCH_BOTH);
// $row = $st->fetch(PDO::FETCH_OBJ);
var_dump($row);
fetch
メソッド引数に PDO::FETCH_ASSOC
を指定すると、戻り値に列名だけをキーに持つ配列を取得できます。プログラムを実行すると次のようになります。
$ php pdo6.php
array(2) {
["id"]=>
string(1) "1"
["title"]=>
string(11) "Programming"
}
PDO::FETCH_BOTH
を指定した場合
次にフェッチモードに PDO::FETCH_BOTH
を指定してみましょう。プログラム( pdo6.php
)を修正します。
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories";
$st = $pdo->query($sql);
// $row = $st->fetch();
// $row = $st->fetch(PDO::FETCH_NUM);
// $row = $st->fetch(PDO::FETCH_ASSOC);
$row = $st->fetch(PDO::FETCH_BOTH);
// $row = $st->fetch(PDO::FETCH_OBJ);
var_dump($row);
fetch
メソッド引数に PDO::FETCH_BOTH
を指定すると、戻り値に列名と列番号(要素番号)をキーに持つ配列を取得できます。これは引数を省略した場合と同じ、デフォルトの振る舞いです。プログラムを実行すると次のようになります。
$ php pdo6.php
array(4) {
["id"]=>
string(1) "1"
[0]=>
string(1) "1"
["title"]=>
string(11) "Programming"
[1]=>
string(11) "Programming"
}
PDO::FETCH_OBJ
を指定した場合
さいごにフェッチモードに PDO::FETCH_OBJ
を指定してみましょう。プログラム( pdo6.php
)を修正します。
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories";
$st = $pdo->query($sql);
// $row = $st->fetch();
// $row = $st->fetch(PDO::FETCH_NUM);
// $row = $st->fetch(PDO::FETCH_ASSOC);
// $row = $st->fetch(PDO::FETCH_BOTH);
$row = $st->fetch(PDO::FETCH_OBJ);
var_dump($row);
fetch
メソッド引数に PDO::FETCH_OBJ
を指定すると、戻り値が配列ではなくオブジェクト( stdClass
のインスタンス)となります。プログラムを実行すると次のようになります。
$ php pdo6.php
object(stdClass)#3 (2) {
["id"]=>
string(1) "1"
["title"]=>
string(11) "Programming"
}
この場合、戻り値が配列ではなくオブジェクト( stdClass
のインスタンス)として返却されているので、テーブルの各列に対してプロパティ経由でアクセスできます。プログラム( pdo6.php
)を次のように修正してみましょう。
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories";
$st = $pdo->query($sql);
$rows = $st->fetchAll(PDO::FETCH_OBJ);
foreach ($rows as $row) {
echo $row->id . ":" . $row->title . PHP_EOL;
}
$row->id
や $row->title
のようにプロパティ経由で検索結果にアクセスします。プログラムを実行すると次のようになります。
$ php pdo6.php
1:Programming
2:Design
3:Marketing
まとめ
PDOStatement
インスタンスのfetch
メソッド、fetchAll
メソッドの戻り値である配列は、要素番号によるアクセス、カラム名によるアクセスをサポートしている- これらのアクセス方法は
fetch
メソッド(fetchAll
メソッド)の実行時にPDO
クラスに用意されている定数によって変更できる - デフォルトのフェッチモードは
PDO::FETCH_BOTH
を指定した場合の動作となる