欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PDO预处理语句PDOStatement对象使用总结

程序员文章站 2023-03-26 10:36:44
pdo对预处理语句的支持需要使用pdostatement类对象,但该类对象并不是通过new关键字实例化出来的,而是通过pdo对象中的prepare()方法,在数据库服务器中...

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

复制代码 代码如下:

pdostatement::bindcolumn — 绑定一列到一个 php 变量
pdostatement::bindparam — 绑定一个参数到指定的变量名
pdostatement::bindvalue — 把一个值绑定到一个参数
pdostatement::closecursor — 关闭游标,使语句能再次被执行。
pdostatement::columncount — 返回结果集中的列数
pdostatement::debugdumpparams — 打印一条 sql 预处理命令
pdostatement::errorcode — 获取跟上一次语句句柄操作相关的 sqlstate
pdostatement::errorinfo — 获取跟上一次语句句柄操作相关的扩展错误信息
pdostatement::execute — 执行一条预处理语句
pdostatement::fetch — 从结果集中获取下一行
pdostatement::fetchall — 返回一个包含结果集中所有行的数组
pdostatement::fetchcolumn — 从结果集中的下一行返回单独的一列。
pdostatement::fetchobject — 获取下一行并作为一个对象返回。
pdostatement::getattribute — 检索一个语句属性
pdostatement::getcolumnmeta — 返回结果集中一列的元数据
pdostatement::nextrowset — 在一个多行集语句句柄中推进到下一个行集
pdostatement::rowcount — 返回受上一个 sql 语句影响的行数
pdostatement::setattribute — 设置一个语句属性
pdostatement::setfetchmode — 为语句设置默认的获取模式。

1、准备语句

重复执行一个sql查询,通过每次迭代使用不同的参数,这种情况使用预处理语句运行效率最高。使用预处理语句,首先需要在数据库服务器中先准备好“一个sql语句”,但并不需要马上执行。pdo支持使用“占位符”语法,将变量绑定到这个预处理的sql语句中。对于一个准备好的sql语句,如果在每次执行时都要改变一些列值,这种情况必须使用“占位符号”而不是具体的列值。在pdo中有两种使用占位符的语法:“命名参数”和“问号参数”,使用哪一种语法要看个人的喜好。

使用命名参数作为占位符的insert插入语句:

复制代码 代码如下:

$dbh->prepare(“insert into contactinfo(name,address,phone) values(:name,:address,:phone)”);

需要自定义一个字符串作为“命名参数”,每个命名参数需要冒号(:)开始,参数的命名一定要有意义,最好和对应的字段名称相同。
使用问号(?)参数作为占位符的insert插入语句:
复制代码 代码如下:

$dbh->prepare(“insert into contactinfo(name,address,phone) values(?,?,?)”);

问号参数一定要和字段的位置顺序对应。不管是使用哪一种参数作为占位符构成的查询,或是语句中没有用到占位符,都需要使用pdo对象中的prepare()方法,去准备这个将要用于迭代执行的查询,并返回pdostatement类对象。

2、绑定参数

当sql语句通过pdo对象中的prepare()方法在数据库服务器端准备好了以后,如果使用了占位符,就需要在每次执行时替换输入的参数。可以通过pdostatement对象中的bindparam()方法,把参数变量绑定到准备好的占位符上(位置或名字要对应)。方法bindparame()的原型如下所示:

复制代码 代码如下:

bool pdostatement::bindparam ( mixed $parameter , mixed &$variable [, int $data_type = pdo::param_str [, int $length [, mixed $driver_options ]]] )

第一个参数parameter是必选项,如果在准备好的查询中占位符语法使用名字参数,那么将名字参数字符串作为bindparam()方法的第一个参数提供。如果占位符语法使用问号参数,那么将准备好的查询中列值占位符的索引偏移量,作为该方法的第一个参数。

第二个参数variable也是可选项,提供供给第一个参数所指定占位符的值。因为该参数是按引用传递的,所以只能提供变量作为参数,不能直接提供数值。

第三个参数data_type是可选项,为当前被绑定的参数设置数据类型。可以为以下值。

pdo::param_bool 代表boolean数据类型。
pdo::param_null 代表sql中的null类型。
pdo::param_int 代表sql中的integer数据类型。
pdo::param_str 代表sql中的char、varchar和其他字符串数据类型。
pdo::param_lob 代表sql中大对象数据类型。

第四个参数length是可选项,用于指定数据类型的长度。

第五个参数driver_options是可选项,通过该参数提供任何数据库驱动程序特定的选项。
使用命名参数作为占位符的参数绑定示例:

复制代码 代码如下:

<?php
//...省略pdo连接数据库代码
$query = "insert into contactinfo (name,address,phone) values(:name,:address,:phone)";
$stmt = $dbh->prepare($query);          //调用pdo对象中的prepare()方法
 
$stmt->blinparam(':name',$name);        //将变量$name的引用绑定到准备好的查询名字参数":name"中
$stmt->blinparam(':address',$address);
$stmt->blinparam(':phone',phone);
//...
?>

使用问号(?)作为占位符的参数绑定示例:

复制代码 代码如下:

<?php
//...省略pdo连接数据库代码
$query = "insert into contactinfo (name,address,phone) values(?,?,?)";
$stmt = $dbh->prepare($query);          //调用pdo对象中的prepare()方法
 
$stmt->blinparam(1,$name,pdo::param_str);        //将变量$name的引用绑定到准备好的查询名字参数":name"中
$stmt->blinparam(2,$address,pdo::param_str);
$stmt->blinparam(3,phone,pdo::param_str,20);
//...
?>

3、执行准备语句

当准备语句完成,并绑定了相应的参数后,就可以通过调用pdostatement类对象中的execute()方法,反复执行在数据库缓存区准备好的语句了。在下面的示例中,向前面提供的contactinfo表中,使用预处理方式连续执行同一个insert语句,通过改变不同的参数添加两条记录。如下所示:

复制代码 代码如下:

<?php
try {
     $dbh = new pdo('mysql:dbname=testdb;host=localhost', $username, $passwd);
}catch (pdoexception $e){
    echo '数据库连接失败:'.$e->getmessage();
    exit;
}
 
$query = "insert into contactinfo (name,address,phone) values(?,?,?)";
$stmt = $dbh->prepare($query);
 
$stmt->blinparam(1,$name);     
$stmt->blinparam(2,$address);
$stmt->blinparam(3,phone);
 
$name = "赵某某";
$address = "海淀区中关村";
$phone = "15801688348";
 
$stmt->execute();           //执行参数被绑定后的准备语句
?>

如果你只是要传递输入参数,并且有许多这样的参数要传递,那么你会觉得下面所示的快捷方式语法非常有帮助。是通过在execute()方法中提供一个可选参数,该参数是由准备查询中的命名参数占位符组成的数组,这是第二种为预处理查询在执行中替换输入参数的方式。此语法使你能够省去对$stmt->bindparam()的调用。将上面的示例做如下修改:
复制代码 代码如下:

<?php
//...省略pdo连接数据库代码
$query = "insert into contactinfo (name,address,phone) values(?,?,?)";
$stmt = $dbh->prepare($query);
 
//传递一个数组为预处理查询中的命名参数绑定值,并执行一次。
$stmt->execute(array("赵某某","海淀区","15801688348"));
?>

另外,如果执行的是insert语句,并且数据表中有自动增长的id字段,可以使用pdo对象中的lastinsertid()方法获取最后插入数据表中的记录id。如果需要查看其他dml语句是否执行成功,可以通过pdostatement类对象中的rowcount()方法获取影响记录的行数。