betterCode() PHP 2025

获取模式

参见 PDO::FETCH_ORI_* 游标常量的游标常量

基本获取模式

获取模式 摘要
PDO::FETCH_DEFAULT 用于当前默认获取模式的特殊值。
PDO::FETCH_ASSOC 仅按列名索引的数组。
PDO::FETCH_BOTH(默认) 同时按列号和列名索引的数组。
PDO::FETCH_NAMED 保留重复列的 PDO::FETCH_ASSOC 变体。
PDO::FETCH_NUM 仅按列号索引的数组。
PDO::FETCH_COLUMN 单列。
PDO::FETCH_KEY_PAIR 键值对,按第一列索引。
PDO::FETCH_FUNC 使用函数创建返回值。(仅适用于 PDOStatement::fetchAll()
PDO::FETCH_OBJ 匿名(stdClass)对象。
PDO::FETCH_CLASS 指定类的对象。

PDO::FETCH_CLASS 选项

这些模式用于在使用 PDO::FETCH_CLASS 时实现选项。

获取模式 摘要
PDO::FETCH_CLASSTYPE 使用第一列作为类名。
PDO::FETCH_PROPS_LATE 在设置属性之前调用构造方法。
PDO::FETCH_SERIALIZE 使用 PHP 序列化数据。自 PHP 8.1.0 起弃用。

单结果模式

以下模式无法与 PDOStatement::fetchAll() 一起使用。

获取模式 摘要
PDO::FETCH_BOUND 将值绑定到指定变量。
PDO::FETCH_INTO 更新现有对象。
PDO::FETCH_LAZY 通过 PDORow 实现延迟获取,以支持类似数组和对象的访问方式。

PDOStatement::fetchAll() 的特殊行为 flag

以下适用于多结果的特殊模式仅与 PDOStatement::fetchAll() 兼容,且不适用于某些其他获取模式。详情请参阅完整文档。

获取模式 摘要
PDO::FETCH_GROUP 结果按第一列分组。
PDO::FETCH_UNIQUE 结果按第一列(唯一)索引。

重复列名的处理方式

结果中可能包含使用相同名称的多个列。例如,在连接两个表时,这两个表都包含具有相同名称的列。

由于 PHP 的数组和对象等结构不支持使用相同名称的多个 key 或属性,返回的数组或对象将仅包含其中一个使用相同名称的值。

对于重复名称,指定返回哪个值应视为未定义行为。

为避免此问题,可以使用别名手动命名列。例如:

SELECT table1.created_at AS t1_created_at,
       table2.created_at AS t2_created_at
FROM table1
JOIN table2 ON table1.table2id = table2.id

参见 PDO::FETCH_NAMEDPDO::ATTR_FETCH_TABLE_NAMESPDO::ATTR_FETCH_CATALOG_NAMES

设置默认获取模式

You can set the default fetch mode for all queries using PDO::ATTR_DEFAULT_FETCH_MODE with PDO::__construct() or PDO::setAttribute().

You can set the default fetch mode for a specific statement using PDOStatement::setFetchMode(). This affects reuse as a prepared statement and iteration (using foreach).

警告

PDOStatement::setAttribute() cannot be used to set the default fetch mode. It only accepts driver specific attributes and silently ignores attributes that are not recognized.

PDO::FETCH_DEFAULT (int)

Available since PHP 8.0.7.

This is a special value that uses the current default fetch mode for a PDOStatement. It's specifically useful as the default value for method parameters when extending PDOStatement for use with PDO::ATTR_STATEMENT_CLASS.

This value cannot be used with PDO::ATTR_DEFAULT_FETCH_MODE.

PDO::FETCH_ASSOC (int)

PDO::FETCH_ASSOC returns an array indexed by column name only.

<?php
$stmt
= $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
print_r($row);

以上示例会输出:

Array
(
    [userid] => 104
    [name] => Chris
    [country] => Ukraine
)

PDO::FETCH_BOTH (int)

This is the default fetch mode.

PDO::FETCH_BOTH returns an array indexed by both column number and name. This means that every returned value is duplicated for each result row.

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.

注意:

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 SELECT *.

注意:

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.

<?php
$stmt
= $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_BOTH);
print_r($row);

以上示例会输出:

Array
(
    [id] => 104,
    [0] => 104,
    [name] => Chris,
    [1] => Chris,
    [country] => Ukraine,
    [2] => Ukraine
)

PDO::FETCH_NAMED (int)

PDO::FETCH_NAMED returns results in the same format as PDO::FETCH_ASSOC except that where multiple columns use the same name, all values are returned as a list.

For more information on handling of duplicated column names and alternatives, see the handling of duplicated names section above.

The order in which duplicated values are returned should be considered undefined. There's no way to tell where each value came from.

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

以上示例会输出:

Array
(
    [userid] => 109
    [name] => Array
        (
            [0] => Toni
            [1] => Chris
        )
    [country] => Germany
    [referred_by] = 104
)

PDO::FETCH_NUM (int)

PDO::FETCH_NUM 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.

注意:

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 SELECT *.

<?php
$stmt
= $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_NUM);
print_r($row);

以上示例会输出:

Array
(
    [0] => 104
    [1] => Chris
    [2] => Ukraine
)

PDO::FETCH_COLUMN (int)

PDO::FETCH_COLUMN returns values from a single column. Use the second argument for PDOStatement::setFetchMode() or PDOStatement::fetchAll() to specify which column is returned.

If the specified column does not exist a ValueError will be thrown.

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

以上示例会输出:

Array
(
    [0] => Chris
    [1] => Jamie
    [2] => Robin
)

Array
(
    [0] => Ukraine
    [1] => England
    [2] => Germany
)

PDO::FETCH_KEY_PAIR (int)

PDO::FETCH_KEY_PAIR returns pairs of values, indexed by the first column. The results must contain only 2 columns. This fetch mode only makes sense with PDOStatement::fetchAll().

注意:

If the first column is not unique, values will be lost. Which value(s) are lost should be considered undefined.

<?php
$stmt
= $pdo->query("SELECT name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
print_r($row);

以上示例会输出:

Array
(
    [Chris] => Ukraine
    [Jamie] => England
    [Robin] => Germany
)

PDO::FETCH_FUNC (int)

Specify a function to create the returned value. This mode can only be used with PDOStatement::fetchAll().

The function receives the values as parameters. There's no way to retrieve the column name a given value was associated with. You must make sure the column order in the query matches that expected by the function.

注意:

The effects of PDO::FETCH_GROUP and PDO::FETCH_UNIQUE are applied to results before the function is called.

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

以上示例会输出:

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
        )

)

PDO::FETCH_OBJ (int)

PDO::FETCH_OBJ returns a stdClass object.

See also PDOStatement::fetchObject() and PDO::FETCH_CLASS.

<?php
$stmt
= $pdo->query("SELECT userid, name, country FROM users");
$row = $stmt->fetch(\PDO::FETCH_OBJ);
print_r($row);

以上示例会输出:

stdClass Object
(
    [userid] => 104
    [name] => Chris
    [country] => Ukraine
)

PDO::FETCH_CLASS (int)

Returns an object of a specified class. For additional behaviors see the option flags.

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.

See also PDOStatement::fetchObject().

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

以上示例的输出类似于:

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
}

PDO::FETCH_CLASSTYPE (int)

This fetch mode can only be used combined with PDO::FETCH_CLASS (and its other options).

When this fetch mode is used, PDO will use the first returned column as the name of the class to return.

If the specified class cannot be found, a stdClass object will be returned, without warning or error.

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

以上示例的输出类似于:

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
}

PDO::FETCH_PROPS_LATE (int)

This fetch mode can only be used combined with PDO::FETCH_CLASS (and its other options).

When this fetch mode is used, the constructor will be called before the properties are set.

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

以上示例的输出类似于:

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
}

PDO::FETCH_SERIALIZE (int)

警告

This feature has been DEPRECATED as of PHP 8.1.0. Relying on this feature is highly discouraged.

This fetch mode can only be used combined with PDO::FETCH_CLASS (and its other options).

When this fetch mode is used, the specified class must be Serializable.

警告

This feature does not support a string that contains a complete serialized object (with serialize()).

警告

This fetch mode does not call the constructor.

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

以上示例的输出类似于:

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
}

PDO::FETCH_BOUND (int)

This fetch mode cannot be used with PDOStatement::fetchAll().

This fetch mode does not directly return a result, but binds values to variables specified with PDOStatement::bindColumn(). The called fetch method returns true.

注意:

When using prepared statements, to work correctly, variables must be bound after the query is executed.

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

print
"\nfetch:\n";
while (
$stmt->fetch(\PDO::FETCH_BOUND)) {
print
join("\t", [$userId, $name, $country, ($referrerName ?? 'NULL')]) . "\n";
}

以上示例会输出:

104	Chris	Ukraine	NULL
105	Jamie	England	NULL
107	Robin	Germany	Chris
108	Sean	Ukraine	NULL
109	Toni	Germany	NULL
110	Toni	Germany	NULL

PDO::FETCH_INTO (int)

This fetch mode cannot be used with PDOStatement::fetchAll().

This fetch mode updates properties in the specified object. The object is returned on success.

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.

Properties must be public and cannot be readonly.

警告

There's no way to change the object to be updated without using PDOStatement::setFetchMode() between retrieving each record.

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

以上示例的输出类似于:

object(TestEntity)#3 (4) {
  ["userid"]=>
  int(104)
  ["name"]=>
  string(5) "Chris"
  ["country"]=>
  string(7) "Ukraine"
  ["referred_by_userid"]=>
  NULL
}

PDO::FETCH_LAZY (int)

This fetch mode cannot be used with PDOStatement::fetchAll().

This fetch mode returns a PDORow object which provides both array- and object-like access to values (i.e. combines the behavior of PDO::FETCH_BOTH and PDO::FETCH_OBJ), retrieved in a lazy manner.

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).

警告

PDORow will return NULL 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.

警告

The returned PDORow object is updated each time a result is retrieved.

<?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";

以上示例会输出:

ID: 104
Name: Chris
Country: Ukraine
Does not exist: NULL
ID: 105

PDO::FETCH_GROUP (int)

PDO::FETCH_GROUP returns lists of associative arrays, indexed by a (non-unique) column. This fetch mode only works with PDOStatement::fetchAll().

When combined with PDO::FETCH_UNIQUE, both modes will use the same column, rendering the combination of these modes useless.

This fetch should be combined with one of PDO::FETCH_ASSOC, PDO::FETCH_BOTH, PDO::FETCH_NAMED, PDO::FETCH_NUM, PDO::FETCH_COLUMN or PDO::FETCH_FUNC.

If no fetch mode from the above list is given, the current default fetch mode for the PDOStatement will be used.

<?php
$stmt
= $pdo->query("SELECT country, userid, name FROM users");
$row = $stmt->fetchAll(\PDO::FETCH_GROUP | \PDO::FETCH_ASSOC);
print_r($row);

以上示例会输出:

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
                )
        )
)

In the above example you'll 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:

<?php
$stmt
= $pdo->query("SELECT country, userid, name, country FROM users");
$row = $stmt->fetchAll(\PDO::FETCH_GROUP | \PDO::FETCH_ASSOC);
print_r($row);

以上示例会输出:

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
                )
        )
)

PDO::FETCH_UNIQUE (int)

PDO::FETCH_UNIQUE uses the first column to index records, returning 1 record per index value. This fetch mode only works with PDOStatement::fetchAll().

When combined with PDO::FETCH_GROUP, both modes will use the same column, rendering the combination of these modes useless.

This fetch should be combined with one of PDO::FETCH_ASSOC, PDO::FETCH_BOTH, PDO::FETCH_NAMED, PDO::FETCH_NUM, PDO::FETCH_COLUMN or PDO::FETCH_FUNC.

If no fetch mode from the above list is given, the current default fetch mode for the PDOStatement will be used.

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.

注意:

If the first column is not unique, values will be lost. Which value(s) are lost should be considered undefined.

警告

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.

<?php
$stmt
= $pdo->query("SELECT userid, name, country FROM users LIMIT 3");
$row = $stmt->fetchAll(\PDO::FETCH_UNIQUE | \PDO::FETCH_ASSOC);
print_r($row);

以上示例会输出:

Array
(
    [104] => Array
        (
            [name] => Chris
            [country] => Ukraine
        )

    [105] => Array
        (
            [name] => Jamie
            [country] => England
        )

    [107] => Array
        (
            [name] => Robin
            [country] => Germany
        )

)

In the above example you'll 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:

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

以上示例会输出:

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
        )

)
添加备注

用户贡献的备注

此页面尚无用户贡献的备注。
To Top