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;
/* Methods */
public __construct(
    string $dsn,
    ?string $username = null,
    #[\SensitiveParameter] ?string $password = null,
    ?array $options = null
)
public commit(): bool
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,
    array $constructorArgs
): PDOStatement|false
public query(string $query, ?int $fetchMode = PDO::FETCH_INTO, object $object): PDOStatement|false
public quote(string $string, int $type = PDO::PARAM_STR): string|false
public rollBack(): bool
public setAttribute(int $attribute, mixed $value): bool
}

目录

添加笔记

用户贡献的笔记 8 个笔记

69
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('Unable to open ' . $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 文件访问。
15
anrdaemon at freemail dot ru
15 年前
请记住,您绝对不能在应用程序中使用“root”用户,除非您的应用程序设计用于执行数据库维护。

将用户名/密码存储在类中对于生产代码来说不是一个好主意。您需要编辑实际的工作代码来更改设置,这是不好的。
13
williambarry007 at gmail dot com
12 年前
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);

?>
7
thz at plista dot com
11 年前
从 PHP 5.4 开始,当您有自己的从本机 PDO 类派生的数据库类时,您将无法使用持久连接。如果您的代码使用此组合,您会在 PHP 进程清理期间遇到分段错误。
您仍然可以使用 _either_ 派生的 PDO 类 _or_ 持久连接。

有关更多信息,请参阅此错误报告:https://bugs.php.net/bug.php?id=63176
3
sinri at everstray dot com
6 年前
对于某些数据库环境,例如阿里云 DRDS(分布式关系型数据库服务),无法处理 SQL 的准备。
对于这种情况,应将选项 `\PDO::ATTR_EMULATE_PREPARES` 设置为 true。如果您始终收到有关“无法准备 SQL”的报告,而此选项设置为 false,则可以尝试打开此选项以模拟 SQL 的准备。
3
Anonymous
6 年前
我个人像这样创建一个新的 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' );
-14
kcleung at kcleung dot no-ip dot org
14 年前
这是一个单例 PDO 示例

###### config.ini ######
db_driver=mysql
db_user=root
db_password=924892xp

[dsn]
host=localhost
port=3306
dbname=localhost

[db_options]
PDO::MYSQL_ATTR_INIT_COMMAND=set names utf8

[db_attributes]
ATTR_ERRMODE=ERRMODE_EXCEPTION
############

<?php class Database {
private static
$link = null ;

private static function
getLink ( ) {
if (
self :: $link ) {
return
self :: $link ;
}

$ini = _BASE_DIR . "config.ini" ;
$parse = parse_ini_file ( $ini , true ) ;

$driver = $parse [ "db_driver" ] ;
$dsn = "${driver}:" ;
$user = $parse [ "db_user" ] ;
$password = $parse [ "db_password" ] ;
$options = $parse [ "db_options" ] ;
$attributes = $parse [ "db_attributes" ] ;

foreach (
$parse [ "dsn" ] as $k => $v ) {
$dsn .= "${k}=${v};" ;
}

self :: $link = new PDO ( $dsn, $user, $password, $options ) ;

foreach (
$attributes as $k => $v ) {
self :: $link -> setAttribute ( constant ( "PDO::{$k}" )
,
constant ( "PDO::{$v}" ) ) ;
}

return
self :: $link ;
}

public static function
__callStatic ( $name, $args ) {
$callback = array ( self :: getLink ( ), $name ) ;
return
call_user_func_array ( $callback , $args ) ;
}
}
?>

<?php // examples
$stmt = Database :: prepare ( "SELECT 'something' ;" ) ;
$stmt -> execute ( ) ;
var_dump ( $stmt -> fetchAll ( ) ) ;
$stmt -> closeCursor ( ) ;
?>
-38
Ale L
5 年前
1) 不要将数据库信息放在同一个文件中

以及

2) 千万不要使用具有“所有权限”的用户来访问所有内容,始终创建一个具有受限权限的替代用户(基本权限:SELECT、INSERT 等)
To Top