PDO

Posted zhony

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PDO相关的知识,希望对你有一定的参考价值。

什么是PDO?
PDO是php数据对象(PHP DATA Object)的缩写,PDO 提供了一个数据访问抽象层,这意味着,不
管使?哪种数据库,都可以用相同的函数(方法)来查询和获取数据。
简单来说,PDO就是实现PHP连接不同数据库之间的桥梁的工具,PHP操作mysql系列函数只能操作
mysql数据库,但如果有其他类型的数据库,PDO就是必备之选,当然,PDO也可以操作mysql数据
库。
优势:
1.PDO从底层实现统一接口数据库操作,不管用哪种数据库,都非常方便。
2.PDO是PHP官方库,兼容性稳定。
3.PDO的预处理可以有效防止sql注入,确保数据库更安全。

PDO连接mysql

 PDO查询数据库

 1 //1.准备一个可连接的dsn
 2 $mysqldsn = ‘mysql:host=localhost;dbname=test;charset=utf8‘;
 3 //2.实例化对象,传入dsn,用户名,密码
 4 //$pdo = new PDO($mysqldsn,‘root‘,‘root‘);
 5 try{
 6  //如果实例化失败会抛出异常,我们可以使用异常处理来接收并输出异常信息
 7  $pdo = new PDO($mysqldsn,‘root‘,‘root‘);
 8 }catch(PDOException $e){
 9  echo $e->getMessage();
10 }
11 //var_dump($pdo);
12 //3.设置字符集,如果开头dsn信息中设置了字符集,这一步可以省略
13 //$sql = "set names utf8";
14 //$pdo->exec($sql);
15 //4.常规操作
16 $sql = "select * from info";
17 //5.发送sql语句
18 $result = $pdo->query($sql);
19 var_dump($result);

写到这里可能会报错,但没有任何报错信息,pdo默认是沉默模式,报错了不说话,除非语法有问
题。
设置错误模式

1 //手册中关于pdo错误设置在方法$pdo->setAttrbute()方法
2 //设置属性
3 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
4 //它们均可用数字表示
5 echo PDO::ATTR_ERRMODE;//3
6 echo PDO::ERRMODE_WARNING;//1
7 $pdo->setAttribute(3,1);
8 //输出错误信息
9 var_dump($pdo->errorInfo());

PDO::ATTR_ERRMODE:错误报告。
PDO::ERRMODE_SILENT: 仅设置错误代码,沉默模式。
PDO::ERRMODE_WARNING: 引发 E_WARNING 错误
PDO::ERRMODE_EXCEPTION: 抛出 exceptions 异常。
总结:分6部完成pdo查询数据库信息

 1 //1.准备一个可连接的dsn
 2 $mysqldsn = ‘mysql:host=localhost;dbname=test;charset=utf8‘;
 3 //2.实例化对象,传入dsn,用户名,密码
 4 //$pdo = new PDO($mysqldsn,‘root‘,‘root‘);
 5 try{
 6  //如果实例化失败会抛出异常,我们可以使用异常处理来接收并输出异常信息
 7  $pdo = new PDO($mysqldsn,‘root‘,‘root‘);
 8 }catch(PDOException $e){
 9  echo $e->getMessage();
10 }
11 //var_dump($pdo);
12 //3.设置字符集,如果开头dsn信息中设置了字符集,这一步可以省略
13 //$sql = "set names utf8";
14 //$pdo->exec($sql);
15 //4.设置错误错误模式
16 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
17 //5.常规操作
18 $sql = "select * from info";
19 //6.发送sql语句
20 $result = $pdo->query($sql);
21 var_dump($result);

PDO删除和修改数据库

 1 <?php
 2  //删除和修改
 3  //1.准备一个dsn 
 4  $mysql = ‘mysql:dbname=test;host=localhost;charset=utf8‘;
 5  
 6  //2.实例化对象
 7  try{
 8  $pdo = new PDO($mysql,‘root‘,‘root‘);
 9  }catch(PDOException $e){
10  echo $e->getMessage();
11  }
12  
13  //3.设置字符集
14  //4.设置错误模式
15  $pdo->setAttribute(3,1);
16  //常规操作
17  
18  //删除操作
19  //$sql="DELETE FROM info WHERE id=10";
20  
21  //修改操作
22  $sql="UPDATE info SET `name`=‘二哈‘ WHERE id=11";
23  
24  //发送sql语句
25  //返回的是受影响行
26  $row =$pdo->exec($sql);
27  var_dump($row);

 PDO添加数据

 1 <?php
 2  $dsn = ‘mysql:dbname=test;host=localhost;charset=utf8‘;
 3  try{
 4  $pdo= new PDO($dsn,‘root‘,‘root‘);
 5  }catch(PDOException $e){
 6  echo $e->getMessage();
 7  }
 8  $pdo->setAttribute(3,1); 
 9  $sql="INSERT INTO info(name,sex,age,city) VALUES(‘强强‘,2,45,‘呼市‘)";
10  //执行
11  $row = $pdo->exec($sql);
12  var_dump($row);
13  //mysqli_insert_id()
14  //最后一次插入的id
15  
16  echo $pdo->lastInsertId();

 PDO查询遍历表格

 1 <?php
 2  //1.
 3  $dsn = ‘mysql:dbname=test;host=localhost;charset=utf8‘;
 4  try{
 5  $pdo = new PDO($dsn,‘root‘,‘root‘);
 6  }catch(PDOException $e){
 7  echo $e->getMessage();
 8  }
 9  //3
10  //4
11  $pdo->setAttribute(3,1);
12  $sql="SELECT * FROM info";
13  //返回一个对象 PDOStatement
14  //对象可以当做数组形式遍历(不推荐)
15  $userlist = $pdo->query($sql);
16  var_dump($userlist);
17 ?>
18 <!DOCTYPE html>
19 <html lang="en">
20 <head>
21  <meta charset="UTF-8">
22  <title>Document</title>
23 </head>
24 <body>
25  <table border="1" width="800" align="center">
26  <tr>
27  <th>Id</th>
28  <th>Name</th>
29  <th>Age</th>
30  <th>Sex</th>
31  <th>City</th>
32  </tr>
33  <?php foreach($userlist as $value){?>
34  <tr>
35  <td><?php echo $value[‘id‘]?></td>
36  <td><?php echo $value[‘name‘]?></td>
37  <td><?php echo $value[‘age‘]?></td>
38  <td><?php echo $value[‘sex‘]?></td>
39  <td><?php echo $value[‘city‘]?></td>
40  </tr>
41  <?php } ?>
42  </table>
43 </body>
44 </html>

PDO事务

 1 <?php
 2  
 3  //1.
 4  $dsn = ‘mysql:dbname=test;host=localhost;charset=utf8‘;
 5  try {
 6  $pdo = new PDO($dsn,‘root‘,‘root‘);
 7  } catch (PDOException $e) {
 8  echo $e->getMessage();
 9  }
10  //3.
11  //4
12  $pdo->setAttribute(3,1);
13  //常规操作
14  //1.开启事务
15  $pdo->beginTransaction();
16  //2.一系列操作
17  
18  $sql="UPDATE info SET age=age-5 WHERE id=79";
19  $row = $pdo->exec($sql);
20  //$sql="UPDATE info SET age=age+5 WHERE id=81";
21  //$row = $pdo->exec($sql);
22  //如何判断两个操作都完成了?
23  $sql="UPDATE info SET age=age+5 WHERE id=81";
24  $row += $pdo->exec($sql);
25  //var_dump($row);
26  if($row == 2){
27  //表示完成事务,结束
28  $pdo->commit();
29  }else{
30  //表示未完成,中间可能断了,执行回滚。
31  $pdo->rollBack();
32  }

 PDO预处理

 

常见的破坏

所谓预处理,就是预先把mysql的执行语句语法部分先执行,然后再往里填写内容,而不是像我们之
前那样拼装出来的sql语句,拼装的sql很容易出现用户捣乱的事情。
比如:

 1 <?php
 2  $dsn = ‘mysql:dbname=test;host=localhost;charset=utf8‘;
 3  try {
 4  $pdo= new PDO($dsn,‘root‘,‘root‘);
 5  } catch (PDOException $e) {
 6  echo $e->getMessage();
 7  }
 8  //3设置字符集
 9  //4.开启错误模式
10  $pdo->setAttribute(3,1);
11  //$name ="jack‘s sister";
12  //$name = $pdo->quote($name);
13  //echo $name;exit;
14  //$sql="INSERT INTO info(name,sex,age,city) VALUES({$name},0,18,‘美利坚合众
15 国‘)";
16  //echo $sql;exit;
17  $id=" ‘ or 1=1 or ‘";
18  //$id=79;
19  $sql="SELECT * FROM info WHERE id=‘{$id}‘";
20  $sql="DELETE FROM info WHERE id=‘{$id}‘";
21  echo $sql;exit;
22  //发送sql语句
23  //echo $pdo->exec($sql);
24  $stmt=$pdo->query($sql);
25  var_dump($stmt);

对于这种用户搞破坏的情况,记住,用户过来的所有信息都需要特别注意,树林子大了什么鸟都有。
比如:地址栏,form表单,后面还有cookie等等。

预处理的应用

利用PDO的预处理可以有效防止这种情况。

 1 <?php
 2  //1.准备dsn
 3  $mysql ="mysql:dbname=test;host=localhost;charset=utf8";
 4  //2.实例化对象
 5  try {
 6  $pdo=new PDO($mysql,‘root‘,‘root‘);
 7  } catch (PDOException $e) {
 8  echo $e->getMessage();
 9  }
10  //3.设置字符集
11  //4.开启错误模式
12  $pdo->setAttribute(3,1);
13  
14  //利用?来站位,表示我的sql语句有几个参数。
15  $sql="INSERT INTO info(name,sex,age,city) VALUES(?,?,?,?)";
16  //发送模版语句 得到预处理对象
17  $stmt = $pdo->prepare($sql);
18  var_dump($stmt);
19  
20  $name =‘喜洋洋‘;
21  $sex =1;
22  $age =11;
23  $city=‘草原‘;
24  //绑定参数
25  //bindParam()
26  //参数1是数字 而且是从1开始的连续的数字
27  //参数2是必须是一个变量
28  $stmt->bindParam(1,$name);
29  $stmt->bindParam(2,$sex);
30  $stmt->bindParam(3,$age);
31  $stmt->bindParam(4,$city);
32  //执行 返回一个是bool
33  $bool = $stmt->execute();
34  var_dump($bool);

问号批量绑定预处理

批处理预定义sql语句,减少麻烦

 1 <?php
 2  //1.准备dsn
 3  $mysql ="mysql:dbname=test;host=localhost;charset=utf8";
 4  //2.实例化对象
 5  try {
 6  $pdo=new PDO($mysql,‘root‘,‘root‘);
 7  } catch (PDOException $e) {
 8  echo $e->getMessage();
 9  }
10  //3.设置字符集
11  //4.开启错误模式
12  $pdo->setAttribute(3,1);
13  $sql="INSERT INTO info(name,sex,age,city) VALUES(?,?,?,?)";
14  //发送模版
15  $stmt=$pdo->prepare($sql);
16  $name = ‘美杨洋‘;
17  $sex = 4;
18  $age = 19;
19  $city=‘??草原‘;
20  //问号占位符 批量绑定
21  //必须从下标为0开始连续的索引数组
22  $data = array(
23  ‘灰太狼‘,
24  $sex,
25  $age,
26  $city
27  );
28  // var_dump($data);exit;
29  //执行
30  $bool = $stmt->execute($data);
31  var_dump($bool);

 冒号占位符进行预处理

 1 <?php
 2  //1.准备dsn
 3  $mysql ="mysql:dbname=test;host=localhost;charset=utf8";
 4   //2.实例化对象
 5   try {
 6   $pdo=new PDO($mysql,‘root‘,‘root‘);
 7   } catch (PDOException $e) {
 8   echo $e->getMessage();
 9   } //3.设置字符集
10   //4.开启错误模式
11   $pdo->setAttribute(3,1);
12   $sql="INSERT INTO info(name,sex,age,city)
13 VALUES(:name,:sex,:age,:city)";
14   //发送模版语句
15   $stmt = $pdo->prepare($sql);
16   $name =‘熊大‘;
17   $sex = 5;
18   $age =17;
19   $city=‘?兴安岭‘;
20   //绑定参数 冒号形式
21   //冒号占位符可以省略掉前面的冒号
22   $stmt->bindParam(‘name‘,$name);
23   $stmt->bindParam(‘sex‘,$sex);
24   $stmt->bindParam(‘age‘,$age);
25   $stmt->bindParam(‘city‘,$city);
26   //执?
27   $bool = $stmt->execute();
28   var_dump($bool);

 冒号批量绑定预处理

 1 <?php
 2  //1.准备dsn
 3  $mysql ="mysql:dbname=test;host=localhost;charset=utf8";
 4  //2.实例化对象
 5  try {
 6  $pdo=new PDO($mysql,‘root‘,‘root‘);
 7  } catch (PDOException $e) {
 8  echo $e->getMessage();
 9   } //3.设置字符集
10   //4.开启错误模式
11   $pdo->setAttribute(3,1);
12   $sql="INSERT INTO info(name,sex,age,city)
13 VALUES(:name,:sex,:age,:city)";
14   //发送模版语句
15   $stmt = $pdo->prepare($sql);
16   // $name =‘熊大‘;
17   // $sex = 5;
18   // $age =17;
19   // $city=‘兴安岭‘;
20   //请看这个数组想什么数组?$_POST
21   // $data = array(
22   // ‘name‘=>$name,
23   // ‘sex‘=>$sex,
24   // ‘age‘=>$age,
25   // ‘city‘=>$city,
26   // );
27   // var_dump($data);exit;
28   var_dump($_POST);
29   //执?
30   $bool = $stmt->execute($_POST);
31   var_dump($bool);
32 ?>
33 <!DOCTYPE html>
34 <html lang="en">
35 <head>
36   <meta charset="UTF-8">
37   <title> </title>
38 </head>
39 <body>
40   <form action="demo.php" method="post">
41   name: <input type="text" name="name"><br/>
42   sex: <input type="text" name="sex"><br/>
43   age: <input type="text" name="age"><br/>
44   city: <input type="text" name="city"><br/>
45   <input type="submit" value="提交">
46   </form>
47 </body>
48 </html>

获取结果集

 1 <?php
 2  $mysql = ‘mysql:dbname=test;host=localhost;charset=utf8‘;
 3  try {
 4  $pdo = new PDO($mysql,‘root‘,‘root‘);
 5  } catch (PDOException $e) {
 6  echo $e->getMessage();
 7  }
 8  $pdo->setAttribute(3,1);
 9  $sql="SELECT id,name,sex,age,city FROM info WHERE id>:id";
10  $stmt = $pdo->prepare($sql);
11  $id = 80;
12  $stmt->bindParam(‘id‘,$id);
13  
14  $bool = $stmt->execute();
15  var_dump($bool);
16  
17  //var_dump($stmt->fetch());
18  //var_dump($stmt->fetch());
19  //var_dump($stmt->fetch());
20  //echo PDO::FETCH_ASSOC;exit;
21  // while($row = $stmt->fetch(2)){
22  // $list[]=$row;
23  // }
24  // var_dump($list);
25  $list = $stmt->fetchAll(2);
26  var_dump($list);
27  //获取得到多少条数据或者受多少行影响
28  echo $stmt->rowCount();

对象->fetch()方法和 对象 ->fetchAll() 的区别
这两个方法分别提供了不同的参数来显示不同的效果。
默认是关联索引都有的数组

技术分享图片

 





















以上是关于PDO的主要内容,如果未能解决你的问题,请参考以下文章

PDO

通过 pdo 代码填充下拉菜单

在 PDO 的 JS 代码中使用 PHP 数组

我应该在 PDO 对象中返回啥来生成可靠的代码?

封装PDO连接数据库代码

这个 PDO 代码对 SQL 注入是不是足够安全? [复制]