PHP-DB - 4. レコードの取得
PDOインスタンスを生成できたので、次はSQLを実行する方法を学習します。ここではまず select
文の実行方法について取り上げます。次のプログラム( pdo2.php
)を作成してみましょう。
<?php
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories order by id";
$st = $pdo->query($sql);
$row = $st->fetch();
while ($row !== false) {
echo $row["id"] . ":" . $row["title"] . PHP_EOL;
$row = $st->fetch();
}
このプログラムではまず PDO
インスタンスを生成しています。
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
PDO
インスタンスを生成した後、 $sql
変数 に select
文を文字列データとして代入し、 $pdo
変数に対して query
メソッドを呼び出しています。このとき PDO
クラスの query
メソッドは戻り値に PDOStatement
インスタンスを返却します。
$sql = "select id, title from categories order by id";
$st = $pdo->query($sql);
PDOStatement
クラスには検索結果にアクセスするための fetch
メソッドや fetchAll
メソッドが用意されています。 $st
変数に代入されている PDOStatement
インスタンスに対してこれらのメソッドを呼び出すことで検索結果にアクセスできます。
このプログラムでは while
文と組み合わせて、 $st
変数に対して fetch
メソッドを繰り返し呼び出すことで、検索結果を1行ずつ取得しています。
$row = $st->fetch();
while ($row !== false) {
echo $row["id"] . ":" . $row["title"] . PHP_EOL;
$row = $st->fetch();
}
$st->fetch()
メソッドの呼び出しは、デフォルトで検索結果から1行のデータを連想配列として返却します。この連想配列は select
文に指定した列名(と列番号)をキーとしています。ここでは $st->fetch()
の戻り値を $row
変数に代入しているので、 $row["id"]
や $row["title"]
として検索結果にアクセスできます。
また $st->fetch()
メソッドの呼び出しは、検索結果の終端に達している時点で呼び出すと戻り値に false
を返します。そのため while
文の条件式において $row
変数が false
でないことを確認しています。
それではコマンドラインからプログラムを実行してみましょう。
$ php pdo2.php
1:Programming
2:Design
3:Marketing
表示された内容からSQL( select id, title from categories order by id
) の検索結果をPHPで処理できているのがわかります。
PDOStatement
クラス - fetchAll
メソッド
さきほどのプログラム( pdo2.php
)では PDOStamenet
インスタンスに対して、繰り返し fetch
メソッドを呼び出すことで検索結果を処理しました。もう一つ、ここでは fetchAll
メソッドを呼び出して検索結果を処理する方法を取り上げます。プログラム( pdo2.php
)を次のように修正してみましょう。
<?php
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories order by id";
$st = $pdo->query($sql);
$rows = $st->fetchAll();
foreach ($rows as $row) {
echo $row["id"] . ":" . $row["title"] . PHP_EOL;
}
PDOStatement
クラスの fetchAll
メソッドを呼び出すことで select
文の実行結果を2次元配列で取得できます。ここでは $st->fetchAll()
メソッドを呼び出しているので、 $rows
変数には2次元配列が代入されます。そのため foreach
構文を使って 2次元配列 $rows
の中の要素を $row
変数 に代入して繰り返し処理しています。 $row
変数には列名(と列番号)をキーにした連想配列が代入されているので、 $row["id"]
や $row["title"]
のように列名を指定して結果にアクセスできます。
コマンドラインからプログラムを実行してみましょう。
$ php pdo2.php
1:Programming
2:Design
3:Marketing
実行結果から $st->fetchAll()
メソッドの呼び出しの結果を繰り返し処理できているのがわかります。
参考:列番号によるアクセス
PDOStatement
クラスの fetch
メソッドや fetchAll
メソッドの戻り値に対して、列名でなく列番号でもアクセスできます。さきほどのプログラム( pdo2.php
)において、 $st->fetchAll()
呼び出しの戻り値である2次元配列を print_r
関数で出力してみましょう。
<?php
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories order by id";
$st = $pdo->query($sql);
$rows = $st->fetchAll();
print_r($rows);
コマンドラインからプログラムを実行してみましょう。
$ php pdo2.php
Array
(
[0] => Array
(
[id] => 1
[0] => 1
[title] => Programming
[1] => Programming
)
[1] => Array
(
[id] => 2
[0] => 2
[title] => Design
[1] => Design
)
[2] => Array
(
[id] => 3
[0] => 3
[title] => Marketing
[1] => Marketing
)
)
実行結果から、検索結果として3件のレコードが返却されているのがわかります。また各レコードを表す連想配列のキーには列名( "id"
や "title"
)以外にはも 0
や 1
といった番号もキーに含まれているのがわかります。
そのため、次のように列名ではなく列番号を指定して検索結果にアクセスできます。プログラム( pdo2.php
)を修正してみましょう。
$dsn = "sqlite:eldb.sqlite3";
$pdo = new PDO($dsn);
$sql = "select id, title from categories order by id";
$st = $pdo->query($sql);
$rows = $st->fetchAll();
foreach ($rows as $row) {
echo $row[0] . ":" . $row[1] . PHP_EOL;
}
ここでは echo $row[0] . ":" . $row[1] . PHP_EOL;
のように列名ではなく列番号を指定しています。この場合、 "id"
列にアクセスするには列番号 0
、 "title"
列にアクセスするには列番号 1
でアクセスできます。
コマンドラインからプログラムを実行してみましょう。
$ php pdo2.php
1:Programming
2:Design
3:Marketing
実行結果から列番号による指定も正しく動作していることがわかります。
まとめ
PDO
インスタンスのquery
メソッドによってselect
文を実行するquery
メソッドの戻りにはPDOStatement
インスタンスが返却されるPDOStatement
インスタンスのfetch
メソッドやfetchAll
メソッドを呼び出すことでselect
文の実行結果にアクセスできる