php中的PDO使用详解

来源:互联网 发布:索尼和夏普电视 知乎 编辑:程序博客网 时间:2024/04/29 11:19

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 0
原创粉丝点击