PDO为PHP访问各类数据库定义了一个轻量级一致性的接口,无论什么数据库,都可以通过一致的方法执行查询和获取数据,而不用考虑不同数据库之间的差异,大大简化了数据库操作。使用PDO可以支持mysql、postgresql、oracle、mssql等多种数据库。

本文以基础讲解常用的PHP以PDO方式操作MySQL,包括常用的CURD语句执行,以及预处理语句和事务的应用。虽然很多朋友使用开发框架封装好了数据库操作层,或者使用ORM等不直接接触SQL语句,但是在一些小项目中可能会用到原生的数据库操作,所以虽然是基础但是很有用。

我们准备一张mysql数据表mycomments,这是一张常见的评论表。

首先创建PDO对象,建立与数据库服务器的连接。

PDO::setAttribute()用于设置属性,如上面的代码中就设置了使用异常模式处理错误。

如果我们不使用预处理语句,可以直接使用query()和exec()方法执行sql语句。

而实际开发中我们最常用的是预处理语句,简单的说预处理语句预先将sql命令分析一次,可以多次执行,提高了处理效率,而且能有效防止SQL注入。在执行单个查询时快于直接使用query()或exec()的方法,速度快且安全,所以强烈推荐使用预处理语句。

使用预处理语句处理时配套的方法是prepare()和execute()。

我们用预处理语句来查询符合条件的数据记录:

我们在sql语句中使用问号(?)参数作为占位符,使用bindParam()可以设置绑定参数值。

不过,如果有很多参数需要传递,我们最常用的是这样写:

在execute()方法中加入参数占位符数组,不使用?占位符可能更直观点。

fetch()返回查询结果中的一行数据,数据以数组形式返回,该方法可以带参数,其中参数默认为 PDO::FETCH_BOTH,即返回一个索引为结果集列名和以0开始的列号的数组,而常用的参数PDO::FETCH_ASSOC则返回一个索引为结果集列名的数组。

fetchAll()可以获取结果集中的所有行,并赋给返回的二维数组。和fetch()一样也可以带参数。

如查询表中用户id为2的所有数据,可能会有多行结果:

打印$row结果看下,是不是一个二维数组?

最常用的插入数据表的写法,如果有自增长id(一般必须有),使用lastInsertId()可以获取到插入成功后的id。

使用预处理更新数据,rowCount()返回影响行数,大于0即表示执行成功的记录数。

对于只有一个参数需要绑定的,可以使用问号?占位符。删除后同样使用rowCount()返回影响行数,大于0表示执行成功。

事务是确保数据库一致的机制,是一个或一系列的查询,作为一个单元的一组有序的数据库操作。如果组中的所有SQL语句都操作成功,则认为事务成功,事务则被提交。如果在事务的组中只有一个环节操作失败,事务也不成功,则整个事务将被回滚,该事务中所有操作都被取消。事务在开发中也经常用到,因为很多业务过程都包括多个步骤,如果任何一个步骤失败,则所有步骤都不应发生。

值得注意的是,如果要用到事务处理功能,你的MySQL应该使用InnoDB引擎或者其他支持事务的引擎,切不可以使用MyISAM引擎。

来看PDO事务处理实例:

上述代码中首先是启动一个事务,然后依次执行三条sql,然后提交事务。细心的同学可能会发现,在第2条sql中查询条件sid=2有误,因为我们在前面创建mycomments表的时候没有sid这个字段,所以在执行到第2条sql时就会出错,这个时候会抛出异常,使用try{}cache(){}语句即可捕获异常,于是就执行了回滚事务rollBack(),而并没有提交事务。换句话说就是上面的代码虽然第一条sql执行完了,但是最终执行不成功,数据库没有任何写入和更新。