このシリーズはPHPでデータベースを扱いたいと考えている方を対象とした記事となっています。
前回はPDOのオブジェクトを生成することでデータベースへの接続を行いました。今回はいよいよデータベースへアクセスしていきます。プログラムからデータベースを扱う場合、プログラム自体はそれほど複雑ではなく、今回取り上げるQueryの実行ができるようになれば、データに関する基本的な操作はほとんど可能となりますので、しっかりと確認していきましょう。
Query (クエリー)とは
まず今回のタイトルにもなっているQuery(クエリー)という言葉について確認しておきましょう。
Queryとは、データベースに対する問い合わせのことです。問い合わせというとイメージしにくいかもしれませんが、各種コマンドと思って概ね間違いではありません。データベースへの問い合わせはSQLという特殊な問い合わせ言語を利用することが多く、QueryとはそのSQLで書かれたコマンドを発行することを指します。
IT業界や技術者の間ではQueryの事を、SQL文や単にSQLと表現することも珍しくありません。人にもよるかもしれませんが、Queryは実行、SQL文は発行するものと表現することが多そうですが、どれもほぼ同じ意味で用いています。強いて違いを挙げると、Queryは動詞的なニュアンスを感じ、SQL文からは静的な文章/SQLというニュアンスを感じます。SQL文とSQLはどちらも静的なニュアンスですが、SQL文の方が少し完成された感が強いくらいの微妙な違いしか感じません。
QueryもSQL文も「実行する」といって違和感はありませんが、「作成する」の場合はSQL文は問題なくても、Queryだと意味は伝わるのですが若干違和感を感じます。これは先の動詞的なニュアンスのせいかもしれません。
今回はQueryの中身についてはあまり掘り下げず、Queryの実行から結果を取得するまでの流れに注目して全体を紹介します。
PDOでのクエリー実行 – query
PHPからPDOを使ってQueryを実行するには、PDOクラスのquery関数を使用します。説明の簡略化のために、最も単純な例を以下に示します。
// $dsn, $user, $passwordはデータベースへの接続情報
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
// データベースへ接続
$conn = new PDO($dsn, $user, $password);
// SQL文を準備
$sql = "SELECT * FROM hoge";
// Query実行
$conn->query($sql);
少しサンプルが長そうに見えますが、上半分は前回までに紹介した内容で、データベースへの接続に関する手続です。SQL文の準備は、単純に文字列を変数$sqlに代入しているだけです。そのため上記サンプルの中でQueryの実行に該当している部分は、PDOオブジェクトの$connからqueryを呼び出す処理だけということになります。
今回のサンプルでは$sqlにSELECTと呼ばれる「データベースからデータの抽出」を行うコマンドを指定しています。SQLについては次回改めて基本的な使い方を紹介しますが、上記SQLの意味は、データベースのテーブル[hoge]から全ての行・列を取得するという指定になっています。
上記のままだと、抽出を実行してもその結果を捨ててしまっているので、次項でそのデータを取り出す方法を確認してみます。
実行結果の全取得 – fetchAll
PDO::queryの結果からデータを取り出す方法はいろいろと用意されていますが、ここでは最も単純に全取得する方法[fetchAll]を紹介します。fetchという英単語は「取ってくる」といった意味なので、fetchAllは「全部取ってくる」という意味です。
PDOのqueryを実行して成功するとPDOStatementという新しいオブジェクトが返却されます。失敗した場合はfalseが返却されます。fetchAllなどデータへの直接アクセスはPDOStatementオブジェクトを使って行っていきます。(今回は簡略化のためエラー処理などは割愛しています。ご注意ください。)
// $dsn, $user, $passwordはデータベースへの接続情報
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
// データベースへ接続
$conn = new PDO($dsn, $user, $password);
// SQL文を準備
$sql = "SELECT * FROM hoge";
// Query実行とPDOStatementオブジェクトの取得
$state_obj = $conn->query($sql);
// Queryの実行結果を全取得
$ret_array = $state_obj->fetchAll();
PDO::query関数で$sqlをデータベースに発行し、結果として返ってくるPDOStatementのオブジェクト$state_objに入れています。$state_objからfetchAll関数を実行し、返ってきた値を$ret_arrayに保管しています。$sqlの内容は「hogeテーブルの内容をすべて取得」となっていますので、データベースの内容の一部をPHPの変数$ret_arrayへ取り出した形になります。この後、データベースとの接続が失われても、$ret_arrayに取り出した値は失われません。
$ret_arrayは連想配列の形になっていて、その後のプログラムで自由に扱うことができます。ただし、データベースの中身と同じであっても、データベースと連結している訳ではないので、この配列の中身を更新してもデータベースの中身は更新されません。データベースの更新をするには、別途更新のSQLを実行する必要があり、それについては次回紹介しています。
連想配列は行、列がそれぞれ以下のようなイメージとなります。行は番号で、列は名前でも番号でもアクセスできます。
Array
(
[0] => Array
(
[name] => apple
[0] => apple
[colour] => red
[1] => red
)
[1] => Array
(
[name] => pear
[0] => pear
[colour] => green
[1] => green
)
)
こういった連想配列を処理する方法は沢山ありますが、とても便利なforeachの例だけ紹介しておきます。
foreach($ret_array as $oneRow) {
// 各一行毎に最後まで順番に処理
}
foreachによって、配列全ての要素を順番に要素数回ループ処理し、各ループで対象とする要素が$oneRowに入れられます。{}(カッコ内)で$oneRowを使って処理を行うことで、配列内のすべての要素に対して順番に処理を行うことが出来ます。データベースの構造に合わせたPHPのクラスを用意しておき、取得結果に合わせてインスタンスを生成・初期化するような処理は、データベースを扱うプログラムで良く行われ、そういった処理などではforeachはとても便利に働きます。
再度になりますが、この連想配列の行を追加したり更新することでデータベースに反映できるわけではないことに注意してください。データベースへの各操作は基本的にSQLで行います。
まとめ
今回はデータベースに接続した後、PHPから実際にSQLを発行し、結果をPHPの変数に取り出す流れを確認してみました。最も単純な例だけを紹介しているため物足りないと感じる方もいるかもしれませんが、今回は「まずは簡単な例で体感」することを重要視しているためご容赦ください。
今回は説明のために各種エラー処理をすべて抜いてサンプルを紹介しています。実際にはデータベースやネットワークの状態、またSQL文の間違いなど様々なエラーが発生することが予想され、エラー処理は非常に重要です。エラー処理を正しく構成し堅牢なプログラムを書けることは、プログラマーの力量を示すひとつの指標と言っても良い程なので、できるだけ注意深くプログラムを見て、「ここに値が入ってこない場合はどうなるだろう」という率直な疑問をそのままにしないようにしていきましょう。今回のサンプルは非常にシンプルですが、環境によっては正しく動作しない場合もあるでしょう。そういった時に問題を特定し解決するのにもエラー処理は役立ちます。
データベースにSQLを発行することができるようになると、一気に出来ることが広がります。ただ、肝心のSQLについてはPHP/PDOとは異なる知識が必要になります。次回、基本的なSQLを紹介していますので、是非そちらも参考にしてみてください。