1
0
mirror of https://github.com/php/doc-en.git synced 2026-03-23 23:32:18 +01:00
Files
archived-doc-en/reference/pdo/constants.fetch-modes.xml

1453 lines
37 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<section xmlns="http://docbook.org/ns/docbook" xml:id="pdo.constants.fetch-modes">
<title>Fetch Modes</title>
<simpara>
See <link linkend="pdo.constants.cursors">cursor constants</link> for the
<literal>PDO::FETCH_ORI_*</literal> cursor constants.
</simpara>
<section xml:id="pdo.fetch-modes.basic" annotations="chunk:false">
<title>Basic Fetch Modes</title>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Fetch Mode</entry>
<entry>Summary</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<constant>PDO::FETCH_DEFAULT</constant>
</entry>
<entry>
Special value for using the current default fetch mode.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_ASSOC</constant>
</entry>
<entry>
Array indexed by column name only.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_BOTH</constant> (Default)
</entry>
<entry>
Array indexed by both column number and name.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_NAMED</constant>
</entry>
<entry>
Variant of <constant>PDO::FETCH_ASSOC</constant> that retains duplicated
columns.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_NUM</constant>
</entry>
<entry>
Array indexed by column number only.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_COLUMN</constant>
</entry>
<entry>
A single column.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_KEY_PAIR</constant>
</entry>
<entry>
Key-value pairs, indexed by the first column.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_FUNC</constant>
</entry>
<entry>
Use a function to create the return value.
(<methodname>PDOStatement::fetchAll</methodname> only)
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_OBJ</constant>
</entry>
<entry>
Anonymous (<classname>stdClass</classname>) object.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_CLASS</constant>
</entry>
<entry>
An object of a specified class.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section xml:id="pdo.fetch-modes.class-flags" annotations="chunk:false">
<title>PDO::FETCH_CLASS options</title>
<simpara>
These modes are used to implement options when using
<constant>PDO::FETCH_CLASS</constant>.
</simpara>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Fetch Mode</entry>
<entry>Summary</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<constant>PDO::FETCH_CLASSTYPE</constant>
</entry>
<entry>
Use the first column as the class name.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_PROPS_LATE</constant>
</entry>
<entry>
Call the constructor before setting properties.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_SERIALIZE</constant>
</entry>
<entry>
Use PHP serialized data. Deprecated as of PHP 8.1.0.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section xml:id="pdo.fetch-modes.single" annotations="chunk:false">
<title>Single Result Modes</title>
<simpara>
The following modes cannot be used with
<methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Fetch Mode</entry>
<entry>Summary</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<constant>PDO::FETCH_BOUND</constant>
</entry>
<entry>
Bind values to specified variables.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_INTO</constant>
</entry>
<entry>
Update an existing object.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_LAZY</constant>
</entry>
<entry>
Lazy fetch via <classname>PDORow</classname> for array- and object-like
access.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section xml:id="pdo.fetch-modes.grouped" annotations="chunk:false">
<title>
Special Behavior Flags for <methodname>PDOStatement::fetchAll</methodname>
</title>
<simpara>
The following special modes for multiple results only work with
<methodname>PDOStatement::fetchAll</methodname> and do not work with some other
fetch modes. Check the full documentation for details.
</simpara>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Fetch Mode</entry>
<entry>Summary</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<constant>PDO::FETCH_GROUP</constant>
</entry>
<entry>
Results are grouped by the first column.
</entry>
</row>
<row>
<entry>
<constant>PDO::FETCH_UNIQUE</constant>
</entry>
<entry>
Results are (uniquely) indexed by the first column.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section xml:id="pdo.fetch-modes.duplicate-names" annotations="chunk:false">
<title>Handling of Duplicated Column Names</title>
<simpara>
It's possible for results to contain multiple columns that use the same name.
For example, when joining 2 tables that both contain a column with the same
name.
</simpara>
<simpara>
Because PHP structures such as arrays and objects don't support multiple keys
or properties that use the same name, the returned array or object will
contain only 1 of the values using the same name.
</simpara>
<simpara>
Which value is returned for a given duplicated name should be considered
undefined.
</simpara>
<simpara>
To avoid this issue, explicitly name columns using an alias. For example:
</simpara>
<informalexample>
<programlisting role="sql">
<![CDATA[
SELECT table1.created_at AS t1_created_at,
table2.created_at AS t2_created_at
FROM table1
JOIN table2 ON table1.table2id = table2.id
]]>
</programlisting>
</informalexample>
<simpara>
See also <constant>PDO::FETCH_NAMED</constant>,
<constant>PDO::ATTR_FETCH_TABLE_NAMES</constant> and
<constant>PDO::ATTR_FETCH_CATALOG_NAMES</constant>.
</simpara>
</section>
<section xml:id="pdo.fetch-modes.default" annotations="chunk:false">
<title>Setting the Default Fetch Mode</title>
<simpara>
It is possible to set default fetch mode for all queries using
<constant>PDO::ATTR_DEFAULT_FETCH_MODE</constant> with
<methodname>PDO::__construct</methodname> or
<methodname>PDO::setAttribute</methodname>.
</simpara>
<simpara>
The default fetch mode for a specific statement can be set using
<methodname>PDOStatement::setFetchMode</methodname>.
This affects reuse as a prepared statement and iteration (using
&foreach;).
</simpara>
<caution>
<simpara>
<methodname>PDOStatement::setAttribute</methodname> cannot be used to set the
default fetch mode. It only accepts driver specific attributes and silently
ignores attributes that are not recognized.
</simpara>
</caution>
</section>
<section xml:id="pdo.constants.fetch-default" annotations="chunk:false">
<title>PDO::FETCH_DEFAULT (<type>int</type>)</title>
<simpara>
Available as of PHP 8.0.7.
</simpara>
<simpara>
This is a special value that uses the current default fetch mode for a
<classname>PDOStatement</classname>. It's specifically useful as the default
value for method parameters when extending
<classname>PDOStatement</classname> for use with
<constant>PDO::ATTR_STATEMENT_CLASS</constant>.
</simpara>
<para>
This value cannot be used with
<constant>PDO::ATTR_DEFAULT_FETCH_MODE</constant>.
</para>
</section>
<section xml:id="pdo.constants.fetch-assoc" annotations="chunk:false">
<title>PDO::FETCH_ASSOC (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_ASSOC</constant> returns an array indexed by column name
only.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[userid] => 104
[name] => Chris
[country] => Ukraine
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-both" annotations="chunk:false">
<title>PDO::FETCH_BOTH (<type>int</type>)</title>
<simpara>
This is the default fetch mode.
</simpara>
<simpara>
<constant>PDO::FETCH_BOTH</constant> returns an array indexed by both column
number and name. This means that every returned value is duplicated for each
result row.
</simpara>
<simpara>
The column number starts at 0 and is determined by the result column order in
the query, not (for example) the order columns are defined in the table.
</simpara>
<note>
<simpara>
Using the numeric column index is not recommended as this may change when
the query is changed, or when the table schema is changed when using
<literal>SELECT *</literal>.
</simpara>
</note>
<note>
<simpara>
The number of entries indexed by name may not match the number of entries
indexed by number in cases where multiple returned columns use the same
name.
</simpara>
</note>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_BOTH);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[id] => 104,
[0] => 104,
[name] => Chris,
[1] => Chris,
[country] => Ukraine,
[2] => Ukraine
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-named" annotations="chunk:false">
<title>PDO::FETCH_NAMED (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_NAMED</constant> returns results in the same format as
<constant>PDO::FETCH_ASSOC</constant> except that where multiple columns use
the same name, all values are returned as a list.
</simpara>
<simpara>
For more information on handling of duplicated column names and alternatives,
see the <link linkend="pdo.fetch-modes.duplicate-names">handling of
duplicated names section</link> above.
</simpara>
<simpara>
The order in which duplicated values are returned should be considered
undefined. There's no way to tell where each value came from.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query(
"SELECT users.*, referrer.name
FROM users
LEFT JOIN users AS referrer ON users.referred_by = referrer.userid
WHERE userid = 109"
);
$row = $stmt->fetch(\PDO::FETCH_NUM);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[userid] => 109
[name] => Array
(
[0] => Toni
[1] => Chris
)
[country] => Germany
[referred_by] = 104
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-num" annotations="chunk:false">
<title>PDO::FETCH_NUM (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_NUM</constant> returns an array indexed by column number
only. The column number starts at 0 and is determined by the result column order in
the query, not (for example) the order columns are defined in the table.
</simpara>
<note>
<simpara>
Using the numeric column index is not recommended as this may change when
the query is changed, or when the table schema is changed when using
<literal>SELECT *</literal>.
</simpara>
</note>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_NUM);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => 104
[1] => Chris
[2] => Ukraine
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-column" annotations="chunk:false">
<title>PDO::FETCH_COLUMN (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_COLUMN</constant> returns values from a single column.
Use the second argument for <methodname>PDOStatement::setFetchMode</methodname>
or <methodname>PDOStatement::fetchAll</methodname> to specify which column is
returned.
</simpara>
<simpara>
If the specified column does not exist a <classname>ValueError</classname>
will be thrown.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_COLUMN);
print_r($row);
$stmt = $pdo->query("SELECT name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_COLUMN, 1);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => Chris
[1] => Jamie
[2] => Robin
)
Array
(
[0] => Ukraine
[1] => England
[2] => Germany
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-key-pair" annotations="chunk:false">
<title>PDO::FETCH_KEY_PAIR (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_KEY_PAIR</constant> returns pairs of values, indexed by
the first column. The results must contain only 2 columns. This fetch mode
only makes sense with <methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<note>
<simpara>
If the first column is not unique, values will be lost. Which value(s) are
lost should be considered undefined.
</simpara>
</note>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[Chris] => Ukraine
[Jamie] => England
[Robin] => Germany
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-func" annotations="chunk:false">
<title>PDO::FETCH_FUNC (<type>int</type>)</title>
<simpara>
Specify a function to create the returned value. This mode can only be used
with <methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<simpara>
The function receives the values as parameters.
There's no way to retrieve the column name a given value was associated with.
It is crucial to ensure that the column order in the query matches the
order of parameters of the function.
</simpara>
<note>
<simpara>
The effects of <constant>PDO::FETCH_GROUP</constant> and
<constant>PDO::FETCH_UNIQUE</constant> are applied to results before the
function is called.
</simpara>
</note>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function valueCreator($col1, $col2, $col3)
{
return [
'col1' => $col1,
'col2' => strtoupper($col2),
'col3' => $col3,
'customKey' => 'customValue',
];
}
$stmt = $pdo->query("SELECT userid, name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_FUNC, valueCreator(...));
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => Array
(
[col1] => 104
[col2] => SAM
[col3] => Ukraine
[customKey] => customValue
)
[1] => Array
(
[col1] => 105
[col2] => JAMIE
[col3] => England
[customKey] => customValue
)
[2] => Array
(
[col1] => 107
[col2] => ROBIN
[col3] => Germany
[customKey] => customValue
)
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-obj" annotations="chunk:false">
<title>PDO::FETCH_OBJ (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_OBJ</constant> returns a <classname>stdClass</classname>
object.
</simpara>
<simpara>
See also <methodname>PDOStatement::fetchObject</methodname> and
<constant>PDO::FETCH_CLASS</constant>.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_OBJ);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
stdClass Object
(
[userid] => 104
[name] => Chris
[country] => Ukraine
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-class" annotations="chunk:false">
<title>PDO::FETCH_CLASS (<type>int</type>)</title>
<simpara>
Returns an object of a specified class. For additional behaviors see the
<link linkend="pdo.fetch-modes.class-flags">option flags</link>.
</simpara>
<simpara>
If a property does not exist with the name of a returned column, it will be
dynamically declared. This behavior is deprecated and will cause an error
from PHP 9.0.
</simpara>
<simpara>
See also <methodname>PDOStatement::fetchObject</methodname>.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class TestEntity
{
public $userid;
public $name;
public $country;
public $referred_by_userid;
public function __construct()
{
print "Constructor called with ". count(func_get_args()) ." args\n";
print "Properties set when constructor called? "
. (isset($this->name) ? 'Yes' : 'No') . "\n";
}
}
$stmt = $db->query(
"SELECT userid, name, country, referred_by_userid FROM users"
);
$stmt->setFetchMode(PDO::FETCH_CLASS, TestEntity::class);
$result = $stmt->fetch();
var_dump($result);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Constructor called with 0 args
Properties set when constructor called? Yes
object(TestEntity)#3 (4) {
["userid"]=>
int(104)
["name"]=>
string(5) "Chris"
["country"]=>
string(7) "Ukraine"
["referred_by_userid"]=>
NULL
}
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-classtype" annotations="chunk:false">
<title>PDO::FETCH_CLASSTYPE (<type>int</type>)</title>
<simpara>
This fetch mode can only be used combined with
<constant>PDO::FETCH_CLASS</constant> (and
<link linkend="pdo.fetch-modes.class-flags">its other options</link>).
</simpara>
<simpara>
When this fetch mode is used, PDO will use the first returned column as the
name of the class to return.
</simpara>
<simpara>
If the specified class cannot be found, a <classname>stdClass</classname>
object will be returned, without warning or error.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class TestEntity
{
public $userid;
public $name;
public $country;
public $referred_by_userid;
public function __construct()
{
print "Constructor called with ". count(func_get_args()) ." args\n";
print "Properties set when constructor called? "
. (isset($this->name) ? 'Yes' : 'No') . "\n";
}
}
$stmt = $db->query(
"SELECT 'TestEntity', userid, name, country, referred_by_userid FROM users"
);
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
$result = $stmt->fetch();
var_dump($result);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Constructor called with 0 args
Properties set when constructor called? Yes
object(TestEntity)#3 (4) {
["userid"]=>
int(104)
["name"]=>
string(5) "Chris"
["country"]=>
string(7) "Ukraine"
["referred_by_userid"]=>
NULL
}
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-props-late" annotations="chunk:false">
<title>PDO::FETCH_PROPS_LATE (<type>int</type>)</title>
<simpara>
This fetch mode can only be used combined with
<constant>PDO::FETCH_CLASS</constant> (and
<link linkend="pdo.fetch-modes.class-flags">its other options</link>).
</simpara>
<simpara>
When this fetch mode is used, the constructor will be called before the
properties are set.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class TestEntity
{
public $userid;
public $name;
public $country;
public $referred_by_userid;
public function __construct()
{
print "Constructor called with ". count(func_get_args()) ." args\n";
print "Properties set when constructor called? "
. (isset($this->name) ? 'Yes' : 'No') . "\n";
}
}
$stmt = $db->query(
"SELECT userid, name, country, referred_by_userid FROM users"
);
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, TestEntity::class);
$result = $stmt->fetch();
var_dump($result);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Constructor called with 0 args
Properties set when constructor called? No
object(TestEntity)#3 (4) {
["userid"]=>
int(104)
["name"]=>
string(5) "Chris"
["country"]=>
string(7) "Ukraine"
["referred_by_userid"]=>
NULL
}
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-serialize" annotations="chunk:false">
<title>PDO::FETCH_SERIALIZE (<type>int</type>)</title>
&warn.deprecated.feature-8-1-0;
<simpara>
This fetch mode can only be used combined with
<constant>PDO::FETCH_CLASS</constant> (and
<link linkend="pdo.fetch-modes.class-flags">its other options</link>).
</simpara>
<simpara>
When this fetch mode is used, the specified class must be
<interfacename>Serializable</interfacename>.
</simpara>
<caution>
<simpara>
This feature does not support a string that contains a complete serialized
object (with <function>serialize</function>).
</simpara>
</caution>
<caution>
<simpara>
This fetch mode does not call the constructor.
</simpara>
</caution>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class TestEntity implements Serializable
{
public $userid;
public $name;
public $country;
public $referred_by_userid;
public function __construct()
{
print "Constructor called with " . count(func_get_args()) . " args\n";
print "Properties set when constructor called? "
. (isset($this->name) ? 'Yes' : 'No') . "\n";
}
public function serialize()
{
return join(
"|",
[$this->userid, $this->name, $this->country, $this->referred_by_userid]
);
}
public function unserialize(string $data)
{
$parts = explode("|", $data);
$this->userid = (int) $parts[0];
$this->name = $parts[1];
$this->country = $parts[2];
$refId = $parts[3];
$this->referred_by_userid = ($refId === "" ? null : (int) $refId);
}
}
print "Set up record (constructor called manually):\n";
$db->exec(
"CREATE TABLE serialize (
sdata TEXT
)"
);
$origObj = new TestEntity();
$origObj->userid = 200;
$origObj->name = 'Seri';
$origObj->country = 'Syria';
$origObj->referred_by_userid = null;
$insert = $db->prepare("INSERT INTO serialize (sdata) VALUES (:sdata)");
$insert->execute(['sdata' => $origObj->serialize()]);
print "\nRetrieve result:\n";
$query = "SELECT sdata FROM serialize";
$stmt = $db->query($query);
// NOTE: Constructor is never called!
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_SERIALIZE, TestEntity::class);
$result = $stmt->fetch();
var_dump($result);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Deprecated: TestEntity implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in Standard input code on line 2
Set up record (constructor called manually):
Constructor called with 0 args
Properties set when constructor called? No
Retrieve result:
Deprecated: PDOStatement::setFetchMode(): The PDO::FETCH_SERIALIZE mode is deprecated in Standard input code on line 58
Deprecated: PDOStatement::fetch(): The PDO::FETCH_SERIALIZE mode is deprecated in Standard input code on line 59
object(TestEntity)#5 (4) {
["userid"]=>
int(200)
["name"]=>
string(4) "Seri"
["country"]=>
string(5) "Syria"
["referred_by_userid"]=>
NULL
}
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-bound" annotations="chunk:false">
<title>PDO::FETCH_BOUND (<type>int</type>)</title>
<simpara>
This fetch mode cannot be used with
<methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<simpara>
This fetch mode does not directly return a result, but binds values to
variables specified with <methodname>PDOStatement::bindColumn</methodname>. The
called fetch method returns &true;.
</simpara>
<note>
<simpara>
When using prepared statements, to work correctly, variables must be bound
after the query is executed.
</simpara>
</note>
<programlisting role="php">
<![CDATA[
<?php
$query = "SELECT users.userid, users.name, users.country, referrer.name
FROM users
LEFT JOIN users AS referrer ON users.referred_by_userid = referrer.userid";
$stmt = $db->prepare($query);
$stmt->execute();
$stmt->bindColumn('userid', $userId);
$stmt->bindColumn('name', $name);
$stmt->bindColumn('country', $country);
// Bind by column position to resolve duplicated column name
// To avoid this breaking if the query is changed, use an SQL alias instead
// For example: referrer.name AS referrer_name
$stmt->bindColumn(4, $referrerName);
while ($stmt->fetch(\PDO::FETCH_BOUND)) {
print join("\t", [$userId, $name, $country, ($referrerName ?? 'NULL')]) . "\n";
}
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
104 Chris Ukraine NULL
105 Jamie England NULL
107 Robin Germany Chris
108 Sean Ukraine NULL
109 Toni Germany NULL
110 Toni Germany NULL
]]>
</screen>
</section>
<section xml:id="pdo.constants.fetch-into" annotations="chunk:false">
<title>PDO::FETCH_INTO (<type>int</type>)</title>
<simpara>
This fetch mode cannot be used with
<methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<simpara>
This fetch mode updates properties in the specified object. The object is
returned on success.
</simpara>
<simpara>
If a property does not exist with the name of a returned column, it will be
dynamically declared. This behavior is deprecated and will cause an error
from PHP 9.0.
</simpara>
<simpara>
Properties must be <literal>public</literal> and cannot be
<literal>readonly</literal>.
</simpara>
<caution>
<simpara>
There's no way to change the object to be updated without using
<methodname>PDOStatement::setFetchMode</methodname> between retrieving each
record.
</simpara>
</caution>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class TestEntity
{
public $userid;
public $name;
public $country;
public $referred_by_userid;
}
$obj = new TestEntity();
$stmt->setFetchMode(\PDO::FETCH_INTO, $obj);
$stmt = $db->query("SELECT userid, name, country, referred_by_userid FROM users");
$result = $stmt->fetch();
var_dump($result);
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
object(TestEntity)#3 (4) {
["userid"]=>
int(104)
["name"]=>
string(5) "Chris"
["country"]=>
string(7) "Ukraine"
["referred_by_userid"]=>
NULL
}
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-lazy" annotations="chunk:false">
<title>PDO::FETCH_LAZY (<type>int</type>)</title>
<simpara>
This fetch mode cannot be used with
<methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<simpara>
This fetch mode returns a <classname>PDORow</classname> object which provides
both array- and object-like access to values (i.e. combines the behavior of
<constant>PDO::FETCH_BOTH</constant> and
<constant>PDO::FETCH_OBJ</constant>), retrieved in a lazy manner.
</simpara>
<simpara>
This can provide memory efficient access (on the PHP side) to unbuffered
results on the database server. Whether PDO uses client-side buffering for
results depends on the database-specific driver used (and its configuration).
</simpara>
<caution>
<simpara>
<classname>PDORow</classname> will return <literal>NULL</literal> without
any error or warning when accessing properties or keys that are not defined.
This can make errors such as typos or queries not returning expected data
harder to spot and debug.
</simpara>
</caution>
<caution>
<simpara>
The returned <classname>PDORow</classname> object is updated each time a
result is retrieved.
</simpara>
</caution>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $db->query("SELECT userid, name, country, referred_by_userid FROM users");
$result = $stmt->fetch(\PDO::FETCH_LAZY);
print "ID: ". $result[0] ."\n";
print "Name: {$result->name}\n";
print "Country: " . $result['country'] ."\n";
// Returns NULL. No warning or error is raised.
print "Does not exist: " . var_export($result->does_not_exist, true) . "\n";
$differentResult = $stmt->fetch(\PDO::FETCH_LAZY);
// The previously retrieved PDORow now points to the newly retrieved result
print "ID: ". $result[0] ."\n";
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
ID: 104
Name: Chris
Country: Ukraine
Does not exist: NULL
ID: 105
]]>
</screen>
</section>
<section xml:id="pdo.constants.fetch-group" annotations="chunk:false">
<title>PDO::FETCH_GROUP (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_GROUP</constant> returns lists of associative arrays,
indexed by a (non-unique) column. This fetch mode only works with
<methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<simpara>
When combined with <constant>PDO::FETCH_UNIQUE</constant>, both modes will
use the same column, rendering the combination of these modes useless.
</simpara>
<simpara>
This fetch should be combined with one of
<constant>PDO::FETCH_ASSOC</constant>, <constant>PDO::FETCH_BOTH</constant>,
<constant>PDO::FETCH_NAMED</constant>, <constant>PDO::FETCH_NUM</constant>,
<constant>PDO::FETCH_COLUMN</constant> or
<constant>PDO::FETCH_FUNC</constant>.
</simpara>
<simpara>
If no fetch mode from the above list is given, the current default fetch mode
for the <classname>PDOStatement</classname> will be used.
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT country, userid, name FROM users");
$row = $stmt->fetchAll(\PDO::FETCH_GROUP | \PDO::FETCH_ASSOC);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[Ukraine] => Array
(
[0] => Array
(
[userid] => 104
[name] => Chris
)
[1] => Array
(
[userid] => 108
[name] => Sean
)
)
[England] => Array
(
[0] => Array
(
[userid] => 105
[name] => Jamie
)
)
[Germany] => Array
(
[0] => Array
(
[userid] => 107
[name] => Robin
)
[1] => Array
(
[userid] => 109
[name] => Toni
)
)
)
]]>
</screen>
</informalexample>
<simpara>
In the above example one should note that the first column is omitted from the
array for each row, only available as the key. It can be included by
repeating the column, as in the following example:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT country, userid, name, country FROM users");
$row = $stmt->fetchAll(\PDO::FETCH_GROUP | \PDO::FETCH_ASSOC);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[Ukraine] => Array
(
[0] => Array
(
[userid] => 104
[name] => Chris
[country] => Ukraine
)
[1] => Array
(
[userid] => 108
[name] => Sean
[country] => Ukraine
)
)
[England] => Array
(
[0] => Array
(
[userid] => 105
[name] => Jamie
[country] => England
)
)
[Germany] => Array
(
[0] => Array
(
[userid] => 107
[name] => Robin
[country] => Germany
)
[1] => Array
(
[userid] => 109
[name] => Toni
[country] => Germany
)
)
)
]]>
</screen>
</informalexample>
</section>
<section xml:id="pdo.constants.fetch-unique" annotations="chunk:false">
<title>PDO::FETCH_UNIQUE (<type>int</type>)</title>
<simpara>
<constant>PDO::FETCH_UNIQUE</constant> uses the first column to index records,
returning 1 record per index value. This fetch mode only works with
<methodname>PDOStatement::fetchAll</methodname>.
</simpara>
<simpara>
When combined with <constant>PDO::FETCH_GROUP</constant>, both modes will use
the same column, rendering the combination of these modes useless.
</simpara>
<simpara>
This fetch should be combined with one of
<constant>PDO::FETCH_ASSOC</constant>, <constant>PDO::FETCH_BOTH</constant>,
<constant>PDO::FETCH_NAMED</constant>, <constant>PDO::FETCH_NUM</constant>,
<constant>PDO::FETCH_COLUMN</constant> or
<constant>PDO::FETCH_FUNC</constant>.
</simpara>
<simpara>
If no fetch mode from the above list is given, the current default fetch mode
for the <classname>PDOStatement</classname> will be used.
</simpara>
<simpara>
When used with a column that is known to be unique (such as record ID), this
mode provides the ability to quickly return results indexed by that value.
</simpara>
<note>
<simpara>
If the first column is not unique, values will be lost. Which value(s) are
lost should be considered undefined.
</simpara>
</note>
<caution>
<simpara>
Filtering records should be done in SQL where possible. The database will
use indexes to optimize this process and return only the required records.
Selecting more records than required from the database may significantly
increase memory usage and query time for larger result sets.
</simpara>
</caution>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT userid, name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_UNIQUE | \PDO::FETCH_ASSOC);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[104] => Array
(
[name] => Chris
[country] => Ukraine
)
[105] => Array
(
[name] => Jamie
[country] => England
)
[107] => Array
(
[name] => Robin
[country] => Germany
)
)
]]>
</screen>
</informalexample>
<simpara>
In the above example one should note that the first column is omitted from the
array for each row, only available as the key. It can be included by
repeating the column, as in the following example:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$stmt = $pdo->query("SELECT userid, userid, name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_UNIQUE | \PDO::FETCH_ASSOC);
print_r($row);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[104] => Array
(
[userid] => 104
[name] => Chris
[country] => Ukraine
)
[105] => Array
(
[userid] => 105
[name] => Jamie
[country] => England
)
[107] => Array
(
[userid] => 107
[name] => Robin
[country] => Germany
)
)
]]>
</screen>
</informalexample>
</section>
</section>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->