PHP PDO prepare()、execute()和bindParam()方法详解

每次将查询发送给MySQL服务器时,都必须解析该查询的语法,确保结构正确并可以执行。这是这个过程当中必要的步骤,但也确实带来了一些开销。作一次是必要的,但若是反复地执行相同的查询,批量插入多行并只改变列值时会怎么样呢?预处理语句会在服务器上缓存查询的语法和执行过程,而只在服务器和客户端之间传输有变化的列值,以此来消除这些额外的开销。php

PDO为支持此特性的数据库提供了预处理语句功能。由于MySQL支持这个特性,因此能够在适当时使用预处理语句。html

预处理语句是使用两个方法实现的:prepare()方法负责准备要执行的查询,execute()方法使用一组给定的列参数反复地执行查询。这些参数能够显式地做为数组传递给execute()方法,也可使用经过bindParam()方法指定的绑定参数提供给execute()方法。mysql


使用预处理语句——prepare()方法

prepare()方法负责准备要执行的查询。语法格式以下:sql

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

可是,用做准备语句的查询与以住使用的查询略有区别,由于对于每次执行迭代中要改变的值,必须使用占位符而不是具体的列值。数据库

查询支持两种不一样的语法:命名参数和问号参数。数组

使用命名参数的查询以下:缓存

INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen;

其中,:xuesheng与:yuwen都是列占位符。服务器

使用问号参数的查询以下:ui

INSERT INTO tb_chengji SET xuesheng=?,yuwen=?;

其中,?也是列占位符。编码

选择哪种语法均可以,可是前者更明确一些。

下面使用prepare()方法准备一个用于迭代执行的查询:

<?php
$pdo=new PDO($dsn,$user,$pwd);  // 链接数据库
$query="INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen";
$result=$pdo->prepare($query);
?>

上面的代码将查询准备好了。继续下面的操做。


执行准备查询——execute()方法

execute()方法负责执行准备好的查询。语法格式以下:

bool PDOStatement::execute([array input_parameters])

该方法须要有每次迭代执行中替换的输入参数。这能够经过两种方法实现:做为数组将值传递给方法,或者经过bindParam()方法把值绑定到查询中相应的变量名或位置偏移。

下面介绍第一种方法,第二种方法在bindParam()方法中介绍。

实例代码中准备了一条语句并经过execute()方法反复执行,每次使用不一样的参数:

<?php
$pdo=new PDO($dsn,$user,$pwd);  // 链接数据库
$query="INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen";
$result=$pdo->prepare($query);

$result->execute(array(':xuesheng'=>'赵天平',':yuwen'=>'90'));  // 执行一次
$result->execute(array(':xuesheng'=>'张冬雪',':yuwen'=>'115')); // 再执行一次
?>

下面经过使用bindParam()方法进行绑定来传递查询参数。


绑定参数——bindParam()方法

execute()方法中的input_parameters参数是可选的,虽然很方便,可是若是须要传递多个变量时,以这种方式提供数组会很快变得难以处理(当数组元素过多时,也就是当数据表中的列过多时,代码设计会变得特别难以阅读或出错)。使用bindParam()方法能够解决这个问题。语法格式以下:

boolean PDOStatement::bindParam(mixed parameter,mixed &variable[,int datatype
                                [,int length[,mixed driver_options]]])

parameter:当在prepare()方法中使用命名参数时,parameter是预处理语句中使用语法(例如:xuesheng)指定的列值占位符的名字;使用问号参数时,parameter是查询中列值占位符的索引偏移。

variable:该参数存储将赋给占位符的值。它按引用传递,由于结合准备存储过程使用此方法时,能够根据存储过程的某个动做修改这个值。

datatype:该参数显式地设置参数的数据类型,能够为如下值:

  • PDO_PARAM_BOOL:SQL BOOLEAN类型。
  • PDO_PARAM_INPUT_OUTPUT:参数传递给存储过程时使用此类型,所以,能够在过程执行后修改。
  • PDO_PARAM_INT:SQL INTEGER数据类型。
  • PDO_PARAM_NULL:SQL NULL数据类型。
  • PDO_PARAM_LOB:SQL大对象数据类型。
  • PDO_PARAM_STMT:PDOStatement对象类型,当前不可操做。
  • PDO_PARAM_STR:SQL CHAR、VARCHAR和其它字符串数据类型。

length:该参数指定数据类型的长度。只有当赋为PDO_PARAM_INPUT_OUTPUT数据类型时才须要这个参数。

driver_options:该参数用来传递任何数据库驱动程序特定的选项。

下面修改前面的实例,使用bindParam()方法来赋列值:

<?php
$pdo=new PDO($dsn,$user,$pwd);  // 链接数据库
$query="INSERT INTO tb_chengji SET xuesheng=:xuesheng,yuwen=:yuwen";
$result=$pdo->prepare($query);

$xuesheng='赵天平';
$yuwen='90';
$result->bindParam(':xuesheng',$xuesheng);
$result->bindParam(':yuwen',$yuwen);
$result->execute();

$xuesheng='张冬雪';
$yuwen='115';
$result->bindParam(':xuesheng',$xuesheng);
$result->bindParam(':yuwen',$yuwen);
$result->execute();
?>

若是使用问号参数,语句则以下所示:

$query="INSERT INTO tb_chengji SET xuesheng=?,yuwen=?";

所以对应的bindParam()方法调用以下:

$xuesheng='赵天平';
$yuwen='90';
$result->bindParam(1,$xuesheng);
$result->bindParam(2,$yuwen);
......
$xuesheng='张冬雪';
$yuwen='115';
$result->bindParam(1,$xuesheng);
$result->bindParam(2,$xuesheng);

实例

在执行下面的实例代码以前,tb_chengji数据表中的数据记录以下图所示:

tb_chengji数据表中原来的记录

执行下面的实例代码:

复制代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP PDO prepare()、execute()和bindParam()方法详解实例-www.baike369.com</title>
</head>
<body>
<?php
$dbms='mysql';
$dbname='db_xuesheng';
$user='root';
$pwd='1234';
$host='localhost';
$dsn="$dbms:host=$host;dbname=$dbname";
try{
  $pdo=new PDO($dsn,$user,$pwd);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  $query="INSERT INTO tb_chengji SET xuesheng = :xuesheng,yuwen = :yuwen,shuxue = :shuxue,yingyu = :yingyu";
  $result=$pdo->prepare($query);

  $result->execute(array(":xuesheng"=>"周一刚",":yuwen"=>"55",":shuxue"=>"80",":yingyu"=>"78"));
  $result->execute(array(":xuesheng"=>"胡伟",":yuwen"=>"107",":shuxue"=>"99",":yingyu"=>"113"));

  $xuesheng="孙维维";    // 能够接受<form>标签传递过来的值
  $yuwen="86";
  $shuxue="66";
  $yingyu="78";
  $result->bindParam(":xuesheng",$xuesheng);
  $result->bindParam(":yuwen",$yuwen);
  $result->bindParam(":shuxue",$shuxue);
  $result->bindParam(":yingyu",$yingyu);
  $result->execute();

// 能够屡次添加数据记录
  $xuesheng="王萍";
  $yuwen="116";
  $shuxue="45";
  $yingyu="69";
  $result->bindParam(":xuesheng",$xuesheng);
  $result->bindParam(":yuwen",$yuwen);
  $result->bindParam(":shuxue",$shuxue);
  $result->bindParam(":yingyu",$yingyu);
  $result->execute();

}catch(Exception $exception){
  echo $exception->getMessage();
}
?>
</body>
</html>

上面的实例执行一次代码,能够添加多条数据记录。固然,执行一次代码,也能够添加一条记录。

上面的实例代码,还能够写成下面的格式,效果是同样的:

复制代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP PDO prepare()、execute()和bindParam()方法详解实例-www.baike369.com</title>
</head>
<body>
<?php
$dbms='mysql';
$dbname='db_xuesheng';
$user='root';
$pwd='1234';
$host='localhost';
$dsn="$dbms:host=$host;dbname=$dbname";
try{
  $pdo=new PDO($dsn,$user,$pwd);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  $query="INSERT INTO tb_chengji SET xuesheng=?,yuwen=?,shuxue=?,yingyu=?";
  $result=$pdo->prepare($query);

  $result->execute(array("周一刚","55","80","78"));
  $result->execute(array("胡伟","107","99","113"));

  $xuesheng="孙维维";    // 能够接受<form>标签传递过来的值
  $yuwen="86";
  $shuxue="66";
  $yingyu="78";
  $result->bindParam(1,$xuesheng);
  $result->bindParam(2,$yuwen);
  $result->bindParam(3,$shuxue);
  $result->bindParam(4,$yingyu);
  $result->execute();

// 能够屡次添加数据记录
  $xuesheng="王萍";
  $yuwen="116";
  $shuxue="45";
  $yingyu="69";
  $result->bindParam(1,$xuesheng);
  $result->bindParam(2,$yuwen);
  $result->bindParam(3,$shuxue);
  $result->bindParam(4,$yingyu);
  $result->execute();
}catch(Exception $exception){
  echo $exception->getMessage();
}
?>
</body>
</html>

执行实例代码之后,tb_chengji数据表中的数据记录以下图所示:

执行实例代码后tb_chengji数据表中的数据记录


提示

当使用PHP中PDO的prepare()、execute()和bindParam()方法时,网页的编码必定要设置为utf-8:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

不然,将不能输入中文汉字数据。

相关文章
相关标签/搜索