CakeFest 2024: The Official CakePHP Conference

PDOStatement::fetchAll

(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.1.0)

PDOStatement::fetchAll Récupère les lignes restantes d'un ensemble de résultats

Description

public PDOStatement::fetchAll(int $mode = PDO::FETCH_DEFAULT): array
public PDOStatement::fetchAll(int $mode = PDO::FETCH_COLUMN, int $column): array
public PDOStatement::fetchAll(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs): array
public PDOStatement::fetchAll(int $mode = PDO::FETCH_FUNC, callable $callback): array

Liste de paramètres

mode

Contrôle le contenu du tableau retourné comme documenté dans la fonction PDOStatement::fetch(). Valeur par défaut : PDO::ATTR_DEFAULT_FETCH_MODE (qui prend sa valeur par défaut de PDO::FETCH_BOTH).

Pour retourner un tableau contenant toutes les valeurs d'une seule colonne depuis le jeu de résultats, spécifiez PDO::FETCH_COLUMN. Vous pouvez spécifier quelle colonne vous voulez avec le paramètre column.

Pour récupérer uniquement les valeurs uniques d'une seule colonne depuis le jeu de résultats, utilisez PDO::FETCH_COLUMN avec PDO::FETCH_UNIQUE.

Pour retourner un tableau associatif groupé par les valeurs d'une colonne spécifique, utilisez PDO::FETCH_COLUMN avec PDO::FETCH_GROUP.

Les paramètres suivants sont dynamiques et dépendent du mode de récupération. Ils ne peuvent pas être utilisés avec des paramètres nommés.
column

Utilisé avec PDO::FETCH_COLUMN. Renvoie la colonne indiquée indexée à 0.

class

Utilisé avec PDO::FETCH_CLASS. Renvoie des instances de la classe spécifiée, en faisant correspondre les colonnes de chaque ligne à des propriétés nommées dans la classe.

constructorArgs

Arguments du constructeur personnalisé de la classe lorsque l'argument mode est à PDO::FETCH_CLASS.

callback

Utilisé avec PDO::FETCH_FUNC. Renvoie les résultats de l'appel de la fonction spécifiée, en utilisant les colonnes de chaque ligne comme paramètres dans l'appel.

Valeurs de retour

PDOStatement::fetchAll() retourne un tableau contenant toutes les lignes du jeu d'enregistrements. Le tableau représente chaque ligne comme soit un tableau de valeurs des colonnes, soit un objet avec des propriétés correspondant à chaque nom de colonne. Un tableau vide est retourné s'il y a zéro résultat.

L'utilisation de cette méthode pour récupérer de gros jeux de résultats peut augmenter les ressources du système, mais également ces ressources. Plutôt que de récupérer toutes les données et de les manipuler avec PHP, utilisez le serveur de base de données pour manipuler les jeux de résultats. Par exemple, utilisez les clauses WHERE et ORDER BY dans vos requêtes SQL pour restreindre les résultats avant de les récupérer et de les traiter avec PHP.

Erreurs / Exceptions

Émet une erreur de niveau E_WARNING si l'attribut PDO::ATTR_ERRMODE est défini à PDO::ERRMODE_WARNING.

Lève une exception PDOException si l'attribut PDO::ATTR_ERRMODE est défini à PDO::ERRMODE_EXCEPTION.

Historique

Version Description
8.0.0 Cette méthode retourne désormais toujours un tableau, auparavant false pouvait être retourné en cas d'échec.

Exemples

Exemple #1 Récupération de toutes les lignes d'un jeu de résultats

<?php
$sth
= $dbh->prepare("SELECT nom, couleur FROM fruit");
$sth->execute();

/* Récupération de toutes les lignes d'un jeu de résultats */
print "Récupération de toutes les lignes d'un jeu de résultats :\n";
$result = $sth->fetchAll();
print_r($result);
?>

Résultat de l'exemple ci-dessus est similaire à :

Récupération de toutes les lignes d'un jeu de résultats :
Array
(
    [0] => Array
        (
            [nom] => apple
            [0] => apple
            [couleur] => red
            [1] => red
        )

    [1] => Array
        (
            [nom] => pear
            [0] => pear
            [couleur] => green
            [1] => green
        )

    [2] => Array
        (
            [nom] => watermelon
            [0] => watermelon
            [couleur] => pink
            [1] => pink
        )

)

Exemple #2 Récupération de toutes les valeurs d'une seule colonne depuis un jeu de résultats

L'exemple suivant montre comment retourner toutes les valeurs d'une seule colonne depuis un jeu de résultats, même si la requête SQL retourne plusieurs colonnes par lignes.

<?php
$sth
= $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

/* Récupération de toutes les valeurs de la première colonne */
$result = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
var_dump($result);
?>

Résultat de l'exemple ci-dessus est similaire à :

Array(3)
(
    [0] =>
    string(5) => apple
    [1] =>
    string(4) => pear
    [2] =>
    string(10) => watermelon
)

Exemple #3 Grouper toutes les valeurs d'une seule colonne

L'exemple suivant montre comment retourner un tableau associatif groupé par les valeurs de la colonne spécifiée d'un jeu de résultats. Le tableau contient trois clés : les valeurs apple et pear sont retournées sous la forme de tableaux qui contiennent deux couleurs différentes, tandis que watermelon est retourné sous la forme d'un tableau qui contient uniquement une seule couleur.

<?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();

/* Grouper les valeurs de la première colonne */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>

Résultat de l'exemple ci-dessus est similaire à :

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) "pink"
    }
}

Exemple #4 Instancier une classe pour chaque résultat

L'exemple suivant montre le comportement de 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);
?>

Résultat de l'exemple ci-dessus est similaire à :

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"
  }
  [3]=>
  object(fruit)#4 (2) {
    ["name"]=>
    string(5) "apple"
    ["colour"]=>
    string(3) "red"
  }
  [4]=>
  object(fruit)#5 (2) {
    ["name"]=>
    string(4) "pear"
    ["colour"]=>
    string(5) "green"
  }
}

Exemple #5 Appel d'une fonction pour chaque résultat

L'exemple suivant montre le comportement de 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);
?>

Résultat de l'exemple ci-dessus est similaire à :

array(3) {
  [0]=>
  string(12) "apple: green"
  [1]=>
  string(12) "pear: yellow"
  [2]=>
  string(16) "watermelon: pink"
  [3]=>
  string(10) "apple: red"
  [4]=>
  string(11) "pear: green"
}

Voir aussi

add a note

User Contributed Notes 32 notes

up
95
simplerezo at gmail dot com
7 years ago
I still don't understand why FETCH_KEY_PAIR is not documented here (http://php.net/manual/fr/pdo.constants.php), because it could be very useful!

<?php
var_dump
($pdo->query('select id, name from table')->fetchAll(PDO::FETCH_KEY_PAIR));
?>

This will display:
array(2) {
[2]=>
string(10) "name2"
[5]=>
string(10) "name5"
}
up
48
dyukemedia at gmail dot com
9 years ago
Getting foreach to play nicely with some data from PDO FetchAll()
I was not understanding to use the $value part of the foreach properly, I hope this helps someone else.
Example:
<?php
$stmt
= $this->db->prepare('SELECT title, FMarticle_id FROM articles WHERE domain_name =:domain_name');
$stmt->bindValue(':domain_name', $domain);
$stmt->execute();
$article_list = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
which gives:

array (size=2)
0 =>
array (size=2)
'title' => string 'About Cats Really Long title for the article' (length=44)
'FMarticle_id' => string '7CAEBB15-6784-3A41-909A-1B6D12667499' (length=36)
1 =>
array (size=2)
'title' => string 'another cat story' (length=17)
'FMarticle_id' => string '0BB86A06-2A79-3145-8A02-ECF6EA5C405C' (length=36)

Then use:
<?php
foreach ($article_list as $row => $link) {
echo
'<a href="'. $link['FMarticle_id'].'">' . $link['title']. '</a></br>';
}
?>
up
37
esw at pixeloution dot removeme dot com
13 years ago
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.
up
21
Daniel Hofmann
14 years ago
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"
...
up
39
Ant P.
15 years ago
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);
?>
up
19
Anonymous
12 years ago
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
?>
up
19
fractalesque at gmail dot com
9 years ago
to fetch rows grouped by primary id or any other field you may use FETCH_GROUP with FETCH_UNIQUE:

<?php

//prepare and execute a statement returning multiple rows, on a single one
$stmt = $db->prepare('SELECT id,name,role FROM table');
$stmt->execute();
var_dump($stmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_UNIQUE));

//returns an array with the first selected field as key containing associative arrays with the row. This mode takes care not to repeat the key in corresponding grouped array.

$result = array
(
1 => array
(
'name'=>'foo',
'role'=>'sage',),
2 => array
(
'name'=>'bar',
'role'=>'rage',),);

// 'SELECT name,id,role FROM table' would result in that:

$result = array
(
'foo' => array
(
'id'=>1,
'role'=>'sage',),
'bar' => array
(
'id'=>2,
'role'=>'rage',),);

?>
up
10
michael dot arnauts at gmail dot com
10 years ago
If you want to use PDO::FETCH_CLASS but don't like that all the values are of the type string, you can always use the __construct function of the class specified to convert them to a different type.

Another way is using mysqlnd, but it seems I had to recompile PHP for that.

<?php

class Cdr {
public
$a; // int
public $b; // float
public $c; // string

public function __construct() {
$this->a = intval($this->a);
$this->b = floatval($this->b);
}

}

// ...
$arrCdrs = $objSqlStatement->fetchAll(PDO::FETCH_CLASS, 'Cdr');

?>
up
5
info at yuriblanc dot it
8 years ago
Something missing in the doc.
If for instance you try to fetchAll(PDO::CLASS, "Class") it sometimes return an array of objects with NULL values, but the count of objects fetched correspond to table rows.

In this way works fine:
fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Class");

For example

$stm = $pdo->prepare("SELECT * FROM Fruit");
$stm->execute();
$stm->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Fruit");
up
6
Hayley Watson
12 years ago
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.
up
21
Anonymous
16 years ago
If no rows have been returned, fetchAll returns an empty array.
up
1
shaunc
1 year ago
Note that \PDO::FETCH_DEFAULT was not introduced until PHP 8.0.7 and 8.1.0. It will throw an undefined constant error in earlier versions.
up
3
Anonymous
7 years ago
Be careful when using PDO::FETCH_COLUMN with PDO::FETCH_GROUP. By default, results are grouped by first column (index 0) and second column (index 1) is returned. But, if you provide fetch argument, it wouldn't affect returned column, but grouping column. If grouping column is set explicitly , first columns is returned instead of second.

<?php
$insert
= $dbh->prepare("INSERT INTO people(id, gender) VALUES (?, ?)");
$insert->execute(array('2', 'female'));
$insert->execute(array('3', 'female'));
$insert->execute(array('4', 'female'));
$insert->execute(array('5', 'male'));
$insert->execute(array('6', 'male'));

$sth = $dbh->prepare("SELECT gender, id FROM people");
$sth->execute();

/* Group values by the first column */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>
Returns:
<?php
array (size=2)
'female' =>
array (
size=3)
0 => string '2' (length=1)
1 => string '3' (length=1)
2 => string '4' (length=1)
'male' =>
array (
size=2)
0 => string '5' (length=1)
1 => string '6' (length=1)
?>

But,
<?php
var_dump
($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP, 0));
?>
returns:
<?php
array (size=2)
'female' =>
array (
size=3)
0 => string 'female' (length=1)
1 => string 'female' (length=1)
2 => string 'female' (length=1)
'male' =>
array (
size=2)
0 => string 'male' (length=1)
1 => string 'male' (length=1)
?>
and
<?php
var_dump
($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP, 1));
?>
returns
<?php
array (size=5)
2 =>
array (
size=1)
0 => string 'female' (length=1)
3 =>
array (
size=1)
0 => string 'female' (length=1)
4 =>
array (
size=1)
0 => string 'female' (length=1)
5 =>
array (
size=1)
0 => string 'male' (length=1)
6 =>
array (
size=1)
0 => string 'male' (length=1)
?>

First column is retuned and grouping is done by provided column index.
up
3
lu_kors
6 years ago
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 - use FETCH_UNIQUE also, or you will probably get some unintended behaivor:
<?php
// $stmt is some query like "SELECT rowid, username, comment"

//with unique
$results = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
$results = array(
1234 => array('username' => 'abc', 'comment' => '[...]'),
1235 => array('username' => 'def', 'comment' => '[...]'),
);
//without unique
$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' => '[...]')),
);
?>
Credit to Ant P. for minimal Example (which i shamelessly copied from the note above me). Thanks a lot!
up
4
stas at metalinfo dot ru
17 years ago
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.
up
3
mxrgus
14 years ago
In method body:

return $pstmt->fetchAll() or die("bad");

will not return correct value, but "1" instead.
up
8
harlequin2 at gmx dot de
15 years ago
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";
?>
up
2
mrshelly at hotmail dot com
15 years ago
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);

?>
up
2
Dennis
13 years ago
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) {
[...]
}
up
1
akira at etnforum dot com
9 years ago
There may be some user who needs to upgrade their MySQL class to PDO class. The way of fetching results were changed from while loop into a foreach loop. For the people who wish to fetch the results in a while loop, here is a simple trick.

<?php

$db
= new DB();
$query = $db->prepare("SELECT * FROM CPUCategory");
$query = $db->execute();
$result = $db->fetchAll();
var_dump($result);

?>

The Output will be:
array(2) {
[0]=> array(2) {
["ccatid"]=> int(1)
["ccatname"]=> string(5) "Intel"
}
[1]=> array(2) {
["ccatid"]=> int(2)
["ccatname"]=> string(3) "AMD"
}
}

Never look like the output of old function.
[ORIGINAL STYLE] mysql_fetch_array($query)
[ MYSQL CLASS] $db->fetch_array($query)

And you may give up.
But there is a simple way to use while loop to fetch the results.

<?php

$db
= new DB();
$query = $db->prepare("SELECT * FROM CPUCategory");
$query = $db->execute();
$result = $db->fetchAll();
$row = array_shift($result);
// If you need to fetch them now, put it in a while loop just like below:
// while($row = array_shift($result)) { ... }

var_dump($row);

?>

The Output will be in a single array with while loop returns TRUE:
array(2) {
["ccatid"]=> int(1)
["ccatname"]=> string(5) "Intel"
}

So after fetching this row, while loop runs again and fetch the next row until all row has fetched, then the while loop will return false. (Just like the old function did)

When you need to upgrade to PDO class, not much code needs to be modified and remember.
up
1
php at erikthiart dot com
2 years ago
I am adding this here as I don’t seem to find any clear and easy to find examples and explanations of PDO::FETCH_GROUP and how it works by means of an example.

I find this to be one of the most useful modes available in fetchAll() when you need to work with any form of grouping.

In essence, PDO can group results into nested arrays, based on the first field selected.

Example

<?php

$data
= $pdo->query('SELECT sex, name, car FROM users')->fetchAll(PDO::FETCH_GROUP);

/* array (
'male' => array ( 0 =>
array (
'name' => 'John',
'car' => 'Toyota',
),
1 => array (
'name' => 'Mike',
'car' => 'Ford',
),
),
'female' => array (
0 => array (
'name' => 'Mary',
'car' => 'Mazda',
),
1 => array (
'name' => 'Kathy',
'car' => 'Mazda',
),
),
) */

?>

Tip: If you need to group the data by something other than the first field then you can do it like this as well

<?php
SELECT sex
, users.* FROM users
?>
up
0
herhor67 at interia dot pl
3 years ago
I noticed quite a weird (at least for me) behaviour. Maybe it can help someone who will struggle with this too.

<?php
$stmt
= new PDOStatement();
$foo = $stmt->fetchAll();
var_dump($foo);

$stmt = $pdo->prepare('SELECT VERSION()');
$foo = $stmt->fetchAll();
var_dump($foo);

$stmt = $pdo->prepare("INSERT INTO `tblnm` (date) VALUES (NOW())");
$stmt->execute();
$foo = $stmt->fetchAll();
var_dump($foo);

$stmt = $pdo->query("INSERT INTO `tblnm` (date) VALUES (NOW())");
$foo = $stmt->fetchAll();
var_dump($foo);
?>

The first is just an empty object, so $foo === bool(false)
The second one is not executed, so $foo === array(0) {}
The third and fourth throw exception at fetchAll():
"General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, [...] you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute."

fetchAll() is already used, and changing the above attribute between true and false changes nothing.
This is probably caused by the INSERT not having any return value. We could use RETURNING in the sql, but it's quite new, so may not yet be supported everywhere.

What finally worked for me, was $pdo->exec() and lastInsertId(), because ID is the only column I needed anyway.
<?php
$count
= $pdo->exec('INSERT INTO `tblnm` (date) VALUES (NOW())');
$foo = $pdo->lastInsertId();
var_dump($foo);
?>
Then e.g. $foo === string(2) "93"
up
0
geompse at gmail dot com
3 years ago
There is a breaking change upgrading from PHP<7.4 to PHP 8.0. If your class extend PDOStatement, the PHP 8.0 typed prototype is incompatible :
- PHP 7.4 = public PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] ) : array
- PHP 8.0 = public PDOStatement::fetchAll ([ int $mode = PDO::FETCH_BOTH[, mixed ...$args] ]) : array

While they are compatible for a human being, PHP is not enjoying it :
- PHP 7.4 = PHP Warning: Declaration of (your class prototype) should be compatible with (PDOStatement's prototype)
- PHP 8.0 = [PhpCompileError] Declaration of (your class prototype) must be comptable with (PDOStatement's prototype)

Because the first one is a warning, it is not fatal, and you might be happy using PHP 8.0's prototype. My personal solution was to stop extending PDOStatement and thus rewrite associated typing declarations and conditions.
up
0
Leonardo Costa linux at linuxmanbr dot com dot br
4 years ago
Method with Return object (PHP 7.2)

class MySql {

public function __construct()
{
parent::__construct();

try{



$options = array
(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"
);

$this->pdo = new PDO('mysql:host=127.0.0.1;dbname=testuser','dbtest', 'xxxxxxx',$options);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

}catch(PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}

public function selectAll(string $sql)
{
$conn = $this->pdo->query($sql);
return $conn->fetchAll(PDO::FETCH_OBJ);
}
}
up
0
rudigerw at hotmail dot com
5 years ago
I was blown away that you can actually combine PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_UNIQUE, because both PDO::FETCH_CLASSTYPE and PDO::FETCH_UNIQUE say they will use the first column, but it turns out PDO::FETCH_CLASSTYPE goes first and then PDO::FETCH_UNIQUE will use the next column. This way you can create an associative array of objects, with one of the table columns as key. For example a query such as

'SELECT Class, Id, t.* FROM subscriptions_tbl t'

might give you this result:

Array
(
[20481086] => WConsumerSubscription Object
(
[Variant] => 2
[_Expiration:WSubscriptionModel:private] => DateTime Object
(
[date] => 2018-08-08 00:00:00.000000
[timezone_type] => 3
[timezone] => UTC
)

[Notes] =>
[Id] => 20481086
[_Deleted:protected] => 0
[_VersionNo:protected] => 2
[ContactId] =>
[ConsumerId] => 2
)

[21878324] => WAdminSubscription Object
(
[Variant] =>
[_Expiration:WSubscriptionModel:private] =>
[Notes] =>
[Id] => 21878324
[_Deleted:protected] => 0
[_VersionNo:protected] => 1
[ContactId] =>
)
)
up
-1
sidi dot khalifa at live dot fr
4 years ago
Inject the parameters directly into `fetchAll` instead of using `bindValue`

$query = "
SELECT
a.total_paid_tax_incl AS prize,
a.date_add AS date_add
FROM orders a
WHERE a.order_id = :seventeen
AND a.name = :name";

// connection (Example in Symfony you use class Connection in namespace Doctrine\DBAL\Connection)
$this->connection->fetchAll($query, ['seventeen' => 70, 'name' => 'Sidi'])
up
0
jeroen dot deklerk at hotmail dot com
7 years ago
I was having trouble with returning PDO query results in arrays, due to the structure of the results of those queries (query array with arrays for results inside). Now when executing a fetchAll() on a query you get the following:

Array ( [0] = Array ( [key1] => "value1", [key2] => "value2") [1] = Array( [key1] => "value1", [key2] => "value2") )

This is a smaller array, but return results in a HUGE database this way and it quickly becomes IMPPOSIBRU to read out the array given.

This is where the glorious foreach comes in! We all know the basic writing of a foreach (foreach ($array as $key => $value) {...}), but with query results there's a twist, as both the $key AND $value variables are arrays, where $key is the array of the query containing the result arrays and $value is/are the result array(s) themselves.

So in this foreach we have to talk directly to $value to get our results! This would look something like this:

<?php

foreach ($query as $key => $value) {
return
$value["key2"];
}

?>

This already does the job, but to return them in arrays we have to change our return code a little bit, like so:

<?php

foreach ($query as $key => $value) {
return array (
"key1" => $value["key1"],
"key2" => $value["key2"]
);
}

?>

This foreach loops through the query array, just like the firs one, but the return code just doesn't return the keys representing the result arrays ($key) and returns only keys from inside the result arrays, stored in $value. This gives us an array looking like this:

Array ( [key1] => "value1", [key2] => "value2")

This should return all the values in your array, if written properly. I'm still having problems with the foreach not returning ALL results, but this note was mainly to show how it can be returned in an array.
up
-2
janniet at kiekies dot net
9 years ago
If you want to fetch rows as an object for which you have not defined a class, you can do:
<?php
$result
= $q->fetchAll(PDO::FETCH_OBJ);
?>
up
-1
davey at php dot net
15 years ago
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
up
-3
ramon at monztro dot com
11 years ago
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.

:)
up
-6
GyoreG
9 years ago
If you would like to get the result as "key-value-pairs", like:

Array(
[key1] => "value1"
[key2] => "value2"
)

then you can do it by calling fetchAll with PDO::FETCH_GROUP | PDO::FETCH_COLUMN parameters.

<?php
$result
= $query->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_COLUMN);
?>
up
-13
Dean S.
8 years ago
Using fetchAll() with the fetch types PDO::FETCH_GROUP and PDO::FETCH_ASSOC, PDO::FETCH_CLASS will always use the first column in the selected table as the key for the row in the output...
To Top