PDO预处理

PDOStatement类

     该类有一个语句,和PDO中对象的exec()及query()相比,可以帮助处理结果集
     预处理的好处是,只在服务端编辑一次SQL语句,可以大大提高效率,同时在安全上可以防止sql注入。传统的防注入的方法是屏蔽表单中的空格或者屏蔽掉sql注入语句中的符号,如*等。
   所以好的严谨的程序一般不用exec()和query()

<?php
    try{
           $pdo=new PDO("mysql:host=localhost;dbname=xsphpdb","root","");
    }catch(PDOException $e){
           echo $e->getMessage();
    }
    //$pdo->exec();//传统用法  负责 更新,删除,插入
    //$pdo->query();//传统用法 负责 查询
    //$stmt=$pdo->prepare("update shops set name='a' where id=100");//prepare这种是把上述两种方法合起来了,负责所有的
     $stmt=$pdo->prepare("insert into shops(name,price,num,desn) values(?,?,?,?)") ;//?相当于操作索引数组,是按所引顺序找的点位符
    //准备好下面的一条语句,并入到服务器端,也已经编译过来了,就差为它分配数据过来
    // $stmt=$pdo->prepare("insert into shops(name,price,num,desn) values(:name,:price,:num,:desn)"); //名字参数相当于操作关联数组
   //下面是绑定参数

     $stmt->bindParam(1,$name);
    $stmt->bindParam(3,$num);
    $stmt->bindParam(4,$desn);
    $stmt->bindParam(2,$p);

     $name="wwww1";
    $num=101;
    $desn="heool1";
    $p=34.51;
    if($stmt->execute()){
        echo "执行成功!";
         echo "最后插入的ID:".$pdo->lastInsertId();
    }else{
        echo "执行失败!";
    }

PDO对预处理语句的支持需要使用PDOStatement类对象,但该类对象并不是通过NEW关键字实例化出来的,而是通过PDO对象中的prepare()方法,在数据库服务器中准备好一个预处理的SQL语句后直接返回的。如果通过之前执行PDO对象中的query()方法返回的PDOStatement类对象,只代表的是一个结果集对象。而如果通过执行PDO对象中的prepare()方法产生的PDOStatement类对象,则为一个查询对象,能定义和执行参数化的SQL命令。PDOStatement类中的全部成员方法如下所示:

01. PDOStatement::bindColumn ― 绑定一列到一个 PHP 变量
02.  
03. PDOStatement::bindParam ― 绑定一个参数到指定的变量名
04.  
05. PDOStatement::bindValue ― 把一个值绑定到一个参数
06.  
07. PDOStatement::closeCursor ― 关闭游标,使语句能再次被执行。
08.  
09. PDOStatement::columnCount ― 返回结果集中的列数
10.  
11. PDOStatement::debugDumpParams ― 打印一条 SQL 预处理命令
12.  
13. PDOStatement::errorCode ― 获取跟上一次语句句柄操作相关的 SQLSTATE
14.  
15. PDOStatement::errorInfo ― 获取跟上一次语句句柄操作相关的扩展错误信息
16.  
17. PDOStatement::execute ― 执行一条预处理语句
18.  
19. PDOStatement::fetch ― 从结果集中获取下一行
20.  
21. PDOStatement::fetchAll ― 返回一个包含结果集中所有行的数组
22.  
23. PDOStatement::fetchColumn ― 从结果集中的下一行返回单独的一列。
24.  
25. PDOStatement::fetchObject ― 获取下一行并作为一个对象返回。
26.  
27. PDOStatement::getAttribute ― 检索一个语句属性
28.  
29. PDOStatement::getColumnMeta ― 返回结果集中一列的元数据
30.  
31. PDOStatement::nextRowset ― 在一个多行集语句句柄中推进到下一个行集
32.  
33. PDOStatement::rowCount ― 返回受上一个 SQL 语句影响的行数
34.  
35. PDOStatement::setAttribute ― 设置一个语句属性
36.  
37. PDOStatement::setFetchMode ― 为语句设置默认的获取模式。
 
使用命名参数作为占位符的INSERT插入语句:
$dbh->prepare(“insert into contactinfo(name,address,phone) values(:name,:address,:phone)”);
 
使用问号(?)参数作为占位符的INSERT插入语句:
$dbh->prepare(“insert into contactinfo(name,address,phone) values(?,?,?)”);

什么是预处理?

成熟的数据库都支持预处理语句(Prepared Statements)的概念。

它们是什么东西?你可以把它们想成是一种编译过的要执行的SQL语句模板,可以使用不同的变量参数定制它。

预处理语句具有两个主要的优点:

1 查询只需要被解析(或准备)一次,但可以使用相同或不同的参数执行多次。当查询准备好(Prepared)之后,数据库就会分析,编译并优化它要执行查询的计划。

对于复杂查询来说,如果你要重复执行许多次有不同参数的但结构相同的查询,这个过程会占用大量的时间,使得你的应用变慢。

通过使用一个预处理语句你就可以避免重复分析、编译、优化的环节。简单来说,预处理语句使用更少的资源,执行速度也就更快。

2 传给预处理语句的参数不需要使用引号,底层驱动会为你处理这个。

如果你的应用独占地使用预处理语句,你就可以确信没有SQL注入会发生。

代码演示:

<?php
header('content-type:text/html; charset=utf-8');
//实例化pdo对象
$pdo = new PDO('mysql:host=127.0.0.1;port=3306;dbname=test;', 'root', '888888');
//通过query函数执行sql命令
$pdo->query('set names utf8');

//插入数据
$sql    = "insert into persons (name,age) values (?, ?);";
$preObj = $pdo->prepare($sql);
$res    = $preObj->execute(array('小明', 22));
var_dump($res);

//删除数据
$sql = "delete from persons where id = ?";
$preObj = $pdo->prepare($sql);
$res    = $preObj->execute(array(3));
var_dump($res);

//修改数据
$sql = "update persons set name = ? where id = ?;";
$preObj = $pdo->prepare($sql);
$res    = $preObj->execute(array('lucy', 5));
var_dump($res);
//查询数据
$sql = "select * from persons where age > ? order by id desc;";
$preObj = $pdo->prepare($sql);
$preObj->execute(array(20));
$arr = $preObj->fetchAll(PDO::FETCH_ASSOC);
/*
 * FETCH_BOTH      是默认的,可省,返回关联和索引。
 * FETCH_ASSOC     参数决定返回的只有关联数组。
 * PDO::FETCH_NUM  返回索引数组
 * PDO::FETCH_OBJ  返回由对象组成的二维数组
 */
print_r($arr);

 PDOStatement类:准备语句,处理结果集     也就是预处理,安全,高效,推荐使用

    两种占位符号:?参数         索引数组,按索引顺序使用                  名子参数      关联数组,按名称使用,和顺序无关,以冒号开头,自己定义

    $stmt=$pdo->prepare($sql);     $sql可是是任意sql语句,这与mysqli不同

两种点位符号

<?php   try{     $pdo=new PDO("mysql:host=localhost;dbname=mysqldb","root","snail");   }catch(PDOException $e){     echo $e->getMessage();   }

  //准备一条语句,并放到服务器端,而且编译   $stmt=$pdo->prepare("insert into shop(name,price)values(?,?)"); //  $stmt=$pdo->prepare("insert into shop(name,price)values(:na,:pr)");

  //绑定参数(变量和参数绑定)   $stmt->bindparam(1,$name);   $stmt->bindparam(2,$price);

//  $stmt->bindparam(":na",$name); //  $stmt->bindparam(":pr",$price);

  $name="liwu11";   $price=234.4311;

  if($stmt->execute()){     echo "执行成功";     echo "最后插入的ID:".$pdo->lastInsertId();   }else{     echo "执行失败";   } ?>

<?php //以数组方式向服务器传值 

 try{     $pdo=new PDO("mysql:host=localhost;dbname=mysqldb","root","snail");   }catch(PDOException $e){     echo $e->getMessage();   }

  $stmt=$pdo->prepare("select * from shop where id >:id");

  $stmt->execute(array(':id'=>130));

  $row=$stmt->fetch();   print_r($row);   echo '<br>'; ?>

<?php

//用fetch(),fetchAll()来获取查询结果   try{     $pdo=new PDO("mysql:host=localhost;dbname=mysqldb","root","snail");   }catch(PDOException $e){     echo $e->getMessage();   }

  $stmt=$pdo->prepare("select * from shop where id >:id");

  $stmt->execute(array(':id'=>130));

/*  单条获取fetch()    $stmt->setFetchMode(PDO::FETCH_ASSOC);  //设置获取模式   while($row=$stmt->fetch()){     print_r($row);     echo '<br>';   } */

  //多条获取fetchAll() //  $stmt->setFetchMode(PDO::FETCH_ASSOC);   $data=$stmt->fetchAll(PDO::FETCH_ASSOC);  //也可以用上句进行设置   echo '<pre>';   print_r($data);   echo '</pre>'; ?>

<?php //以表格输出查询结果 

try{     $pdo=new PDO("mysql:host=localhost;dbname=mysqldb","root","snail");   }catch(PDOException $e){     echo $e->getMessage();   }

  $stmt=$pdo->prepare("select id,name,price from shop where id >:id");

  $stmt->execute(array(':id'=>130));

  $stmt->bindColumn(id,$id);   $stmt->bindColumn(name,$name);   $stmt->bindColumn(price,$price);

  echo '<table border=1 align="center" width=800px>';   echo '<tr>';   for($i=0;$i<$stmt->columncount();$i++){     $field=$stmt->getColumnMeta($i);     echo '<th>'.$field["name"].'</th>';   }   echo "</tr>";

  while($stmt->fetch()){     echo '<tr>';     echo '<td>'.$id.'</td>';     echo '<td>'.$name.'</td>';     echo '<td>'.$price.'</td>';     echo '</tr>';   }

  echo '</table>';

  echo "行:".$stmt->rowcount()."<br>";   echo "列:".$stmt->columncount()."<br>";

?>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值