PHP Conference Japan 2024

PDO 类

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

简介

表示 PHP 和数据库服务器之间的连接。

类概要

class PDO {
/* 常量 */
public const int PARAM_NULL;
public const int PARAM_BOOL = 5;
public const int PARAM_INT = 1;
public const int PARAM_STR = 2;
public const int PARAM_LOB = 3;
public const int PARAM_STMT = 4;
public const int PARAM_INPUT_OUTPUT;
public const int PARAM_STR_NATL;
public const int PARAM_STR_CHAR;
public const int PARAM_EVT_ALLOC;
public const int PARAM_EVT_FREE;
public const int PARAM_EVT_EXEC_PRE;
public const int PARAM_EVT_EXEC_POST;
public const int PARAM_EVT_FETCH_PRE;
public const int PARAM_EVT_NORMALIZE;
public const int FETCH_DEFAULT;
public const int FETCH_LAZY;
public const int FETCH_ASSOC;
public const int FETCH_NUM;
public const int FETCH_BOTH;
public const int FETCH_OBJ;
public const int FETCH_BOUND;
public const int FETCH_COLUMN;
public const int FETCH_CLASS;
public const int FETCH_INTO;
public const int FETCH_FUNC;
public const int FETCH_GROUP;
public const int FETCH_UNIQUE;
public const int FETCH_KEY_PAIR;
public const int FETCH_CLASSTYPE;
public const int FETCH_SERIALIZE;
public const int FETCH_PROPS_LATE;
public const int FETCH_NAMED;
public const int ATTR_AUTOCOMMIT;
public const int ATTR_PREFETCH;
public const int ATTR_TIMEOUT;
public const int ATTR_ERRMODE;
public const int ATTR_SERVER_VERSION;
public const int ATTR_CLIENT_VERSION;
public const int ATTR_SERVER_INFO;
public const int ATTR_CASE;
public const int ATTR_CURSOR_NAME;
public const int ATTR_CURSOR;
public const int ATTR_ORACLE_NULLS;
public const int ATTR_PERSISTENT;
public const int ATTR_DRIVER_NAME;
public const int ATTR_MAX_COLUMN_LEN;
public const int ERRMODE_SILENT;
public const int ERRMODE_WARNING;
public const int ERRMODE_EXCEPTION;
public const int CASE_NATURAL;
public const int CASE_LOWER;
public const int CASE_UPPER;
public const int NULL_NATURAL;
public const int NULL_EMPTY_STRING;
public const int NULL_TO_STRING;
public const string ERR_NONE;
public const int FETCH_ORI_NEXT;
public const int FETCH_ORI_PRIOR;
public const int FETCH_ORI_FIRST;
public const int FETCH_ORI_LAST;
public const int FETCH_ORI_ABS;
public const int FETCH_ORI_REL;
public const int CURSOR_FWDONLY;
public const int CURSOR_SCROLL;
/* 方法 */
public __construct(
    string $dsn,
    ?string $username = null,
    #[\SensitiveParameter] ?string $password = null,
    ?array $options = null
)
public commit(): bool
public static connect(
    string $dsn,
    ?string $username = null,
    #[\SensitiveParameter] ?string $password = null,
    ?array $options = null
): static
public errorCode(): ?string
public errorInfo(): array
public exec(string $statement): int|false
public getAttribute(int $attribute): mixed
public static getAvailableDrivers(): array
public prepare(string $query, array $options = []): PDOStatement|false
public query(string $query, ?int $fetchMode = null): PDOStatement|false
public query(string $query, ?int $fetchMode = PDO::FETCH_COLUMN, int $colno): PDOStatement|false
public query(
    string $query,
    ?int $fetchMode = PDO::FETCH_CLASS,
    string $classname

,
    数组 $constructorArgs
): PDOStatement|false
public query(字符串 $query, ?整数 $fetchMode = PDO::FETCH_INTO, 对象 $object): PDOStatement|false
public quote(字符串 $string, 整数 $type = PDO::PARAM_STR): 字符串|false
public setAttribute(整数 $attribute, 混合类型 $value): 布尔值
}

变更日志

版本 描述
8.4.0 类常量现在已添加类型。

目录

添加注释

用户贡献的注释 6 个注释

74
Megaloman
15 年前
"将用户名/密码存储在类中对于生产代码来说不是一个好主意。"

好主意是将数据库连接设置存储在 *.ini 文件中,但您必须限制对它们的访问。例如,这种方式

my_setting.ini
[database]
driver = mysql
host = localhost
;port = 3306
schema = db_schema
username = user
password = secret

数据库连接
<?php
class MyPDO extends PDO
{
public function
__construct($file = 'my_setting.ini')
{
if (!
$settings = parse_ini_file($file, TRUE)) throw new exception('无法打开 ' . $file . '.');

$dns = $settings['database']['driver'] .
':host=' . $settings['database']['host'] .
((!empty(
$settings['database']['port'])) ? (';port=' . $settings['database']['port']) : '') .
';dbname=' . $settings['database']['schema'];

parent::__construct($dns, $settings['database']['username'], $settings['database']['password']);
}
}
?>

对于那些即使看到一个 PHP/HTML/任何其他命令也会尖叫的人,数据库连接参数可以通过人类可读的 ini 文件访问。
14
anrdaemon at freemail dot ru
16 年前
请记住,您绝对不能在应用程序中使用“root”用户,除非您的应用程序旨在执行数据库维护。

将用户名/密码存储在类中对于生产代码来说不是一个好主意。您需要编辑实际的工作代码来更改设置,这是不好的。
12
williambarry007 at gmail dot com
13 年前
PDO 和依赖注入

依赖注入有利于测试。但是,对于任何希望各种数据映射器对象具有数据库连接的人来说,依赖注入可能会使其他模型代码变得非常混乱,因为数据库对象必须在各处实例化并提供给数据映射器对象。

以下代码是在保持依赖注入的同时保持模型代码简洁和最少的一种好方法。

<?php

class DataMapper
{
public static
$db;

public static function
init($db)
{
self::$db = $db;
}
}

class
VendorMapper extends DataMapper
{
public static function
add($vendor)
{
$st = self::$db->prepare(
"insert into vendors set
first_name = :first_name,
last_name = :last_name"
);
$st->execute(array(
':first_name' => $vendor->first_name,
':last_name' => $vendor->last_name
));
}
}

// 在您的引导程序中
$db = new PDO(...);
DataMapper::init($db);

// 在您的模型逻辑中
$vendor = new Vendor('John', 'Doe');
VendorMapper::add($vendor);

?>
3
sinri at everstray dot com
6 年前
对于某些数据库环境,例如阿里云 DRDS(分布式关系数据库服务),无法处理 SQL 的准备工作。
对于此类情况,应将选项 `\PDO::ATTR_EMULATE_PREPARES` 设置为 true。如果您始终收到有关“无法准备 SQL”的报告,而此选项设置为 false,则可以尝试打开此选项以模拟 SQL 的准备工作。
5
thz at plista dot com
11 年前
从 PHP 5.4 开始,当您有自己的从原生 PDO 类派生的数据库类时,您将无法使用持久连接。如果您的代码使用此组合,则在 PHP 进程清理期间会遇到分段错误。
您仍然可以使用_任一_派生的 PDO 类_或_持久连接。

有关更多信息,请参阅此错误报告: https://bugs.php.net/bug.php?id=63176
2
匿名用户
7 年前
我个人创建 PDO 的新实例如下

$dbDatas = parse_ini_file( DB_FILE );
$dbOptions = [
\PDO::ATTR_DEFAULT_FECTH_MODE => \PDO::FETCH_OBJ,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
];

$dsn = sprintf( 'mysql:dbname=%s;host=%s', $dbDatas['dbname'],
$dbDatas['host'] );

$this->cn = new \PDO( $dsn, $dbDatas['user'], $dbDatas['password'],
$dbOptions );
$this->cn->exec( 'SET CHARACTER SET UTF8' );
To Top