转载处:http://www.cnblogs.com/xiaohuochai/p/6133353.html


定义

  在生成网页时,许多PHP脚本通常都会执行除参数之外,其他部分完全相同的查询语句,针对这种重复执行一个查询,每次迭代使用不同的参数情况,PDO提供了一种名为预处理语句(prepared statement)的机制。它可以将整个SQL命令向数据库服务器发送一次,以后只有参数发生变化,数据库服务器只需对命令的结构做一次分析就够了,即编译一次,可以多次执行。会在服务器上缓存查询的语句和执行过程,而只在服务器和客户端之间传输有变化的列值,以此来消除这些额外的开销。这不仅大大减少了需要传输的数据量,还提高了命令的处理效率。可以有效防止SQL注入,在执行单个查询时快于直接使用query()或exec()的方法,速度快且安全,推荐使用

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

准备语句

  重复执行一个SQL查询,通过每次迭代使用不同的参数,这种情况使用预处理语句运行效率最高。使用预处理语句,首先需要在数据库服务器中先准备好“一个SQL语句”,但并不需要马上执行。PDO支持使用“占位符”语法,将变量绑定到这个预处理的SQL语句中。另外,PDO几乎为所支持的所有数据库提供了命令占位符模拟,甚至可以为生来就不支持该概念的数据库模拟预处理语句和绑定参数。这是PHP向前迈进的积极一步,因为这样可以使开发人员能够用PHP编写“企业级”的数据库应用程序,而不必特别关注数据库平台的能力

  对于一个准备好的SQL语句,如果在每次执行时都要改变一些列值,这种情况必须使用“占位符”而不是具体的列值,或者只要有需要使用变量作为值的地方,就先使用占位符替代,准备好一个没有传值的SQL语句,在数据库服务器的缓存区等待处理,然后再去单独赋给占位符具体的值,再通过这个准备好的预处理语句执行。在PDO中有两种使用占位符的语法:“命令参数”和“问号参数”,使用哪一种语法看个人的喜好

  使用命名参数作为占位符的INSERT查询如下所示:

$dbh->prepare("INSERT INTO contactInto(name,address,phone)VALUES (:name,:address,:phone)");

  需要自定义一个字符串作为“命名参数”,每个命名参数需要冒号(:)开始,参数的命名一定要有意义,最好和对应的字段名称相同

  使用问号(?)参数作为占位符的INSERT查询如下所示:

$dbh->prepare("INSERT INTO contactInfo(name,address,phone) VALUES (?,?,?)");

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

绑定参数

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

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )

  绑定一个PHP变量到用作预处理的SQL语句中的对应命名占位符或问号占位符。不同于 PDOStatement::bindValue(),此变量作为引用被绑定,并只在PDOStatement::execute()被调用的时候才取其值

  parameter表示参数标识符(必须项)。对于使用命名占位符的预处理语句,应是类似:name形式的参数名。对于使用问号占位符的预处理语句,应是以1开始索引的参数位置

  variable(必须项)表示绑定到 SQL 语句参数的 PHP 变量名

  data_type(可选项)表示使用PDO::PARAM_*常量明确地指定参数的类型。要从一个存储过程中返回一个INOUT参数,需要为data_type参数使用按位或操作符去设置PDO::PARAM_INPUT_OUTPUT位,可以为以下值

PDO:PARAM_BOOL:表示boolean数据类型
PDO:PARAM_NULL:表示NULL数据类型
PDO:PARAM_INT:表示INT数据类型
PDO:PARAM_STR:表示字符串数据类型
PDO:PARAM_LOB:表示大对象数据类型

  length(可选项)表示数据类型的长度。为表明参数是一个存储过程的OUT参数,必须明确地设置此长度

  使用bindParam()方法分别绑定上对应的参数。查询中使用名字参数的绑定如下所示

$query = "INSERT INTO contactInfo (name,address,phone) VALUES (:name,:address,:phone)";
$stmt = $dbh->prepare($query);
$stmt->bindParam(":name",$name);
$stmt->bindParam(":address",$address);
$stmt->bindParam(":phone",$phone);
$name = '爱新觉罗';
$address = '东城';
$phone = '88888';

  查询中使用问号?参数的绑定如下所示

$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->bindParam("1",$name);
$stmt->bindParam("2",$address);
$stmt->bindParam("3",$phone);
$name = '司马';
$address = '西城';
$phone = '666';

执行查询

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

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->bindParam("1",$name);
$stmt->bindParam("2",$address);
$stmt->bindParam("3",$phone);
$name = '司马';
$address = '西城';
$phone = '666';
$stmt->execute(); $name = '曹操';
$address = '平谷';
$phone = '1';
$stmt->execute();
?>
<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (:name,:address,:phone)";
$stmt = $dbh->prepare($query);
$stmt->bindParam(":name",$name);
$stmt->bindParam(":address",$address);
$stmt->bindParam(":phone",$phone);
$name = '爱新觉罗';
$address = '东城';
$phone = '88888';
$stmt->execute();
?>

  如果只是要传递输入参数,并且有许多这样的参数要传递,那么通过在execute()方法中提供一个可选参数,该参数是由准备查询中的命名参数占位符组成的数组,这是第二种为预处理查询在执行中替换输入参数的方式。此语法可以活动对bindParam()的调用

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->execute(array("张飞",'延庆','3')); $query = "INSERT INTO contactInfo (name,address,phone) VALUES (:name,:address,:phone)";
$stmt = $dbh->prepare($query);
$stmt->execute(array(":name"=>"关羽",":address"=>"密云",":phone"=>"2"));
?>

  如果执行的是INSERT语句,并且数据表有自动增长的ID字段,可以使用PDO对象中的lastInsertId()方法获取最后插入数据表中的记录ID。如果需要查看其他DML语句是否执行成功,可以通过PDOStatement类对象中的rowCount()方法获取影响记录的行数

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->execute(array("孙权",'通州','123456'));
echo $dbh->lastInsertId(); $query = "UPDATE contactInfo SET name=? WHERE uid=?";
$stmt = $dbh->prepare($query);
$stmt->execute(array("天使","6"));
echo $stmt->rowCount();//1 $query = "DELETE FROM contactInfo WHERE name= ?";
$stmt = $dbh->prepare($query);
$stmt->execute(["孙权"]);
echo $stmt->rowCount();//11
?>

获取数据

  PDO的数据获取方法与其他数据库扩展都非常类似,只要成功执行SELECT查询,都会有结果集对象生成。不管是使用PDO对象中的query()方法,还是使用prepare()和execute()等方法结合的预处理语句,执行SELECT查询都会得到相同的结果集对象PDOStatement,都需要通过PDOStatement类对象中的方法将数据遍历出来

fetch()

  PDOStatement类中的fetch()方法可以将结果集中当前行的记录以某种方式返回,并将结果集指针移到下一行,当到达结果集末尾时返回FALSE,该方法的原型如下:

mixed PDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )

  第一个参数fetch_style(可选项),用于控制下一行如何返回给调用者。此值必须是 PDO::FETCH_* 系列常量中的一个,缺省为 PDO::ATTR_DEFAULT_FETCH_MODE 的值(默认为 PDO::FETCH_BOTH)

PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组
PDO::FETCH_BOTH(默认):返回一个索引为结果集列名和以0开始的列号的数组
PDO::FETCH_BOUND:返回 TRUE ,并分配结果集中的列值给 PDOStatement::bindColumn() 方法绑定的 PHP 变量。
PDO::FETCH_CLASS:返回一个请求类的新实例,映射结果集中的列名到类中对应的属性名。如果 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE),则类名由第一列的值决定
PDO::FETCH_INTO:更新一个被请求类已存在的实例,映射结果集中的列到类中命名的属性
PDO::FETCH_LAZY:结合使用PDO::FETCH_BOTH和PDO::FETCH_OBJ,创建供用来访问的对象变量名
PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组
PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象

  第二个参数cursor_orientation(可选项)表示对于一个PDOStatement对象表示的可滚动游标,该值决定了哪一行将被返回给调用者。此值必须是 PDO::FETCH_ORI_* 系列常量中的一个,默认为 PDO::FETCH_ORI_NEXT。要想让 PDOStatement 对象使用可滚动游标,必须在用 PDO::prepare() 预处理SQL语句时,设置 PDO::ATTR_CURSOR 属性为 PDO::CURSOR_SCROLL

  第三个参数offset(可选项)表示对于一个cursor_orientation参数设置为PDO::FETCH_ORI_ABS的PDOStatement对象代表的可滚动游标,此值指定结果集中想要获取行的绝对行号

  对于一个 cursor_orientation 参数设置为 PDO::FETCH_ORI_REL 的PDOStatement 对象代表的可滚动游标,此值指定想要获取行相对于调用 PDOStatement::fetch() 前游标的位置

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
//Array ( [uid] => 1 [0] => 1 [name] => 张三 [1] => 张三 [address] => 朝阳 [2] => 朝阳 [phone] => 123 [3] => 123 [email] => zs@aaa.com [4] => zs@aaa.com )
print_r($stmt->fetch());
echo "<br>";
//Array ( [uid] => 2 [0] => 2 [name] => 李四 [1] => 李四 [address] => 朝阳 [2] => 朝阳 [phone] => 123456789 [3] => 123456789 [email] => ls@aaa.com [4] => ls@aaa.com )
print_r($stmt->fetch());
echo "<br>";
?>
<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
/*
Array ( [0] => 1 [1] => 张三 [2] => 朝阳 [3] => 123 [4] => zs@aaa.com )
Array ( [0] => 2 [1] => 李四 [2] => 朝阳 [3] => 123456789 [4] => ls@aaa.com )
Array ( [0] => 3 [1] => 王五 [2] => 海淀 [3] => 15011113456 [4] => ww@aaa.com )
Array ( [0] => 4 [1] => 赵四 [2] => 海淀 [3] => 123456789 [4] => zx@aaa.com )
Array ( [0] => 5 [1] => 诸葛 [2] => [3] => 120120120 [4] => zg@aaa.com )
Array ( [0] => 6 [1] => 天使 [2] => [3] => 222 [4] => zg2@aaa.com )
Array ( [0] => 7 [1] => 司马 [2] => 西城 [3] => 666 [4] => )
Array ( [0] => 8 [1] => 曹操 [2] => 平谷 [3] => 1 [4] => )
Array ( [0] => 9 [1] => 爱新觉罗 [2] => 东城 [3] => 88888 [4] => )
Array ( [0] => 10 [1] => 张飞 [2] => 延庆 [3] => 3 [4] => )
Array ( [0] => 11 [1] => 关羽 [2] => 密云 [3] => 2 [4] => )
*/
while($row = $stmt->fetch(PDO::FETCH_NUM)){
print_r($row);
echo "<br>";
}
?>

  下面以表格的形式输出结果集

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
echo '<table border="1" >';
echo "<th>编号</th>";
echo "<th>姓名</th>";
echo "<th>地址</th>";
echo "<th>电话</th>";
echo "<th>邮箱</th>";
while(list($uid, $name, $address, $phone, $email) = $stmt -> fetch(PDO::FETCH_NUM)) {
echo '<tr>';
echo '<td>'.$uid.'</td>';
echo '<td>'.$name.'</td>';
echo '<td>'.$address.'</td>';
echo '<td>'.$phone.'</td>';
echo '<td>'.$email.'</td>';
echo '</tr>';
}
echo '</table>';
?>

fetchAll()

  fetchAll()方法与上一个方法fetch()类似,但是该方法只需要调用一次就可以获取结果集中的所有行,并赋给返回的二维数组。该方法的原型如下:

fetchAll([int fetch_style [,int column_index]])

  第一个参数fetch_style是可选项,以何种方式引用所获取的列取决于该参数。默认值为PDO::FETCH_BOTH,所有可用的值可以参考在fetch()方法中介绍的第一个参数的列表,还可以指定PDO::FETCH_COLUMN值,从结果集中返回一个包含单列的所有值

  第二个参数column_index是可选项,需要提供一个整数索引,当在fetchAll()方法的第一个参数中指定PDO::FETCH_COLUMN值时,从结果集中返回通过该参数提供的索引所指定列的所有值

/*
Array ( [0] => Array ( [uid] => 1 [0] => 1 [name] => 张三 [1] => 张三 [address] => 朝阳 [2] => 朝阳 [phone] => 123 [3] => 123 [email] => zs@aaa.com [4] => zs@aaa.com ) [1] => Array ( [uid] => 2 [0] => 2 [name] => 李四 [1] => 李四 [address] => 朝阳 [2] => 朝阳 [phone] => 123456789 [3] => 123456789 [email] => ls@aaa.com [4] => ls@aaa.com ) [2] => Array ( [uid] => 3 [0] => 3 [name] => 王五 [1] => 王五 [address] => 海淀 [2] => 海淀 [phone] => 15011113456 [3] => 15011113456 [email] => ww@aaa.com [4] => ww@aaa.com ) [3] => Array ( [uid] => 4 [0] => 4 [name] => 赵四 [1] => 赵四 [address] => 海淀 [2] => 海淀 [phone] => 123456789 [3] => 123456789 [email] => zx@aaa.com [4] => zx@aaa.com ) [4] => Array ( [uid] => 5 [0] => 5 [name] => 诸葛 [1] => 诸葛 [address] => [2] => [phone] => 120120120 [3] => 120120120 [email] => zg@aaa.com [4] => zg@aaa.com ) [5] => Array ( [uid] => 6 [0] => 6 [name] => 天使 [1] => 天使 [address] => [2] => [phone] => 222 [3] => 222 [email] => zg2@aaa.com [4] => zg2@aaa.com ) [6] => Array ( [uid] => 7 [0] => 7 [name] => 司马 [1] => 司马 [address] => 西城 [2] => 西城 [phone] => 666 [3] => 666 [email] => [4] => ) [7] => Array ( [uid] => 8 [0] => 8 [name] => 曹操 [1] => 曹操 [address] => 平谷 [2] => 平谷 [phone] => 1 [3] => 1 [email] => [4] => ) [8] => Array ( [uid] => 9 [0] => 9 [name] => 爱新觉罗 [1] => 爱新觉罗 [address] => 东城 [2] => 东城 [phone] => 88888 [3] => 88888 [email] => [4] => ) [9] => Array ( [uid] => 10 [0] => 10 [name] => 张飞 [1] => 张飞 [address] => 延庆 [2] => 延庆 [phone] => 3 [3] => 3 [email] => [4] => ) [10] => Array ( [uid] => 11 [0] => 11 [name] => 关羽 [1] => 关羽 [address] => 密云 [2] => 密云 [phone] => 2 [3] => 2 [email] => [4] => ) )
*/
print_r($stmt->fetchAll());

  下面以表格的形式输出结果集

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute(); echo '<table border="1" >';
echo "<th>编号</th>";
echo "<th>姓名</th>";
echo "<th>地址</th>";
echo "<th>电话</th>";
echo "<th>邮箱</th>";
$allRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($allRows as $row){
echo '<tr>';
echo '<td>'.$row['uid'].'</td>';
echo '<td>'.$row['name'].'</td>';
echo '<td>'.$row['address'].'</td>';
echo '<td>'.$row['phone'].'</td>';
echo '<td>'.$row['email'].'</td>';
echo '</tr>';
}
echo '</table>';
?>

  下面使用fetchAll()方法输出所有的姓名数组

$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
$row=$stmt->fetchAll(PDO::FETCH_COLUMN,1);
echo '所有联系人的姓名:';
//所有联系人的姓名:Array ( [0] => 张三 [1] => 李四 [2] => 王五 [3] => 赵四 [4] => 诸葛 [5] => 天使 [6] => 司马 [7] => 曹操 [8] => 爱新觉罗 [9] => 张飞 [10] => 关羽 )
print_r($row);

setFetchMode()

  PDOStatement对象中的fetch()和fetchAll()两个方法,获取结果数据的引用方式默认是一样的,既按列名索引又按列在行中的数值偏移(从0开始)索引的值数组,因为它们的默认模式都被设置为PDO::FETCH_BOTH值,如果计划使用其他模式来改变这个默认设置,可以在fetch()或fetchAll()方法中提供需要的模式参数。但如果多次使用这两个方法,在每次调用时都需要设置新的模式来改变默认的模式。这时就可以使用PDOStatement类对象中的setFetchMode()方法,在脚本页面的顶部设置一次模式,以后所有fetch()和fetchAll()方法的调用都将生成相应引用的结果集,减少了多次在调用fetch()方法时的参数录入

$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
echo '<table border="1" >';
echo "<th>编号</th>";
echo "<th>姓名</th>";
echo "<th>地址</th>";
echo "<th>电话</th>";
echo "<th>邮箱</th>";
$allRows = $stmt->fetchAll();
foreach($allRows as $row){
echo '<tr>';
echo '<td>'.$row['uid'].'</td>';
echo '<td>'.$row['name'].'</td>';
echo '<td>'.$row['address'].'</td>';
echo '<td>'.$row['phone'].'</td>';
echo '<td>'.$row['email'].'</td>';
echo '</tr>';
}
echo '</table>';

bindColumn()

  使用该方法可以将一个列和一个指定的变量名绑定,这样在每次使用fetch()方法获取各行记录时,会自动将相应的列值赋给该变量,但必须是在fetch()方法的第一个参数设置为PDO::FETCH_BOTH值时。bindColumn()方法的原型如下所示:

bindColumn(mixed column,mixed $param[,int type]);//设置绑定列值到变量上

  第一个参数column为必选项,可以使用整数的列偏移位置索引(索引值从1开始),或是列的名称字符串。第二个参数param也是必选项,需要传递一个引用,所以必须提供一个相应的变量名。第三个参数type是可选项,通过设置变量的类型来限制变量值,该参数支持的值和介绍bindParam()方法时提供的一样

<?php
try {
//创建对象
$dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
$query = "SELECT * FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
$stmt->bindColumn(1,$uid);
$stmt->bindColumn(2,$name);
$stmt->bindColumn(3,$departmentID);
$stmt->bindColumn('address',$address);
$stmt->bindColumn('phone',$phone);
$stmt->bindColumn(6,$email); $stmt->setFetchMode(PDO::FETCH_ASSOC);
echo '<table border="1" >';
echo "<th>编号</th>";
echo "<th>姓名</th>";
echo "<th>部门</th>";
echo "<th>地址</th>";
echo "<th>电话</th>";
echo "<th>邮箱</th>";
while($stmt->fetch()){
echo '<tr>';
echo '<td>'.$uid.'</td>';
echo '<td>'.$name.'</td>';
echo '<td>'.$departmentID.'</td>';
echo '<td>'.$address.'</td>';
echo '<td>'.$phone.'</td>';
echo '<td>'.$email.'</td>';
echo '</tr>';
}
echo '</table>';
?>

  除了可以通过上面几种方式获取数据表中记录信息外,还可以使用PDOStatement类对象的columnCount()方法获取数据表中字段的数量,并且可以通过PDOStatement类对象的getColumnMeta()方法获取具体列的属性信息

PDOStatement::getColumnMeta

  PDOStatement::getColumnMeta — 返回结果集中一列的元数据。参数column表示结果集中以0开始索引的列

array PDOStatement::getColumnMeta ( int $column )
$query = "SELECT * FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
echo $stmt->columnCount();//6
/*
array (size=7)
'native_type' => string 'INT24' (length=5)
'pdo_type' => int 2
'flags' =>
array (size=2)
0 => string 'not_null' (length=8)
1 => string 'primary_key' (length=11)
'table' => string 'contactInfo' (length=11)
'name' => string 'uid' (length=3)
'len' => int 8
'precision' => int 0
*/
var_dump($stmt->getColumnMeta(0));

大数据对象

  在进行项目开发时,有时会需要在数据库中在存储“大型”数据。大型对象可以是文本数据,也可以是二进制的图片、电影等。PDO允许在bindParam()或bindColumn()调用中通过使用PDO::PARAM_LOB类型代码来使用大型数据类型。PDO::PARAM_LOB告诉PDO将数据映射为流,所以可以使用PHP中的文件处理函数来操纵这样的数据

  下面将上传的图像插入到一个数据库

    $stmt =$dbh->prepare("insert into images(mimetype, data) values(?, ?)");
$stmt->bindParam(1, $_FILES['pic']['type']);
$fp = fopen($_FILES['pic']['tmp_name'], "rb");
//直接使用文件资源就可以入库,而不用读出文件,再插入
$stmt->bindparam(2, $fp, PDO::PARAM_LOB);
$stmt->execute();
fclose($fp);

  下面从数据库中读出一幅图像

    $stmt = $dbh->prepare("select mimetype, data from images where id=?");
$stmt -> execute(array(1));
list($mimetype, $data) = $stmt->fetch(PDO::FETCH_NUM);
header("Content-Type: {$mimetype}");
echo $data;

PHP基础知识之————PDO预处理语句的更多相关文章

  1. 前端学PHP之PDO预处理语句

    × 目录 [1]定义 [2]准备语句 [3]绑定参数[4]执行查询[5]获取数据[6]大数据对象 前面的话 本来要把预处理语句和前面的基础操作写成一篇的.但是,由于博客园的限制,可能是因为长度超出,保 ...

  2. php pdo预处理语句与存储过程

    很多更成熟的数据库都支持预处理语句的概念.什么是预处理语句?可以把它看作是想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制.预处理语句可以带来两大好处: 1.查询仅需解析(或预处理) ...

  3. PDO预处理语句规避SQL注入攻击

    所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存 ...

  4. PDO预处理语句

    1.造PDO对象$dsn = "mysql:dbname=mydb;host=localhost";$pdo = new PDO($dsn,"root",&qu ...

  5. PHP PDO 预处理语句与存储过程

    很多更成熟的数据库都支持预处理语句的概念. 什么是预处理语句?可以把它看作是想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制.预处理语句可以带来两大好处: 查询仅需解析(或预处理)一 ...

  6. C#基础知识---迭代器与Foreach语句

    一.Foreach语句简介 在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而如果一个集合要支持使用foreach语句来进行遍历,这个集合一般需要IEnumerable或IEnum ...

  7. MySQL数据库基础知识及优化

    MySQL数据库基础知识及优化必会的知识点,你掌握了多少? 推荐阅读: 这些必会的计算机网络知识点你都掌握了吗 关于数据库事务和锁的必会知识点,你掌握了多少? 关于数据库索引,必须掌握的知识点 目录 ...

  8. PHP中的PDO操作学习(二)预处理语句及事务

    今天这篇文章,我们来简单的学习一下 PDO 中的预处理语句以及事务的使用,它们都是在 PDO 对象下的操作,而且并不复杂,简单的应用都能很容易地实现.只不过大部分情况下,大家都在使用框架,手写的机会非 ...

  9. PDO 学习与使用 ( 二 ) PDO 数据提取 和 预处理语句

    以数据库 msg 为例,说明 PDO 的数据提取.预处理语句: mysql> show tables;+---------------+| Tables_in_msg |+----------- ...

随机推荐

  1. win8以上系统,设置英文为默认输入法

    说明:这里将添加“简体中文(美式键盘)”,也就是英文输入法,并设置为默认输入法. 1.打开控制面板—时钟.语言和区域—语言,点击“添加语言”,选择“英语”—打开,选择“英语(美国)” —添加. 2.选 ...

  2. 【Pro ASP.NET MVC 3 Framework】.学习笔记.7.SportsStore:购物车

    3 创建购物车 每个商品旁边都要显示Add to cart按钮.点击按钮后,会显示客户已经选中的商品的摘要,包括总金额.在购物车里,用户可以点击继续购物按钮返回product目录.也可以点击Check ...

  3. hobby

    如果把战争的原则凝缩为一个词,那就是集中. 人生有三把钥匙, 接受. 改变. 离开.不能接受,那就改变,不能改变,那就离开. 少问别人为什么,多问自己凭什么. 太平自古将军定,不许将军见太平

  4. MySQL start and stop

    一.本文说明 本实验主要是演示MySQL的四种启动方式,附带停止的操作. 二.mysqld mysqld is the MySQL server   mysqld reads options from ...

  5. Linux系统中为php添加pcntl扩展的方法

    1.首先看下 phpize命令 所在的目录  (ps:我的目录/usr/bin/phpize)如果没有找到的话 执行安装yum install php53_devel (ps:请注意自己的版本) 安装 ...

  6. yii2 批量插入or更新

    $sql1 = 'insert into business_ip (gid, name, area, belongName, belongArea, destIPv4, created, update ...

  7. poj1961 Period

    我们考虑KMP算法中fail失配指针的意义. 对于一个模式串(Pattern),位置i对应的失配指针fail[i]是那个位置: 这个位置满足的条件是,子串[0, fail[i])是位置i(不含)的后缀 ...

  8. Optimal Milking 分类: 图论 POJ 最短路 查找 2015-08-10 10:38 3人阅读 评论(0) 收藏

    Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 13968 Accepted: 5044 Case ...

  9. register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别

    register_chrdev:Linux2.6.30之前所用,不用定义cdev:但 如果是register_chrdev 注册的话,这个时候,分配的次设备号,是从0~255,这样子的话,就分配的范围 ...

  10. jquery简单插件到复杂插件(3)--顶部导航固定

    那个效果很多,比如hao123的头部 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...