PDOのfetch系メソッド
前提
- PHP 5.6
- mysql Ver 14.14 Distrib 5.7.18
- Google Chromeでしかテストしていません
- PDOのfetch系メソッドをまとめただけです
テストデータを用意
※ fetch系メソッドだけ調べたい方は下の方まで飛ばしてください
ターミナルでMySQLを起動。それから以下の命令を実行します。
create database fetch_test default charset utf8;
もちろんphpMyAdmin
からでもOKです。
show databases;
で作成できたか確認できます。databases
と複数形であることに注意しましょう。
確認ができたら、use fetch_test
でDBを選択します。
文房具を管理するitems
テーブルを作成します。
create table items ( id int auto_increment not null primary key, name varchar(30), price int(30) );
show tables
で確認できます。 こちらもDBを表示した時と同じくtables
と複数形であることに注意です。
ここでようやくテストデータの挿入です。
適当にinsertしていきます。
insert into items (name, price) values ('鉛筆', 100); insert into items (name, price) values ('ノート', 120); insert into items (name, price) values ('消しゴム', 50);
終わったらselect * from items;
でチェックしておきましょう。
id | name | price |
---|---|---|
1 | 鉛筆 | 100 |
2 | ノート | 120 |
3 | 消しゴム | 50 |
メソッドを切り替えてfetch系メソッドを検証するクラスをつくる
同じディレクトリ下に
という3つのファイルを作成します。
database.php
<?php class Database { public static function connectDB() { $pdo = ''; try { $pdo = new PDO( // 環境によってはhost部分をlocalhostにしてください 'mysql:dbname=fetch_test;host=127.0.0.1;charset=utf8', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ] ); } catch (PDOException $e) { header('Content-Type: text/plain; charset=UTF-8', true, 500); exit($e->getMessage()); } return $pdo; } }
静的メソッドでデータベースに接続するだけのクラスです。本来はDB名、ユーザ名、パスワードなど
は別ファイルに定数として分割するものですが、ここでは省略します。
PDO::ATTR_DEFAULT_FETCH_MODE
はPDOのfetch系メソッドで引数が省略された場合などのフェッチスタイルを決定します。
ここではPDO::FETCH_ASSOC
で設定しています。これは、カラム名をキーとする連想配列で取得するモードになります。
また、コメントアウトにもあるとおり、環境によってはhostの部分を127.0.0.1
からlocalhost
にしてください。僕の環境では逆で
ないと動きませんでした。
fetchTester.php
<?php require_once 'database.php'; class FetchTester { private $pdo; private $table = 'items'; function __construct() { $this->pdo = Database::connectDB(); } public function fetch() { $stmt = $this->selectTable(); while ($row = $stmt->fetch()) { var_dump($row); } } public function fetchObject() { $stmt = $this->selectTable(); while ($row = $stmt->fetchObject()) { var_dump($row); } } public function fetchColumn($fetchColumnNumber) { $stmt = $this->selectTable(); while (false !== $val = $stmt->fetchColumn($fetchColumnNumber)) { var_dump($val); } } public function fetchAll() { $stmt = $this->selectTable(); $rows = $stmt->fetchAll(); var_dump($rows); } private function selectTable() { $sql = 'select * from ' . $this->table; $stmt = $this->pdo->query($sql); return $stmt; } }
fetch系メソッドをそれぞれクラス固有のメソッドに分けています。唯一、前処理に当たるselectTable
のみprivate
で定義し、
残りのアクセス権はindex.php
で使えるようにpublic
にしてあります。
index.php
<?php require_once 'FetchTester.php'; $fetch_tester = new FetchTester(); // この部分のメソッドを変更して使う $fetch_tester->fetchAll();
実際に実行するメソッドを実装するファイルです。動作を確かめる際、このファイルへアクセスします。
ここではfetchAll
になっていますが、動作を確認したいfetch系メソッド名に切り替えることで、その動きをvar_dump
形式で確認することができます。var_dump
が嫌だ、という方はecho
なりprint
なりに書きかえてもらって構いません。値をreturn
する形式にして汎用性を高めても良いです。
1. fetch
では、順番に見ていきましょう。
まず基本形のfetch
メソッドです。
$fetch_tester->fetch();
出力結果は以下のようになります。
array(3) { ["id"]=> string(1) "1" ["name"]=> string(6) "鉛筆" ["price"]=> string(3) "100" } array(3) { ["id"]=> string(1) "2" ["name"]=> string(9) "ノート" ["price"]=> string(3) "120" } array(3) { ["id"]=> string(1) "3" ["name"]=> string(12) "消しゴム" ["price"]=> string(2) "50" }
fetch
は取得し終えるとfalseを返すので、それを条件分岐として利用することができます。
fetchTester.php
では以下の部分です。
while ($row = $stmt->fetch()) { // 処理 }
2. fetchObjcet
連想配列ではなく、オブジェクトとしてデータを取得します。
$fetch_tester->fetchObject();
結果は以下のような感じ。
object(stdClass)#4 (3) { ["id"]=> string(1) "1" ["name"]=> string(6) "鉛筆" ["price"]=> string(3) "100" } object(stdClass)#5 (3) { ["id"]=> string(1) "2" ["name"]=> string(9) "ノート" ["price"]=> string(3) "120" } object(stdClass)#4 (3) { ["id"]=> string(1) "3" ["name"]=> string(12) "消しゴム" ["price"]=> string(2) "50" }
3. fetchColumn
引数で指定した番号のカラムを文字列で取得します。省略時は0を指定したとみなされます。
$fetch_tester->fetchColumn();
今回使用しているfetchTester.php
では、fetchTesterクラスのfetchColumnメソッドの引数から、PDO
のfetchColumnメソッドの引数へとカラム番号を受け渡す形になるよう実装してあります。
while
内で、false !==
としているのは値に0が入る場合を考慮してです。参考にさせていただいたサイトのソースコードが
しっかりしていると思ったので、そのまま採用させていただきました。
public function fetchColumn($fetchColumnNumber = 0) { $stmt = $this->selectTable(); while (false !== $val = $stmt->fetchColumn($fetchColumnNumber)) { var_dump($val); } }
以下は、引数に2を指定した場合の結果。
string(3) "100" string(3) "120" string(2) "50"
4. fetchAll
2次元配列として全データを取得します。
$fetch_tester->fetchAll();
ブラウザには以下のように出力されます。
array(3) { [0]=> array(3) { ["id"]=> string(1) "1" ["name"]=> string(6) "鉛筆" ["price"]=> string(3) "100" } [1]=> array(3) { ["id"]=> string(1) "2" ["name"]=> string(9) "ノート" ["price"]=> string(3) "120" } [2]=> array(3) { ["id"]=> string(1) "3" ["name"]=> string(12) "消しゴム" ["price"]=> string(2) "50" } }