If you are trying to call PDOStatement::fetchAll and is not getting the result set as expected (empty instead), check if you called PDOStatement::execute first.
Remember PDOStatement::fetchAll does not execute the query, it just mounts the array.
:)
PDOStatement::fetchAll
(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0)
PDOStatement::fetchAll — 全ての結果行を含む配列を返す
説明
$fetch_style
[, mixed $fetch_argument
[, array $ctor_args = array()
]]] )パラメータ
-
fetch_style -
PDOStatement::fetch() に文章化されているような 返される配列の内容を制御します。 デフォルトは
PDO::ATTR_DEFAULT_FETCH_MODEの値 (そのデフォルトはPDO::FETCH_BOTH) です。結果セットから単一カラムの全ての値を含む配列を返す場合、
PDO::FETCH_COLUMNを指定します。column-indexパラメータにどのカラムを返すかを 指定することができます。結果セットから単一カラムの一意な値のみ取得する場合、
PDO::FETCH_UNIQUEをビット OR したPDO::FETCH_COLUMNを指定します。指定したカラムの値によってグループ化した連想配列を返す場合、
PDO::FETCH_GROUPをビット OR したPDO::FETCH_COLUMNを指定します。 -
fetch_argument -
この引数は、
fetch_styleの値によって意味が異なります。-
PDO::FETCH_COLUMN: ここで指定した、 0 から始まる番号のカラムを返します。 -
PDO::FETCH_CLASS: ここで指定したクラスのインスタンスを返します。各行のカラムがクラスのプロパティ名にマッピングされます。 -
PDO::FETCH_FUNC: ここで指定した関数をコールした結果を返します。各行のカラムを関数コール時のパラメータとします。
-
-
ctor_args -
fetch_styleがPDO::FETCH_CLASSのときに使う、独自のクラスコンストラクタへの引数。
返り値
PDOStatement::fetchAll() は、 結果セットに残っている全ての行を含む配列を返します。 この配列は、カラム値の配列 もしくは各カラム名に対応するプロパティを持つオブジェクトをして 各行を表します。
大きな結果セットをフェッチするためにこのメソッドを使用することは、 システムとネットワークリソースに大量の要求を行うことになります。 PHP で全てのデータ処理と操作を行うよりも、データベースサーバー側で 結果セットを操作することを検討してください。例えば、PHP で処理を行う前に SQL で WHERE 句や ORDER BY 句を使用し、結果を制限することです。
例
例1 結果セットに残っている全ての行をフェッチする
<?php
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* 結果セットに残っている全ての行をフェッチする */
print("Fetch all of the remaining rows in the result set:\n");
$result = $sth->fetchAll();
print_r($result);
?>
上の例の出力は、 たとえば以下のようになります。
Fetch all of the remaining rows in the result set:
Array
(
[0] => Array
(
[NAME] => pear
[0] => pear
[COLOUR] => green
[1] => green
)
[1] => Array
(
[NAME] => watermelon
[0] => watermelon
[COLOUR] => pink
[1] => pink
)
)
例2 結果セットから単一カラムの全ての値を取得する
以下の例は、 SQL ステートメント自身が行毎に複数のカラムを返す場合において、 どのように結果セットから単一カラムの全ての値を取得するかを 例示しています。
<?php
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* 最初のカラムの全ての値を取得する */
$result = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
var_dump($result);
?>
上の例の出力は、 たとえば以下のようになります。
Array(3)
(
[0] =>
string(5) => apple
[1] =>
string(4) => pear
[2] =>
string(10) => watermelon
)
例3 単一カラムによる全ての値のグループ化
以下の例は、どのように結果セット中の特定のカラムの値によって グループ化された連想配列を返すかを例示しています。 その配列は 3 つのキーを有します。値 apple、 pear は異なる 2 つの異なる色を有する配列として返され、 一方 watermelon は 1 つの色のみ有する配列として返されます。
<?php
$insert = $dbh->prepare("INSERT INTO fruit(name, colour) VALUES (?, ?)");
$insert->execute(array('apple', 'green'));
$insert->execute(array('pear', 'yellow'));
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* 最初のカラムの値によってグループ化する */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>
上の例の出力は、 たとえば以下のようになります。
array(3) {
["apple"]=>
array(2) {
[0]=>
string(5) "green"
[1]=>
string(3) "red"
}
["pear"]=>
array(2) {
[0]=>
string(5) "green"
[1]=>
string(6) "yellow"
}
["watermelon"]=>
array(1) {
[0]=>
string(5) "green"
}
}
例4 各結果用のクラスのインスタンス作成
次の例は、
PDO::FETCH_CLASS の振る舞いを示すものです。
<?php
class fruit {
public $name;
public $colour;
}
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_CLASS, "fruit");
var_dump($result);
?>
上の例の出力は、 たとえば以下のようになります。
array(3) {
[0]=>
object(fruit)#1 (2) {
["name"]=>
string(5) "apple"
["colour"]=>
string(5) "green"
}
[1]=>
object(fruit)#2 (2) {
["name"]=>
string(4) "pear"
["colour"]=>
string(6) "yellow"
}
[2]=>
object(fruit)#3 (2) {
["name"]=>
string(10) "watermelon"
["colour"]=>
string(4) "pink"
}
}
例5 各結果に対する関数コール
次の例は、
PDO::FETCH_FUNC の振る舞いを示すものです。
<?php
function fruit($name, $colour) {
return "{$name}: {$colour}";
}
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_FUNC, "fruit");
var_dump($result);
?>
上の例の出力は、 たとえば以下のようになります。
array(3) {
[0]=>
string(12) "apple: green"
[1]=>
string(12) "pear: yellow"
[2]=>
string(16) "watermelon: pink"
}
参考
- PDO::query() - SQL ステートメントを実行し、結果セットを PDOStatement オブジェクトとして返す
- PDOStatement::fetch() - 結果セットから次の行を取得する
- PDOStatement::fetchColumn() - 結果セットの次行から単一カラムを返す
- PDO::prepare() - 文を実行する準備を行い、文オブジェクトを返す
- PDOStatement::setFetchMode() - この文に対するデフォルトのフェッチモードを設定する
If you use the PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE flags to map columns to object properties, fetchAll() will use any __set() method your object has when carrying out the mapping.
Note that fetchAll() can be extremely memory inefficient for large data sets. My memory limit was set to 160 MB this is what happened when I tried:
<?php
$arr = $stmt->fetchAll();
// Fatal error: Allowed memory size of 16777216 bytes exhausted
?>
If you are going to loop through the output array of fetchAll(), instead use fetch() to minimize memory usage as follows:
<?php
while ($arr = $stmt->fetch()) {
echo round(memory_get_usage() / (1024*1024),3) .' MB<br />';
// do_other_stuff();
}
// Last line for the same query shows only 28.973 MB usage
?>
Error:
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
If you're using something like:
while ($row = $query->fetchObject()) {
[...]
}
try using this instead:
$rows = $query->fetchAll(PDO::FETCH_CLASS, 'ArrayObject');
foreach ($rows as $row) {
[...]
}
Interestingly enough, when you use fetchAll, the constructor for your object is called AFTER the properties are assigned. For example:
<?php
class person {
public $name;
function __construct() {
$this->name = $this->name . " is my name.";
}
}
# set up select from a database here with PDO
$obj = $STH->fetchALL(PDO::FETCH_CLASS, 'person');
?>
Will result in ' is my name' being appended to all the name columns. However if you call it slightly differently:
<?php
$obj = $obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');
?>
Then the constructor will be called before properties are assigned. I can't find this documented anywhere, so I thought it would be nice to add a note here.
In method body:
return $pstmt->fetchAll() or die("bad");
will not return correct value, but "1" instead.
PLEASE BE AWARE: If you do an OUTER LEFT JOIN and set PDO FetchALL to PDO::FETCH_ASSOC, any primary key you used in the OUTER LEFT JOIN will be set to a blank if there are no records returned in the JOIN.
For example:
<?php
//query the product table and join to the image table and return any images, if we have any, for each product
$sql = "SELECT * FROM product, image
LEFT OUTER JOIN image ON (product.product_id = image.product_id)";
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($array);
?>
The resulting array will look something like this:
Array
(
[0] => Array
(
[product_id] =>
[notes] => "this product..."
[brand] => "Best Yet"
...
The fix is to simply specify your field names in the SELECT clause instead of using the * as a wild card, or, you can also specify the field in addition to the *. The following example returns the product_id field correctly:
<?php
$sql = "SELECT *, product.product_id FROM product, image
LEFT OUTER JOIN image ON (product.product_id = image.product_id)";
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($array);
?>
The resulting array will look something like this:
Array
(
[0] => Array
(
[product_id] => 3
[notes] => "this product..."
[brand] => "Best Yet"
...
You might find yourself wanting to use FETCH_GROUP and FETCH_ASSOC at the same time, to get your table's primary key as the array key:
<?php
// $stmt is some query like "SELECT rowid, username, comment"
$results = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
// It does work, but not as you might expect:
$results = array(
1234 => array(0 => array('username' => 'abc', 'comment' => '[...]')),
1235 => array(0 => array('username' => 'def', 'comment' => '[...]')),
);
// ...but you can at least strip the useless numbered array out easily:
$results = array_map('reset', $results);
?>
When passing PDO::FETCH_CLASS as the first argument, this method will accept the class name as the second option:
<?php
$query = $pdo->prepare($sql);
$result = $query->execute($values);
if ($result && $query->rowCount() > 0) {
$records = $query->fetchAll(PDO::FETCH_CLASS, 'Some_Class');
// $record is now an array of Some_Class objects
}
?>
- Davey
PHP fetchAll Data From SQL Server 2005
if field's data type is varchar(nvarchar), only fetch 255 chars. but the "text" data type is ok.
so, notice! to change the 'varchar' or 'nvarchar' (length > 255) to 'text' data type..
hope to help u.
<?php
$user = 'sa';
$pass = 'pass';
$conn = new PDO('mssql:host=127.0.0.1; dbname=tempdb;', $user, $pass);
$mainSQL = "SELECT field_varchar, field_text FROM table1";
$sth = $conn->prepare($mainSQL);
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
$retRows = $sth->fetchAll();
// the field_varchar field only to fetch 255 chars(max)
// the field_text is ok.
var_dump($retRows);
unset($sth); unset($conn);
?>
There is also another fetch mode supported on Oracle and MSSQL:
PDO::FETCH_ASSOC
> fetches only column names and omits the numeric index.
If you would like to return all columns from an sql statement with column keys as table headers, it's as simple as this:
<?php
$dbh = new PDO("DS", "USERNAME", "PASSWORD");
$stmt = $dbh->prepare("SELECT * FROM tablename");
$stmt->execute();
$arrValues = $stmt->fetchAll(PDO::FETCH_ASSOC);
// open the table
print "<table wdith=\"100%\">\n";
print "<tr>\n";
// add the table headers
foreach ($arrValues[0] as $key => $useless){
print "<th>$key</th>";
}
print "</tr>";
// display data
foreach ($arrValues as $row){
print "<tr>";
foreach ($row as $key => $val){
print "<td>$val</td>";
}
print "</tr>\n";
}
// close the table
print "</table>\n";
?>
If no rows have been returned, fetchAll returns an empty array.
Note, that you can use PDO::FETCH_COLUMN|PDO::FETCH_GROUP pair only while selecting two columns, not like DB_common::getAssoc(), when grouping is set to true.
