PDO::FETCH_STYLE

PDO を使って fetch する時、fetch_style の値はいつも PDO::FETCH_ASSOC を使っている。先日、PDO::FETCH_ASSOC ではなく、PDO::FETCH_CLASS を使うことがあった。他の fetch_style はどう使うのか興味が湧いたので、まとめてみた。だって、マニュアルには全部載ってないんだもの。

ソース
<?php
class User
{
  public $id, $name, $age = null;
}

$pdo = new PDO(
  'sqlite::memory:',
  null,
  null,
  array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
);

$queries = array(
  'CREATE TABLE Users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)',
  'INSERT INTO Users (name, age) VALUES ("Who Ami", 20)'
);
foreach ($queries as $query) {
  $pdo->query($query);
}
$query = 'SELECT id, name, age FROM Users';
$stmt  = $pdo->prepare($query);

echo "連想配列\n";
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_ASSOC));

echo "連想配列と配列\n";
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_BOTH));

echo "配列\n";
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_NUM));

echo "匿名オブジェクト\n";
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_OBJ));

echo "PDORowオブジェクト\n";
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_LAZY));

echo "Userオブジェクト (fetch 時にオブジェクトが生成される)\n";
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
var_dump($user = $stmt->fetch(PDO::FETCH_CLASS));

echo "Userオブジェクト (既にあるオブジェクトに値がセットされる)\n";
$user = new User();
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_INTO, $user);
$stmt->fetch(PDO::FETCH_INTO);
var_dump($user);

echo "バインドした変数\n";
$stmt->execute();
$stmt->bindColumn('id',   $id);
$stmt->bindColumn('name', $name);
$stmt->bindColumn('age',  $age);
$stmt->fetch(PDO::FETCH_BOUND);
var_dump($id, $name, $age);
結果
連想配列
array(3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(7) "Who Ami"
  ["age"]=>
  string(2) "20"
}
連想配列と配列
array(6) {
  ["id"]=>
  string(1) "1"
  [0]=>
  string(1) "1"
  ["name"]=>
  string(7) "Who Ami"
  [1]=>
  string(7) "Who Ami"
  ["age"]=>
  string(2) "20"
  [2]=>
  string(2) "20"
}
配列
array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(7) "Who Ami"
  [2]=>
  string(2) "20"
}
匿名オブジェクト
object(stdClass)#3 (3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(7) "Who Ami"
  ["age"]=>
  string(2) "20"
}
PDORowオブジェクト
object(PDORow)#3 (4) {
  ["queryString"]=>
  string(31) "SELECT id, name, age FROM Users"
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(7) "Who Ami"
  ["age"]=>
  string(2) "20"
}
Userオブジェクト (fetch 時にオブジェクトが生成される)
object(User)#4 (3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(7) "Who Ami"
  ["age"]=>
  string(2) "20"
}
Userオブジェクト (既にあるオブジェクトに値がセットされる)
object(User)#5 (3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(7) "Who Ami"
  ["age"]=>
  string(2) "20"
}
バインドした変数
string(1) "1"
string(7) "Who Ami"
string(2) "20"
感想
  • やっぱり PDO::FETCH_ASSOC が使いやすいかな。
  • 次点で、PDO::FETCH_CLASS か。簡単なプログラムだとクラスを作るまでもないし。
  • PDO::FETCH_INTO を使うなら PDO::FETCH_CLASS の方を使いそう。
  • PDO::FETCH_LAZY ってどういう使い道?多分一生使わないんじゃないか。
  • PDO::FETCH_BOUND でバインドする変数名(射影するカラム名)は先頭にコロン":"を付けなくてもいいんだね。