18.6  PDO对预处理语句的支持

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

图18-6  预处理语句的机制

18.6.1  了解PDOStatement对象

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

表18-5  PDOStatement类中的全部成员方法(共18个)

18.6.2  准备语句

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

对于一条准备好的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类对象。

18.6.3  绑定参数

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

bindParam ( mixed parameter, mixed &variable [, int data_type   [, 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是可选项,通过该参数提供数据库驱动程序特定的选项。

将上一节中用两种占位符语法准备的SQL查询,使用bindParam()方法分别绑定对应的参数。查询中使用命名参数的绑定示例如下所示:

查询中使用问号(?)参数的绑定示例如下所示,并在绑定时通过第三个参数显式地指定数据类型。当然,使用名字参数一样可以通过第三个参数指定类型并通过第四个参数指定长度。

《细说PHP》第四版 样章 第18章 数据库抽象层PDO 7的更多相关文章

  1. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 1

    现在,如果你已经能熟练地使用MySQL客户端软件来操作数据库中的数据,就可以开始学习如何使用PHP来显示和修改数据库中的数据了.PHP提供了标准的函数来操作数据库.在PHP 5以上的版本中可以使用My ...

  2. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 12

    18.9  管理表books实例 在Web项目中,几乎所有模块都要和数据表打交道,而对表的管理无非就是增.删.改.查等操作,所以熟练掌握对表进行管理的这些常见操作是十分有必的.本例为了能更好地展示PD ...

  3. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 11

    18.8.3  完美分页类的代码实现 分页类的编写除了需要使用在18.8.2节中提供的可以操作的3个成员方法,还需要更多的成员,但其他的成员方法和成员属性只需要内部使用,并不需要用户在对象外部操作,所 ...

  4. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 4

    18.4  创建PDO对象 使用PDO在与不同数据库管理系统之间交互时,PDO对象中的成员的方法是统一各种数据库的访问接口,所以在使用PDO与数据库交互之前,首先要创建一个PDO对象.在通过构造方法创 ...

  5. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 10

    18.8  设计完美分页类 数据记录列表几乎出现在Web项目的每个模块中,假设一张表中有十几万条记录,我们不可能一次全都显示出来,当然也不能仅显示几十条.为了解决这样的矛盾,通常在读取时设置以分页的形 ...

  6. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 9

    18.7  PDO的事务处理 事务是确保数据库一致的机制,是一个或一系列的查询,作为一个单元的一组有序的数据库操作.如果组中的所有SQL语句都操作成功,则认为事务成功,那么事务被提交,其修改将作用于所 ...

  7. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 8-1

    18.6.5  获取数据 PDO的数据获取方法与其他数据库扩展非常类似,只要成功执行SELECT查询,都会有结果集对象生成.不管使用PDO对象中的query()方法,还是使用prepare()和exe ...

  8. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 8

    18.6.4  执行准备好的查询 当准备好查询并绑定了相应的参数后,就可以通过调用PDOStatement类对象中的execute()方法,反复执行在数据库缓存区准备好的语句了.在下面的示例中,向前面 ...

  9. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 6

    18.5.3  PDO的错误处理模式 PDO共提供了3种不同的错误处理模式,不仅可以满足不同风格的编程,也可以调整扩展处理错误的方式. 1.PDO::ERRMODE_SILENT 这是默认模式,在错误 ...

随机推荐

  1. DSP编程与调试总结

    (1)error: can't allocate .ebss, size 000c450d (page 1) in DXINTFRAM2 (avail: 00010000) error: errors ...

  2. python将字符串插入表中避免单双引号问题

    调用pymysql.escape_string('向数据库插入的数据') 例如: import pymysql str = 'as"sdf' print(pymysql.escape_str ...

  3. cURL无法访问TLS网站故障解决

    大多数人都厌烦使用老旧的系统,无论软件还是硬件.但有的时候又不得不困守其中,坚持延续着系统的寿命,或者还需要点几柱香,祈求神佛的护佑. Linux是一个模块化极好的操作系统,得益于此,当其中有组件落伍 ...

  4. 「Shimo使用指南」mac支持pptp协议的小软件

    Mac的好多小伙伴在访问网络设备时觉得远程连接不方便,例如ssh,***登陆都不是很方便,后来又安装了open*** forMac.ISSH等客户端,使用后发现不是很稳定,断线后很久都无法连接等缺点, ...

  5. react后台项目开发(一)

    1. 项目开发准备 描述项目 技术选型 api 接口(4部分:3请求{url,请求方式,请求参数格式}, 1响应数据格式)/ 接口文档/ 测试接口 2. 启动项目开发 使用react脚手架创建项目 开 ...

  6. Windows安装与配置—Node.js

    一.搭建环境 1.下载软件 打开下载链接:https://nodejs.org/zh-cn/ , 2.双击安装,指定安装位置 3.测试是否安装成功 用管理员方式打开命令行cmd,输入node -v如果 ...

  7. RAC数据库的ORA-27123: Unable To Attach To Shared Memory Segment Linux-x86_64 Error: 22: Invalid argument

    RAC数据库的 ORA-27123: Unable To Attach To Shared Memory Segment Linux-x86_64 Error: 22: Invalid argumen ...

  8. Linux平台安装python的psutil包

    在Linux平台下,pip install psutil 安装python psutil包,出现下面的错误: psutil/_psutil_common.c:9:20: fatal error: Py ...

  9. NXP恩智浦VEGA织女星开发板免费申请!

    前言 大概两周前申请了一块NXP恩智浦的开发板,今天终于收到了!在这里推荐给大家,官方网站刚上线一个月左右,目前申请的人还不算多,感兴趣的朋友可以申请一个,体验一下这个四核性能怪兽.大厂就是大气,包装 ...

  10. 基于STM32F429,Cubemx的SAI音频播放实验

    书接上文:https://www.cnblogs.com/feiniaoliangtiangao/p/11060674.html 和 https://www.cnblogs.com/feiniaoli ...