php中的PDO使用详解

0、准备工作,创建数据表 users

CREATE DATABASE IF NOT EXISTS `test`;
USE `test`;
CREATE TABLE IF NOT EXISTS `users`(
	id 		  int unsigned  auto_increment,
	email 	  varchar(255)  not null default '',
	password  varchar(255)  not null default '',
	primary key(`id`)
)auto_increment=1,charset=utf8,engine=innodb;

1、数据库连接   http://php.net/manual/zh/pdo.connections.php

PDO::__construct ( string $dsn [, string $username [, string $password [, array $driver_options]]] )

$driver_options 数组 长连接设置 PDO::ATTR_PERSISTENT=>true

$dsn = 'mysql://host=127.0.0.1;port=3306;dbname=test;charset=utf8'; // dsn
$user = 'root'; // 帐号
$pass = '';		// 密码
$dbh = new PDO($dsn,$user,$pass);
// $dbh = new PDO($dsn,$user,$pass,[PDO::ATTR_PERSISTENT=>1]); // 长连接
var_dump($dbh);

2、执行sql语句 exec()   执行非查询语句的sql(select ...)   返回影响的行数或者false

int PDO::exec ( string $statement )    

// 正常的非查询操作返回影响行数
$sql = 'insert into users(email,password) value(\'qweqwe@asd.com\',\''.md5('dsfsadsafasf').'\')';
$rt = $dbh->exec($sql);
var_dump($rt); // int(1)

若执行的sql不存在语法错误的情况下slq会执行但是影响行数为0 

如下代码:

// 执行查询sql语句
$sql = 'select * from users';
// 没有满足wher条件的记录 更新了0行 也就是影响了0行
$sql = 'update users set email=\'fanyilong@163.com\' where id>10000';
$rt = $dbh->exec($sql);
var_dump($rt); // int(0)

如果sql有错误返回false

// user表不存在 sql存在语法错误 返回false
$sql = 'update user set email=\'fanyilong@163.com\' where id>10000';
$rt = $dbh->exec($sql);
var_dump($rt); // bool(false)

所以判断exec是否执行成功要用严格判断 因为exec也会返回 0       $dbh->exec($sql) === false;


3、执行所有的sql        PDOStatement  query($sql)    http://php.net/manual/zh/pdo.query.php


可以执行所有类型的sql 执行成功返回PDOStatement 对象执行 若执行错误返回false

public PDOStatement PDO::query ( string $statement )

// 返回PDOStatement 插入更新等操作返回的不是false就是执行成功 并返回PDOStatement
$sql = 'select * from users';
$sql = 'insert into user(email,password) value(\'fanyilong_v5@cmd.net\',\''.md5('123456').'\')';
$sql = 'select * from user'; // sql执行错误 表user不存在 返回false
$rt = $dbh->query($sql);
var_dump($rt);
foreach($rt as $key=>$val){
<span style="white-space:pre">	</span>print_r($val);
}

查询sql若执行成功返回 对象 PDOStatement (存储有查询的结果数据)  foreach可以直接对返回的对象进行遍历

执行insert update等非查询sql 执行成功返回PDOStatement 

执行失败query 会返回false


4、预处理的形式执行sql     这样可防止sql注入


预处理带有占位符的sql字符串

select * from users where id>?
select * from users where id>:id

这里的 '?'    ':id'   都是占位符 预处理模式会转义这些参数防止sql注入 

public PDOStatement PDO::prepare ( string $statement [, array $driver_options = array() ] )


$sql = 'select * from users where id>:id';
$stmt = $dbh->prepare($sql);
var_dump($stmt);


下面的方法是 PDOStatement类的:


绑定参数到占位符

bool PDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )


设置查询结果的组织形式

参数可以是 PDO::FETCH_* 的常量 PDO常量可以在这里查看 http://php.net/manual/zh/pdo.constants.php

bool PDOStatement::setFetchMode ( int $mode )


执行预处理函数

bool PDOStatement::execute ([ array $input_parameters ] )


查询执行

获取一条

mixed PDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT[, int $cursor_offset = 0 ]]] )

获取所有条

array PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )

示例代码:

$sql = 'select * from users where id>:id';
$stmt = $dbh->prepare($sql);
// bindPatam参数绑定形式
$id=1;
$stmt->bindParam('id',$id);
// 直接绑定
$stmt->bindValue('id',1);
$stmt->execute(); // 执行预处理sql
// 设置结果集数据形式
$stmt->setFetchMode(PDO::FETCH_ASSOC);
// 查询一条数据
$rt1 = $stmt->fetch();
// 查询全部
$rt2 = $stmt->fetchAll();
var_dump($rt1);
var_dump($rt2);

关于参数绑定:

bindValidate(key,val); 直接指定绑定的参数

a、?作为占位符的情况

$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$stmt->bindValue(1,1);
$stmt->bindValue(2,'fantasy@sina.com');
$stmt->execute();
print_r($stmt->fetchAll());

?占位符在绑定的时候 bindValue第一个参数指定?的序列 这个序列从1开始(而不是从零)  bindValue(n,value) 就是将value绑定到第n个?


b、以 :field 作为占位符

$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$stmt->bindValue('id',1);
$stmt->bindValue('email','fantasy@sina.com');
$stmt->execute();
print_r($stmt->fetchAll());

bindValue 的第一个参数是 占位符 :field 中的 field bindValue(field,value) 也就是将value绑定到占位符为 :field 的地方


c、? 与 :key 混合的形式作为占位符

$stmt = $dbh->prepare('select * from user where id>? and email!=:email');
$stmt->bindValue(1,1);
$stmt->bindValue('email','fantasy@sina.com');
$stmt->execute();
print_r($stmt->fetchAll());

这种形式会报错 : Invalid parameter number: mixed named and positional parameters

可参照php官网的一个例子 @link http://php.net/manual/en/pdostatement.bindparam.php#98715


bindParam(key,$value) 绑定变量到sql中

第二个参数必须是变量的引用,像bindValue一样传递常量会报错。

php5.3以后 在函数调用传递一用变量不用加 & 符了,只用在函数定义的时候对参数进行引用声明即可

function func(&$arg){......}      func('aaa');

使用方法与bindValue类似,

$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$id = 1;
$email = 'fantasy@sina.com';
$stmt->bindParam(1,$id);
$stmt->bindParam(2,$email);

$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$id = 1;
$email = 'fantasy@sina.com';
$stmt->bindParam('id',$id);
$stmt->bindParam('email',$email);

execut绑定参数 execut(args_array)

在两种不同的占位符的情况下的绑定形式如下:

?占位符

$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$stmt->execute([1,'fantasy@sina.com']);
print_r($stmt->fetchAll());

:field 占位符

$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$stmt->execute(['id'=>1,'email'=>'fantasy@sina.com']);
print_r($stmt->fetchAll());

非常值得注意的一点是 bindParam() 的一个坑就是 这个函数第二个参数是引用,在foreach循环调用的时候会出现一个bug

这个是鸟哥的解释 http://www.laruence.com/2012/10/16/2831.html


当我们这样使用bindParam的时候


$stmt=$dbh->prepare('select * from users where title=:title and name=:name');
$params = [':title'=>'head of artical',':name'=>'fantasy'];
foreach($params as $key=>$val){
	$stmt->bindParam($key,$val);
}

这样绑定的结果是 select * from users where title='fantasy' and name='fantasy';


分析原因 bindParam 的第二个参数是引用型变量
分解上面的foreach 相当于:

$val = $params[':id'];
$dbh->bindParam(':id',&$val);
$val = $params[':name'];
$dbh->bindParam(':name',&$val);

同一个变量 $val 分别绑定到了 id 与 name 并且第三行修改了 $val内存中的值
这样 绑定参数的两处值也会因此改变为 第三行修改到的值












  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值