一 PDO 简介
PDO是数据库访问抽象层,统一各种数据库的访问接口
PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。实现 PDO 接口的每个数据库驱动可以公开具体数据库的特性作为标准扩展功能。 注意利用 PDO 扩展自身并不能实现任何数据库功能;必须使用一个 具体数据库的 PDO 驱动 来访问数据库服务。
PDO 提供了一个 数据访问
下列驱动目前实现了 PDO 接口:
驱动名称 | 支持的数据库 |
PDO_CUBRID | Cubrid |
PDO_DBLIB | FreeTDS / Microsoft SQL Server / Sybase |
PDO_FIREBIRD | Firebird/Interbase 6 |
PDO_IBM | IBM DB2 |
PDO_INFORMIX | IBM Informix Dynamic Server |
PDO_MYSQL | MySQL 3.x/4.x/5.x |
PDO_OCI | Oracle Call Interface |
PDO_ODBC | ODBC v3 (IBM DB2, unixODBC and win32 ODBC) |
PDO_PGSQL | PostgreSQL |
PDO_SQLITE | SQLite 3 及 SQLite 2 |
PDO_SQLSRV | Microsoft SQL Server / SQL Azure |
PDO_4D | 4D |
二 开启PDO
以mysql 举例 在php.ini中找到
extension=php_pdo.dll
extension=php_pdo_mysql.dll
去掉其前面的分号,有的版本可能没有extension=php_pdo.dll
三 PDO连接数据库
(1)通过参数形式
// 参数形式
$dsn = 'mysql:host=localhost;dbname=test';
$username = 'root';
$password = '';
$PDO = new PDO($dsn,$username,$password);
(2)通过URI形式
// URI形式
$dsn = 'uri:file://D:/newwamp/www/dsn.txt';
$username = 'root';
$password = '';
$PDO = new PDO($dsn,$username,$password);
(3)通过配置文件形式
// 配置文件形式
// 在php.ini 中配置 pdo.dsn.dsnConf="mysql:host=localhost;dbname=test"
$dsn = 'dsnConf';
$username = 'root';
$password = '';
$PDO = new PDO($dsn,$username,$password);
四 具体方法使用
(1)执行增删改
PDO::exec — 执行一条 SQL 语句,并返回受影响的行数 增删改 不能查(select)
(2)查询数据
(2.1) query方法的多种用法
$PDO = new PDO('mysql:host=localhost;dbname=test','root','');
//直接执行PDO的query方法返回的是PDOStatement对象 PDOStatement 对象有fetch 和 fetchAll方法 返回数组
// 既可以在query方法返回的对象上调用这两个方法,也可以通过query方法链式调用
// 一 索引数组与关联数组并存
$stmt = $PDO->query("select id,name,phone from user"); // 返回一个PDOStatement类的对象
$data = $PDO->query("select id,name,phone from user")->fetch(); // 返回一条数据 array
$data = $PDO->query("select id,name,phone from user")->fetchAll(); // 返回所有数据 array
foreach($stmt as $k=>$v){
echo "<pre>";
print_r($v);
}
/*
以上程序的输出类似于
Array
(
[id] => 1
[0] => 1
[name] => king
[1] => king
[phone] => 13100000000
[2] => 13100000000
)
Array
(
[id] => 2
[0] => 2
[name] => queen
[1] => queen
[phone] => 13111111111
[2] => 13111111111
)
*/
// 二 只返回关联数组
$stmt = $PDO->query("select id,name,phone from user",PDO::FETCH_ASSOC); // 返回一个PDOStatement类的对象
$data = $PDO->query("select id,name,phone from user",PDO::FETCH_ASSOC)->fetchAll();//array
$data = $PDO->query("select id,name,phone from user")->fetchAll(PDO::FETCH_ASSOC);// 效果同上
foreach($stmt as $k=>$v){
echo "<pre>";
print_r($v);
}
/*
以上程序的输出类似于
Array
(
[id] => 1
[name] => king
[phone] => 13100000000
)
Array
(
[id] => 2
[name] => queen
[phone] => 13111111111
)
*/
// 三 获取某一列 第三个参数为列的编号
$stmt = $PDO->query("select id,name,phone from user",PDO::FETCH_COLUMN,2);
foreach($stmt as $k=>$v){
echo "<pre>";
print_r($v);
}
/*
以上程序的输出类似于
13100000000
13111111111
*/
// 四 取出的每个数据为某个类的对象返回 其中类的构造函数和query的第四个参数同时存在或同时不存在
// 取出的每一条数据都以myobj的一个实例对象返回 取出的字段名都作为对象的属性,值作为对象的属性值存在
class myobj{
private $lei;
public function __construct($lei){
$this->lei = $lei;
}
}
$data = $PDO->query(
"select id,name,phone from user",
PDO::FETCH_CLASS,
'myobj',
array('lei'=>'dog')
)->fetchAll();
foreach($data as $k=>$v){
echo "<pre>";
print_r($v);
}
/*
以上程序输出类似于
myobj Object
(
[lei:myobj:private] => dog
[id] => 1
[name] => king
[phone] => 13100000000
)
myobj Object
(
[lei:myobj:private] => dog
[id] => 2
[name] => queen
[phone] => 13111111111
)
*/
(2.2)prepare()和execute()方法查询数据
$sql = "select * from user";
$stmt = $PDO->prepare($sql);
$res = $stmt->execute();
// 第一种方式 fetchAll设置参数取数据
// if($res){
// $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// var_dump($rows);
// }
// 第二种方式 setFetchMode方法取数据
if($res){
$stmt->setFetchMode(PDO::FETCH_NUM);
$rows1 = $stmt->fetchAll();
var_dump($rows1);
}
(3)设置数据库连接属性
设置自动提交,持久连接之类的属性可以通过getAttribute来得到相应的属性,通过setAttribute来设置相应的属性,也可以通过在new PDO对象时通过构造函数的第四个参数来设置。
可操作的参数有
PDO::ATTR_AUTOCOMMIT (integer) | 如果此值为 FALSE ,PDO 将试图禁用自动提交以便数据库连接开始一个事务。 |
PDO::ATTR_PREFETCH (integer) | 设置预取大小来为你的应用平衡速度和内存使用。并非所有的数据库/驱动组合都支持设置预取大小。较大的预取大小导致性能提高的同时也会占用更多的内存。 |
PDO::ATTR_TIMEOUT (integer) | 设置连接数据库的超时秒数。 |
PDO::ATTR_ERRMODE (integer) | 关于此属性的更多信息请参见 错误及错误处理 部分。 |
PDO::ATTR_SERVER_VERSION (integer) | 此为只读属性;返回 PDO 所连接的数据库服务的版本信息。 |
PDO::ATTR_CLIENT_VERSION (integer) | 此为只读属性;返回 PDO 驱动所用客户端库的版本信息。 |
PDO::ATTR_SERVER_INFO (integer) | 此为只读属性。返回一些关于 PDO 所连接的数据库服务的元信息。 |
PDO::ATTR_CONNECTION_STATUS (integer) | |
PDO::ATTR_CASE (integer) | 用类似 PDO::CASE_* 的常量强制列名为指定的大小写。 |
PDO::ATTR_CURSOR_NAME (integer) | 获取或设置使用游标的名称。当使用可滚动游标和定位更新时候非常有用。 |
PDO::ATTR_CURSOR (integer) | 选择游标类型。 PDO 当前支持 PDO::CURSOR_FWDONLY 和 PDO::CURSOR_SCROLL。一般为 PDO::CURSOR_FWDONLY,除非确实需要一个可滚动游标。 |
PDO::ATTR_DRIVER_NAME (string) | 使用 PDO::ATTR_DRIVER_NAME 的例子: <?php |
PDO::ATTR_ORACLE_NULLS (integer) | 在获取数据时将空字符串转换成 SQL 中的 NULL 。 |
PDO::ATTR_PERSISTENT (integer) | 请求一个持久连接,而非创建一个新连接。关于此属性的更多信息请参见 连接与连接管理 。 |
PDO::ATTR_STATEMENT_CLASS (integer) | |
PDO::ATTR_FETCH_CATALOG_NAMES (integer) | 将包含的目录名添加到结果集中的每个列名前面。目录名和列名由一个小数点分开(.)。此属性在驱动层面支持,所以有些驱动可能不支持此属性。 |
PDO::ATTR_FETCH_TABLE_NAMES (integer) | 将包含的表名添加到结果集中的每个列名前面。表名和列名由一个小数点分开(.)。此属性在驱动层面支持,所以有些驱动可能不支持此属性。 |
PDO::ATTR_STRINGIFY_FETCHES (integer) | |
PDO::ATTR_MAX_COLUMN_LEN (integer) | |
PDO::ATTR_DEFAULT_FETCH_MODE (integer) | 自 PHP 5.2.0 起可用。 |
PDO::ATTR_EMULATE_PREPARES (integer) | 自 PHP 5.1.3 起可用。 |
<span style="font-size:18px;">$PDO->getAttribute(<span style="color: rgb(51, 51, 51); font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, STHeiti, "Microsoft Yahei", sans-serif; background-color: rgb(246, 244, 240);">PDO::ATTR_AUTOCOMMIT</span>);
$PDO->setAttribute(<span style="color: rgb(51, 51, 51); font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, STHeiti, "Microsoft Yahei", sans-serif; background-color: rgb(246, 244, 240);">PDO::ATTR_AUTOCOMMIT,1</span>);</span>
或者new PDO对象时传入参数
$dsn = 'mysql:host=localhost;dbname=test';
$username = 'root';
$password = '';
$options = array(
PDO::ATTR_AUTOCOMMIT=>1
);
$PDO = new PDO($dsn,$username,$password,$options);
(4)quote() 防sql注入
quote() 可以对用户输入的参数作引号处理,并可以对其中的特殊字符转义来防止sql注入
$username = "king'queen";
$username1 = $PDO->quote($username);
echo $username;
echo "<br/>";
echo $username1;
// king'queen 输出结果为
// 'king\'queen'
(5) PDO中的预处理
(5.1) 参数占位形式
// 预处理中的参数占位形式
$username = 'ceshi';
$passwd = '123456';
$sql = " select * from user where username = :username and passwd = :passwd";
$stmt = $PDO->prepare($sql);
$stmt->execute(array(':username'=>$username,':passwd'=>$passwd));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
/*array (size=1) // 以上程序输出类似
0 =>
array (size=5)
'id' => string '1' (length=1)
'phone' => string '13100000000' (length=11)
'username' => string 'ceshi' (length=5)
'passwd' => string '123456' (length=6)
'email' => string 'ceshi@qq.com' (length=12)*/
(5.2) 问号形式
// 预处理中的 ? 形式
$username = 'ceshi';
$passwd = '123456';
$sql = " select * from user where username = ? and passwd = ?";
$stmt = $PDO->prepare($sql);
$stmt->execute(array($username,$passwd));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
// 以上程序输出类似
/*array (size=1)
0 =>
array (size=5)
'id' => string '1' (length=1)
'phone' => string '13100000000' (length=11)
'username' => string 'ceshi' (length=5)
'passwd' => string '123456' (length=6)
'email' => string 'ceshi@qq.com' (length=12)*/
(6)bindParam方法的使用
// bindParam方法的使用
$sql = "select * from user where phone = :phone";
$stmt = $PDO->prepare($sql);
$stmt->bindParam(":phone",$phone,PDO::PARAM_STR);
$phone = '13100000000'; // 可能通过GET 或 POST 接收
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$arr = $stmt->fetchAll();
echo "<pre>";
var_dump($arr);
// 以上程序输出类似 适用于增删改查
/*array(1) {
[0]=>
array(3) {
["id"]=>
string(1) "1"
["name"]=>
string(4) "king"
["phone"]=>
string(11) "13100000000"
}
}*/
(7)bindValue 方法的使用
// bindValue 方法的使用
$sql = "select * from user where phone = :phone";
$stmt = $PDO->prepare($sql);
$stmt->bindValue(":phone",'13100000000'); // 此处可直接写值并且绑定一次可多次使用
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$arr = $stmt->fetchAll();
echo "<pre>";
var_dump($arr);
// 以上程序输出类似
/*array(1) {
[0]=>
array(3) {
["id"]=>
string(1) "1"
["name"]=>
string(4) "king"
["phone"]=>
string(11) "13100000000"
}
}*/
(8) bindColumn 绑定一列到一个 PHP 变量
// bindColumn 绑定一列到一个 PHP 变量
$sql = "select * from user ";
$stmt = $PDO->prepare($sql);
// 通过列号绑定
$stmt->bindColumn(1,$id);
// 通过列名绑定
$stmt->bindColumn('name',$username);
$stmt->bindColumn('phone',$phone);
$stmt->execute();
while(false != ($row = $stmt->fetch(PDO::FETCH_BOUND))){
echo 'id:'.$id.' '.'name:'.$username.' '.'phone:'.$phone.'<br/>';
}
/*
以上程序输出类似于
id:1 name:king phone:13100000000
id:2 name:queen phone:13111111111
更多函数的用法此处就不一一举例