- 浏览: 72612 次
- 性别:
- 来自: 广州
最新评论
之前一段时间,开始了php的研究,看了关于PDO的一些资料,发现不错,整理和总结一下,作为开发笔记,留待日后使用,《PHP开发笔记系列(一)-PDO使用》。
PDO是PHP Data Objects的简称,是一种数据库访问抽象层。PDO是用于多种数据库的一致接口。类比的说,PDO做的事情类似于JAVA中的持久层框架(Hibernate、OpenJPA)的功能,为异构数据库提供一个统一的编程接口,这样就不必再使用mysql_*、pg_*这样的函数,也不必再写自己的"GenericDAO"了。PDO在PHP5.1的时候一起发布,所以我们用的PHP5.2、PHP5.3都已经可以使用。
为了方便,我们使用MySQL5来做演示。
0. 建立实验环境数据库及相关表
CREATE TABLE `blog` ( `id` int(10) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
1. 使用PDO访问数据库
通过PDO访问数据库的步骤是:a)指定dsn、username、password,b)通过#a中的设置构造PDO对象,代码如下:
file:pdo-access.php url:http://localhost:88/pdo/pdo-access.php <?php // 设置dsn、username、passwd $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; // 构造PDO对象 try { $dbh = new PDO($dsn, $username, $passwd); echo 'connect to database successfully!'; } catch (Exception $e) { echo 'Fail to connect to database!\n'; echo $e->getMessage(); } ?>
备注:DSN即Data Source Name-数据源名称,提供数据库的连接信息,包括三部分,PDO驱动名称(MySQL、SQLite、PostgreSQL等)、冒号和驱动特定的语法。但是一般情况下,我们都很难记住这些,可以下载个php manual查,也可以到php的官网查。
2. 使用Query方法查询数据
在#1的基础上,连接数据库成功后,构造SQL语句,调用query方法返回结构数组,通过foreach进行数据结果遍历,代码如下:
file:pdo-query.php url:http://localhost:88/pdo/pdo-query.php?title=title1 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; try { $dbh = new PDO($dsn, $username, $passwd); echo 'connect to database successfully!'."\r\n"; $title = 'title1'; // 构造SQL语句 $sql = "SELECT * FROM blog WHERE title = '".$title."'"; // 执行查询并遍历结果 foreach ($dbh->query($sql) as $row){ print $row['id']."\t"; print $row['title']."\t"; } } catch (PDOException $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
备注:一般情况下, 通过构造SQL语句的方法来进行query、update、insert、delete,都会需要指定where条件,因此不可避免的需要防止SQL注入的问题出现。
例如,正常情况下,当用户输入“title1”时,我们构造的sql语句会是SELECT * FROM blog WHERE title='title1',但是对SQL比较熟悉的用户会输入'OR id LIKE '%,此时我们构造的SQL就会变成SELECT * FROM blog where title='' OR id LIKE '%',这样整张blog 表中的数据都会被读取,因此需要避免,所以需要用到quote方法,把所有用户提供的数据进行转移,从而防止SQL注入的发生。使用quote方法后的sql为$sql = "SELECT * FROM blog WHERE title = ".$dbh->quote($title),转移出来后的sql是SELECT * FROM blog WHERE title = '\'OR id LIKE \'%',把所有的单引号(')都转移了。
3. 使用prepare和execute方法查询数据
如果我们用到的SQL查询是使用频率不高的查询,那么使用query或prepare和execute方法来查询都无太大差别,查询速度也不会差太远。两者不同的是,使用query时,php向数据库发送的sql,每执行一次都需要编译一次,而使用prepare和execute方法,则不需要,因此做大并发量的操作时,使用prepare和execute方法的优势会更加明显。
使用prepare和execute方法的步骤不多,a)构造SQL,b)将SQL传入PDO->prepart方法,得到一个PDOStatement对象,3)调用PDOStatement对象的execute方法,4)通过PDOStatement->fetch或PDOStatement->fetchObject遍历结果集。代码如下:
file:pdo-prepare-fetch.php url:http://localhost:88/pdo/pdo-prepare-fetch.php?title=title1 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; // 从请求获取title参数值 $title = $_GET['title']; try { $dbh = new PDO($dsn, $username, $passwd); echo 'connect to database successfully!'."<br/>"; // 构造SQL语句,使用绑定变量 $sql = "SELECT * FROM blog WHERE title = :title"; // 编译SQL $stmt = $dbh->prepare($sql); // 为绑定变量赋值 $stmt->bindParam(":title", $title, PDO::PARAM_STR); // 执行SQL $stmt->execute(); // 以联合数组方式获取结果,并遍历结果 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print $row['id']."\t"; print $row['title']."\t"; } } catch (PDOException $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
除了使用上面的PDO::FETCH_ASSOC返回联合数组外,还可以使用fetchObject方法,返回结果集对象,代码如下:
file:pdo-prepare-fetch-object.php url:http://localhost:88/pdo/pdo-prepare-fetch-object.php?title=title1 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; $title = $_GET['title']; try { $dbh = new PDO($dsn, $username, $passwd); echo 'connect to database successfully!'."<br/>"; $sql = "SELECT * FROM blog WHERE title = :title"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":title", $title, PDO::PARAM_STR); $stmt->execute(); // 以对象数组方式获取结果,并遍历结果 while ($row = $stmt->fetchObject()) { print $row->id."\t"; print $row->title."\t"; } } catch (Exception $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
4. 设置PDO的错误级别
PDO的错误级别分成PDO::ERRMODE_SILENT(默认)、PDO::ERRORMODE_WARNING、PDO::ERRORMODE_EXCEPTION三种。
PDO::ERRMODE_SILENT级别,当出现错误时,会自动设置PDOStatement对象的errorCode属性,但不进行任何其他操作,因此需要我们手工检查是否出现错误(使用empty($stmt->errorCode())),否则程序将继续走下去。
PDO::ERRORMODE_WARNING级别,基本与PDO::ERRMODE_SILENT一致,都是需要使用empty($stmt->errorCode())手工检查。
只需要在创建PDO对象后,加入以下代码即可:$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);或$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
PDO::ERRORMODE_WARNING级别,当出现错误时,系统将抛出一个PDOException,并设置errorCode属性,程序可以通过try{...}catch{...}进行捕捉,否则未catch的exception会导致程序中断,加入以下代码即可:$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
<?php ... try { ... } catch (Exception $e) { echo 'Errors occur when operation!'."<br/>"; // 获取Exception信息 echo $e->getMessage()."<br/>"; // 获取错误码 echo $e->getCode()."<br/>"; // 获取出错文件名 echo $e->getFile()."<br/>"; // 获取出错行 echo $e->getLine()."<br/>"; // 把异常以字符串返回 echo $e->getTraceAsString(); } ?>
5. 使用prepare和execute方法插入/更新数据
方法和#3中进行查询的差不多,只是构造的SQL语句是insert语句或update语句,代码如下:
file:pdo-prepare-insert.php url:http://localhost:88/pdo/pdo-insert.php?title=title11 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; $title = $_GET['title']; try { $dbh = new PDO($dsn, $username, $passwd); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo 'connect to database successfully!'."<br/>"; // 构造Insert语句 $sql = "INSERT INTO blog(title) VALUES(:title)"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":title", $title); $stmt->execute(); } catch (Exception $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
file:pdo-prepare-update.php url:http://localhost:88/pdo/pdo-update.php?id=1&title=title12 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; $id = $_GET['id']; $title = $_GET['title']; try { $dbh = new PDO($dsn, $username, $passwd); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo 'connect to database successfully!'."<br/>"; // 构造update语句 $sql = "UPDATE blog SET title=:title where id=:id"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":id", $id); $stmt->bindParam(":title", $title); $stmt->execute(); } catch (Exception $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
6. 获取返回的行数
使用#3中的prepare和execute方法,然后将sql语句改成count的,例如SELECT COUNT(id) FROM article ...,代码如下:
file:pdo-prepare-fetch-column.php url:http://localhost:88/pdo/pdo-prepare-fetch-column.php?id=1&title=title12 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; try { $dbh = new PDO($dsn, $username, $passwd); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); echo 'connect to database successfully!'."<br/>"; // 构造count语句 $sql = "SELECT COUNT(id) FROM blog"; $stmt = $dbh->prepare($sql); $stmt->execute(); // 使用fetchColumn获取0列值 echo $stmt->fetchColumn()." rows returned!"; } catch (Exception $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
7. 获取受影响的行数
使用#3中的prepare和execute方法,然后将SQL语句改成insert、update、delete语句即可,代码如下:
file:pdo-prepare-row-count.php url:http://localhost:88/pdo/pdo-prepare-row-count.php?id=1 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; $id = $_GET['id']; try { $dbh = new PDO($dsn, $username, $passwd); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); echo 'connect to database successfully!'."<br/>"; $sql = "DELETE FROM blog WHERE id=:id"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":id", $id); $stmt->execute(); // 获取update、insert、delete操作后影响的行数 echo $stmt->rowCount()." rows affected!"; } catch (Exception $e) { echo 'Errors occur when data operation!\n'; echo $e->getMessage(); } ?>
8. 获得新插入行的ID值
为数据库表插入新数据行时,我们需要获得刚刚插入的新行的ID值,此时我们需要使用到PDO的lastInsertId()方法,代码如下:
file:pdo-prepare-last-insertid.php url:http://localhost:88/pdo/pdo-prepare-last-insertid.php?title=title13 <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; $title = $_GET['title']; try { $dbh = new PDO($dsn, $username, $passwd); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo 'connect to database successfully!'."<br/>"; $sql = "INSERT INTO blog(title) VALUES(:title)"; $stmt = $dbh->prepare($sql); $stmt->bindParam(":title", $title); $stmt->execute(); // 获取上一个之行的insert语句插入的数据的id值 echo $dbh->lastInsertId(); } catch (Exception $e) { echo 'Errors occur when query data!\n'; echo $e->getMessage(); } ?>
9. 使用PDO进行事务管理
事务是进行程序开发时,保证数据ACID(可分性、一致性、独立性、持久性)的工具。要不全部成功,要不全部不成功,这样才能保证关联数据的保存能够达到预期的目的。下面使用PDO的Transaction来进行实验,进行多比数据插入,开启事务,第一句sql是可以正常插入,第二句sql插入出错,检查是否rollback。
file:pdo-prepare-transaction.php url:http://localhost:88/pdo/pdo-prepare-transaction.php <?php $dsn = 'mysql:host=localhost;dbname=pdotest'; $username = 'root'; $passwd = 'password'; try { $dbh = new PDO($dsn, $username, $passwd); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo 'connect to database successfully!'."<br/>"; // 开启事务 $dbh->beginTransaction(); $sql = "INSERT INTO blog(title) VALUES(:title)"; $stmt = $dbh->prepare($sql); $stmt->execute(array(':title'=>'insert title1')); $stmt->execute(array(':title'=>NULL)); // 提交事务 $dbh->commit(); } catch (Exception $e) { echo 'Errors occur when data operation!\n'; echo $e->getMessage(); // 回滚事务 $dbh->rollBack(); } ?>
10. 使用PDO进行数据库备份
使用system函数,将我们构造的mysqldump命令传入即可。下面为了演示,只做了简单的调用。
file:pdo-backup.php url:http://localhost:88/pdo/pdo-backup.php <?php $username="root"; $passwd="password"; $dbname="pdotest"; $file='d:/'.$dbname.'.sql'; // 构造备份命令 $cmd = "mysqldump -u".$username." -p".$passwd." ".$dbname." >".$file; // 执行备份命令 system($cmd,$error); if($error){ trigger_error("backup failed".$error); } ?>
采用工厂模式:
file:AbstractMySQLDump.php <?php require_once 'MySQLDump_Win.php'; abstract class AbstractMySQLDump { protected $cmd; abstract function __construct($username, $passwd, $dbname, $file); // 依据操作系统类型,使用工厂方法构造备份类 public static function factory($username, $passwd, $dbname, $file){ if(strtoupper(substr(PHP_OS, 0, 3))==='WIN'){ return new MySQLDump_Win($username, $passwd, $dbname, $file); }else{ // implement MySQLDump_NIX($username, $passwd, $dbname, $file); } } // 备份逻辑 public function backup(){ system($this->cmd, $error); // 判断是否出错及出错逻辑 if($error){ trigger_error("backup failure! command:".$this->cmd." Error:".$error); } } } ?>
file:MySQLDump_Win.php <?php class MySQLDump_Win extends AbstractMySQLDump { // 覆盖父类的构造方法 public function __construct($username, $passwd, $dbname, $file){ $this->cmd = "mysqldump -u".$username." -p".$passwd." ".$dbname." > ".$file; } } ?>
file:MySQLDumpTest.php url:http://localhost:88/pdo/MySQLDumpTest.php <?php require_once 'AbstractMySQLDump.php'; $username = "root"; $passwd = "password"; $dbname = "pdotest"; $file = "d:/".$dbname.".sql"; // 使用工厂方法生成备份类 $dump = AbstractMySQLDump::factory($username, $passwd, $dbname, $file); // 执行备份类的backup方法 $dump->backup(); ?>
本文地址: http://ryan-d.iteye.com/blog/1543225
- pdo.zip (7.3 KB)
- 下载次数: 26
发表评论
-
php curl in windows configuration
2012-09-11 11:32 0Just an additional note for Win ... -
PHP开发笔记系列(九)- 数组(四)
2012-06-24 23:13 1552经过《PHP开发笔记系列(九)- 数组(一)》 、《 ... -
PHP开发笔记系列(九)- 数组(三)
2012-06-24 16:10 1819写了两篇关于Php数组的日常使用,本篇《PHP开发笔记 ... -
PHP开发笔记系列(九)- 数组(二)
2012-06-23 23:22 1910昨晚临睡前写完了《PHP开发笔记系列(九)- 数组( ... -
PHP开发笔记系列(九)- 数组(一)
2012-06-22 22:34 1561最近在做项目的时候,经常需要用到关联数组的处理,发现P ... -
php 正则表达式
2012-06-15 12:10 0php 正则表达式 -
PHP XML处理
2012-06-15 11:47 0PHP XML处理 -
PHP开发笔记系列(十)- 电子邮件
2012-06-01 17:05 0Mail在应用程序中经常会使用到,例如注册成功后的账号 ... -
PHP开发笔记系列(八)- 上传与下载
2012-06-18 09:26 1944最近由于项目需要,在GZBGY进行了闭关,与同行的De ... -
PHP开发笔记系列(XAMPP+PhpEclipse+XDebug)
2012-05-29 21:51 1944第一篇:《PHP开发 ... -
PHP开发笔记系列(七)- 压缩与解压缩
2012-06-06 20:27 3527压缩与解压缩,在一般的web应用程序中可能用得不 ... -
PHP开发笔记系列(六)- 内置FTP函数
2012-06-04 08:57 1657FTP是我们经常用到的一种服务器,能够用来接收第三方系 ... -
PHP开发笔记系列(五)- INI文件解释
2012-06-01 15:52 1949在JAVA开发中,我 ... -
PHP开发笔记系列(四)-文件操作
2012-05-30 20:32 2230对于一般的web应用程序,数据会保存在数据库表中,但是 ... -
PHP开发笔记系列(三)-日期与时间
2012-05-29 19:53 3870前两篇完成了 《P ... -
PHP开发笔记系列(二)-字符串使用
2012-05-29 11:29 1625经过了《PHP开发笔记系列(一)-PDO使用 ...
相关推荐
### PHP PDO 学习笔记详解 #### 一、PDO简介 PDO(PHP Data Objects...综上所述,PDO作为PHP 5及更高版本中的数据库访问扩展,不仅简化了数据库操作,还提高了代码的安全性和可维护性,是PHP开发中不可或缺的一部分。
PHP(PHP: Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适用于Web开发。在PHP5中,PDO(PHP Data Objects)扩展提供了一种通用的、轻量级的、面向对象的方式来访问各种数据库。PDO为开发者提供了...
PDO 提供了一系列方法来配置连接行为,其中 `PDO::setAttribute()` 方法用于设置连接的属性。下面列出了一些常用的属性及其用途: - **PDO::ATTR_CASE** - `PDO::CASE_LOWER`: 将列名强制转换为小写。 - `PDO::...
**PDO (PHP Data Object)**是PHP提供的一种数据访问接口,用于与各种数据库系统进行交互。它的主要目的是提供一个数据抽象层,使得开发人员能够在不同类型的数据库之间轻松切换,而无需更改大量的代码。PDO通过自动...
在PHP开发笔记中,我们可以期待以下主题的详细讲解: 1. **基础语法**:包括变量声明、数据类型、控制结构(条件语句、循环语句)、函数定义与调用、字符串和数组的操作等。 2. **面向对象编程**:类与对象的概念...
- PHP(Hypertext Preprocessor,原名Personal Home Page)是一种广泛使用的开源服务器端脚本语言,特别适合Web开发,并且可以嵌入到HTML文档中。 - 主要目标是允许Web开发者快速编写动态网页。 - **发展历程**:...
- PDO(PHP Data Objects):介绍PDO的安装和使用,连接数据库,执行SQL查询,处理结果集。 - MySQLi扩展:对比PDO,了解MySQLi的使用方式。 - SQL语句:学习SELECT, INSERT, UPDATE, DELETE等基本SQL操作。 8. ...
- **连接数据库**:使用`mysqli_connect()`或`PDO`对象连接到MySQL数据库。 - **创建数据库和表**:通过执行SQL语句来创建新的数据库或表。 - **插入数据**:使用`INSERT INTO`语句向表中添加新记录。 - **查询数据*...
《韩顺平PHP从入门到精通笔记》是一份详尽的PHP学习资源,由知名IT教育专家韩顺平精心编撰。这份笔记涵盖了从基础到高级的PHP编程知识,旨在帮助初学者逐步掌握PHP编程技能,并对有经验的开发者提供深入理解和提升的...
- `--with-pdo-mysql=/opt/mysql`:启用PDO MySQL驱动。 - `--enable-xml`:启用XML支持。 - `--enable-mcrypt`:启用加密功能。 - `--with-mbstring`:启用多字节字符串支持。 - `--enable-zip`:启用ZIP支持...
【PHP实例开发源码-minIsay php笔记程序.zip】是一个包含PHP编程实践的源代码包,主要用于学习和理解PHP在实际应用中的运用。这个压缩包可能包含了一个名为"minIsay"的简单PHP笔记应用程序,它能帮助用户记录、管理...
【标题】"基于PHP的minIsayphp笔记程序源码.zip"揭示了这是一个使用PHP编程语言开发的笔记应用程序。PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适合于Web开发,可以嵌入到HTML中使用。这个...
数据库交互是Web开发中的关键部分,笔记会讲解如何使用PHP连接MySQL等数据库,执行SQL语句,处理查询结果,并介绍PDO(PHP Data Objects)和mysqli扩展,以实现更安全、高效的数据库操作。 此外,笔记还会涉及错误...
《韩顺平PHP笔记大全》是一份全面涵盖PHP编程语言的教育资源,由知名讲师韩顺平精心编撰。这份笔记集合共149集,旨在为初学者和进阶者提供一个系统化的学习路径,帮助他们掌握PHP的核心概念和技术。 首先,让我们从...
通过这份笔记,我们可以了解到一系列关键知识点,以下将逐一展开。 1. **面向对象编程**:在PHP5中,面向对象编程(OOP)得到了极大的加强。第八章可能就介绍了类、对象、继承、封装和多态等基本概念。类是对象的...
- PDO(PHP Data Objects):介绍PDO扩展,以及如何使用PDO连接数据库,执行SQL语句。 - MySQLi:讲解mysqli扩展,包括预处理语句、事务处理等。 10. **Web应用开发** - $_GET、$_POST、$_REQUEST:理解HTTP请求...
- **注意事项**:MySQLi 或 PDO_MySQL 推荐用于新的开发项目,因为它们提供了更多的功能,并且 mysql_ 扩展已经被废弃。 #### 五、is_dir() 函数 - **功能**:Is_dir() 函数用于检测指定的文件是否是一个目录。 - ...
PHP(Hypertext Preprocessor,超文本预处理器)是一种广泛使用的开源服务器端脚本语言,尤其适合Web开发,可以嵌入到HTML中使用。这份"PHP学习笔记"涵盖了PHP的基础知识、进阶概念以及可能的实际应用,对于想要深入...
PHP FexBook v1.0 Beta 是一个基于PHP编程语言开发的应用程序实例,它可能是类似于Facebook的一个社交网络平台的早期版本。这个源码提供了深入理解PHP在构建大型Web应用时如何处理用户交互、数据存储、页面渲染等...