PHP的数据对象(PDO)扩展操作数据库
PDO提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据
在Unix上或Linux上需要添加扩展:extension=pdo.so
在Windows上要添加扩展:extension=php_pdo.dll
在php5.6之后的版本(不一定准确)中php已经内置了pdo功能,不去要再去添加pdo扩展,只需要在php.ini文件中将对应的数据库扩展引入,如需要使用mysql则去掉;extension=php_pdo_mysql.dll前的分号,需要sqlite则去掉;extension=php_pdo_sqlite.dll前的分号等
使用构造方法创建一个表示数据库连接的PDO实例对象
PDO::__construct(string $dsn[,string $username[,string $password[,array $driver_options]]])
$dsn的格式:数据库驱动名称后面带个冒号,后面是基本属性,以key=value键值对表示,各属性之间使用分号分隔,如
$dsn='mysql:dbname=demo;host=localhost;port=3306';
$dsn='sqlite:D:/wwwroot/dd.db';
$db = new PDO($dsn,$username, $password);
如果有任何连接错误,将抛出一个PDOException异常对象
连接数据成功后,返回一个PDO类的对象实例,此连接在PDO对象的生存周期中保持活动,PHP在脚本结束时会自动关闭连接
数据库的设置可以通过构造函数的$driver_options参数以数组的方式传入,也可以使用$db->setAttribute(int $attribute,mixed $value)设置已经创建的数据库句柄属性,以下是常见的通用属性:
PDO::ATTR_CASE:强制列名为指定的大小写。
PDO::CASE_LOWER:强制列名小写。
PDO::CASE_NATURAL:保留数据库驱动返回的列名。
PDO::CASE_UPPER:强制列名大写。
PDO::ATTR_ERRMODE:错误报告。
PDO::ERRMODE_SILENT:静默模式(Silent):错误发生后,不会主动报错,是默认的模式;
PDO::ERRMODE_WARNING: 警告模式(Warning):错误发生后,通过PHP标准来报告错误;
PDO::ERRMODE_EXCEPTION: 错误发生后,抛出异常,需要捕捉和处理;
PDO::ATTR_ORACLE_NULLS: 转换NULL和空字符串。
PDO::NULL_NATURAL: 不转换。
PDO::NULL_EMPTY_STRING: 将空字符串转换成 NULL。
PDO::NULL_TO_STRING: 将 NULL 转换成空字符串。
PDO::ATTR_STRINGIFY_FETCHES: 提取的时候将数值转换为字符串(bool值)
PDO::ATTR_TIMEOUT:指定超时的秒数。并非所有驱动都支持此选项(int值)
PDO::ATTR_AUTOCOMMIT(在OCI,Firebird以及MySQL中可用):是否自动提交每个单独的语句。
PDO::ATTR_EMULATE_PREPARES 启用或禁用预处理语句的模拟
有些驱动不支持或有限度地支持本地预处理
使用此设置强制PDO总是模拟预处理语句(如果为TRUE),或试着使用本地预处理语句(如果为FALSE)。
如果驱动不能成功预处理当前查询,它将总是回到模拟预处理语句上。 需要 bool 类型。
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY(在MySQL中可用):使用缓冲查询
PDO::ATTR_DEFAULT_FETCH_MODE:设置默认的提取模式。
PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组
PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组
PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象
PDO::FETCH_BOTH(默认):返回一个索引为结果集列名和以0开始的列号的数组
PDO::FETCH_BOUND:返回 TRUE ,并分配结果集中的列值给 PDOStatement::bindColumn() 方法绑定的 PHP 变量。
数据类型常量:
PDO::PARAM_BOOL表示布尔数据类型
PDO::PARAM_NULL表示SQL中NULL数据类型。
PDO::PARAM_INT表示SQL中的整型
PDO::PARAM_STR表示SQL中的CHAR、VARCHAR或其他字符串类型。
PDO::PARAM_STR_NATL标记了字符使用的是国家字符集。 自 PHP 7.2.0 起。
PDO::PARAM_STR_CHAR标记了字符使用的是常规字符集(regular character set)。 自 PHP 7.2.0 起。
PDO::PARAM_LOB表示 SQL 中大对象数据类型
PDO::PARAM_STMT表示一个记录集类型,当前尚未被任何驱动支持。
持久连接(长连接)
持久连接(长连接)在脚本结束后不会被关闭,且被缓存,当另一个使用相同凭证的脚本连接请求时被重用
持久连接可以避免每次脚本需要与数据库会话时都建立一个新连接的开销,从而让应用程序更快
默认是非持久连接,如果需要持久连接需要在$driver_options参数中设置:
$db = new PDO($dsn, $username, $password, array(PDO::ATTR_PERSISTENT => true));
必须在PDO构造函数中设置,如果是在对象初始化之后用PDO::setAttribute()设置此属性,驱动程序不会使用持久连接
开启事务
$db->beginTransaction():开启一个事务
$db->beginTransaction()
如果底层驱动不支持事务,则抛出一个PDOException异常
PDO仅在驱动层检查是否具有事务处理能力,如果某些运行时条件意味着事务不可用时去启动一个事务将仍然返回TRUE而且没有错误(如在MySQL数据库的MyISAM数据表中使用事务)
$db->inTransaction(); 检查是否在一个事务内
$db->commit():提交事务
$db->rollBack():回滚
rollBack()回滚并不是回滚所有的类型(例如在MySQL中使用DROP TABLE)
这个方法并不是真正的可靠,建议尽量避免依赖此方法
预处理语句
在驱动程序不支持的时候PDO将模拟预处理
这可以确保程序用相同的数据访问模式而不管数据库是否具有预处理功能
模拟预处理是在将语句传给SQL服务器之前会把参数数据插入到语句中
这使得某些系统容易受到SQL注入,可以把PDO::ATTR_EMULATE_PREPARES设置为false来关闭模拟预处理功能
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
prepare()方法创建预处理对象(PDOStatement对象)
然后使用bindValue()或bindParam()方法设置预处理对象的占位符的值
bindParam(mixed $parameter,mixed &$variable[,int $type=PDO::PARAM_STR]);
bindValue(mixed $parameter,mixed $variable[,int $type=PDO::PARAM_STR]);
$type为数据类型常量,表示明确地指定参数的类型
两者的区别是bindParam()中$variable变量作为引用被绑定,并只在PDOStatement::execute()被调用的时候才取其值
1、命名占位符(名称前面的冒号不要忘记)
$stmt = $db->prepare("insert into tablename (name, value) values (:name, :value)");
$stmt->bindValue(':name', $name);
$stmt->bindValue(':value', $value);
2、匿名占位符(使用问号'?'作为占位符)
$stmt = $db->prepare("select * from tablename where username=? and passwd=?)");
$stmt->bindValue(1, $username);
$stmt->bindValue(2, $passwd);
在同一个SQL语句里,命名占位符和匿名占位符不能同时使用;
最后使用execute()方法执行预处理语句$stmt->execute();
为了避免只使用bindValue带来的代码碎片,可以给execute方法传入数组作为参数:
$stmt1->execute(array(':name' => 'name', ':value' => 'value'));
$stmt2->execute(array(1 => 'username', 2 => 'passwd'));
PDO类的其他属性和方法
PDO::getAttribute(int $attribute) 获取一个数据库连接的属性
PDO::getAvailableDrivers()获取当前状态所有可用驱动的数组
PDO::exec(string $statement)执行一条SQL语句并返回受影响的行数
PDO::errorCode()获取跟数据库句柄上一次操作相关的 SQLSTATE,一个由5个字母或数字组成的在 ANSI SQL 标准中定义的标识符
PDOS::errorInfo()获取跟数据库句柄上一次操作相关的扩展错误信息(数组类型)
PDO::query(string $statement)执行SQL语句,返回结果集,返回一个PDOStatement对象。
PDO::lastInsertId()返回最后插入行的ID或序列值
PDO::quote(string $string[,int $type=PDO::PARAM_STR])
为输入的字符串添加引号(如果有需要)
并对特殊字符进行转义,且引号的风格和底层驱动适配
$type为数据类型常量,以便选择引号风格
PDOStatement类其他属性和方法
PDOStatement::bindColumn(mixed $column,mixed &$param[,int $type])
绑定一列到一个PHP变量
每次调用PDOStatement::fetch()或 PDOStatement::fetchAll()都将实时更新所有绑定到列的变量
$column:结果集中的列号(从1开始索引)或列名。如果使用列名,注意大小写保持一致
$param:将绑定到列的 PHP 变量名称,以引用赋值传递
$type:为数据类型常量,表示明确地指定参数的类型
PDOStatement::closeCursor():关闭游标,使查询语句能被执行,当上一个执行仍有未取行时是不能再次使用查询语句的,需要关闭游标。
PDOStatement::columnCount()返回结果集中的列数
如果是由PDO::query()返回的PDOStatement对象,则列数计算立即可用。
如果是由PDO::prepare()返回的PDOStatement对象,则在调用PDOStatement::execute()之前都不能准确地计算出列数
PDOStatement::errorCode()获取跟上一次语句句柄操作相关的SQLSTATE,一个由5个字母或数字组成的在 ANSI SQL 标准中定义的标识符
PDOStatement::errorInfo()获取跟上一次语句句柄操作相关的扩展错误信息(数组类型)
PDOStatement::fetch([int $fetch_style])从结果集中获取下一行
$fetch_style控制数据如何返回,是PDO::FETCH_*系列常量中的一个
PDOStatement::fetchAll([int $fetch_style])返回一个包含结果集中所有剩余行的数组
PDOStatement::fetchColumn([int $column_number=0])
从结果集中的下一行返回单独的一列
$column_number是列的索引数字(以0开始)
PDOStatement::fetchObject()获取下一行并作为一个对象返回
PDOStatement::getAttribute(int $attribute)检索一个语句属性
PDOStatement::rowCount()返回受上一个 SQL 语句影响的行数
PDOStatement::setAttribute(int $attribute , mixed $value)设置一个语句属性
PDOStatement::setFetchMode(int $mode)为语句设置默认的获取模式。获取模式是PDO::FETCH_*系列常量中的一个