Some time ago, I started researching PHP. I read some information about PDO and found it to be good. I organized and summarized it as development notes for future use. "PHP Development Notes Series (1) - PDO use".
PDO is the abbreviation of PHP Data Objects, which is a database access abstraction layer. PDO is a consistent interface for multiple databases. By analogy, what PDO does is similar to the function of the persistence layer framework (Hibernate, OpenJPA) in JAVA, providing a unified programming interface for heterogeneous databases, so that there is no need to use functions such as mysql_* and pg_*. No more writing your own "GenericDAO". PDO was released with PHP5.1, so the PHP5.2 and PHP5.3 we use are already available.
For convenience, we use MySQL5 for demonstration.
0. Establish experimental environment database and related tables
Sql code
- 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. Use PDO to access the database
The steps to access the database through PDO are: a) specify dsn, username, password, b) construct the PDO object through the settings in #a, The code is as follows:
Php code
- file:pdo-access.php
- url:http:
-
-
- $dsn = 'mysql:host=localhost;dbname=pdotest';
- $username = 'root';
- $passwd = 'password';
-
-
- 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();
- }
- ?>
Note: DSN is Data Source Name-data source name, which provides database connection information and includes three parts: PDO driver name (MySQL, SQLite, PostgreSQL, etc.), colon and driver-specific syntax. But under normal circumstances, it is difficult for us to remember these. You can download a php manual to check, or you can check it on the official website of php.
2. Use Query method to query data
Based on #1, after successfully connecting to the database, construct a SQL statement, call the query method to return the structure array, and use foreach To traverse the data results, the code is as follows:
Php代码
- file:pdo-query.php
- url:http:
-
-
- $dsn = 'mysql:host=localhost;dbname=pdotest';
- $username = 'root';
- $passwd = 'password';
-
- try {
- $dbh = new PDO($dsn, $username, $passwd);
- echo 'connect to database successfully!'."rn";
-
- $title = 'title1';
-
- $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方法的优势会更加明显。
There are not many steps to use the prepare and execute methods. a) Construct the SQL, b) Pass the SQL into the PDO->prepart method to get a PDOStatement object, 3) Call the execute method of the PDOStatement object, 4) Pass the PDOStatement->fetch Or PDOStatement->fetchObject to traverse the result set. The code is as follows:
Php code
- file:pdo-prepare-fetch.php
- url:http:
-
- $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!'."
";
-
-
- $sql = "SELECT * FROM blog WHERE title = :title";
-
- $stmt = $dbh->prepare($sql);
-
- $stmt->bindParam(":title", $title, PDO::PARAM_STR);
-
- $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();
- }
- ?>
In addition to using the above PDO::FETCH_ASSOC to return the associative array, you can also use the fetchObject method to return the result set object. The code is as follows:
Php代码
- file:pdo-prepare-fetch-object.php
- url:http:
-
- $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!'."
";
-
- $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 code
-
- …
- try {
- …
- } catch (Exception $e) {
- echo 'Errors occur when operation!'."
";
-
- echo $e->getMessage()."
";
-
- echo $e->getCode()."
";
-
- echo $e->getFile()."
";
-
- echo $e->getLine()."
";
-
- echo $e->getTraceAsString();
- }
- ?>
5. Use prepare and execute methods to insert/update data
The method is similar to the query in #3, except that the constructed SQL statement is an insert statement or update statement. The code is as follows :
Php代码
- file:pdo-prepare-insert.php
- url:http:
-
- $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!'."
";
-
-
- $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();
- }
- ?>
Php代码
- file:pdo-prepare-update.php
- url:http:
-
- $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!'."
";
-
-
- $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 ...,代码如下:
Php代码
- file:pdo-prepare-fetch-column.php
- url:http:
-
- $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!'."
";
-
-
- $sql = "SELECT COUNT(id) FROM blog";
- $stmt = $dbh->prepare($sql);
- $stmt->execute();
-
- 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语句即可,代码如下:
Php代码
- file:pdo-prepare-row-count.php
- url:http:
-
- $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!'."
";
-
- $sql = "DELETE FROM blog WHERE id=:id";
- $stmt = $dbh->prepare($sql);
- $stmt->bindParam(":id", $id);
- $stmt->execute();
-
- echo $stmt->rowCount()." rows affected!";
- } catch (Exception $e) {
- echo 'Errors occur when data operation!n';
- echo $e->getMessage();
- }
- ?>
8. 获得新插入行的ID值
为数据库表插入新数据行时,我们需要获得刚刚插入的新行的ID值,此时我们需要使用到PDO的lastInsertId()方法,代码如下:
Php代码
- file:pdo-prepare-last-insertid.php
- url:http:
-
- $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!'."
";
-
- $sql = "INSERT INTO blog(title) VALUES(:title)";
- $stmt = $dbh->prepare($sql);
- $stmt->bindParam(":title", $title);
- $stmt->execute();
-
- echo $dbh->lastInsertId();
- } catch (Exception $e) {
- echo 'Errors occur when query data!n';
- echo $e->getMessage();
- }
- ?>
9. 使用PDO进行事务管理
事务是进行程序开发时,保证数据ACID(可分性、一致性、独立性、持久性)的工具。要不全部成功,要不全部不成功,这样才能保证关联数据的保存能够达到预期的目的。下面使用PDO的Transaction来进行实验,进行多比数据插入,开启事务,第一句sql是可以正常插入,第二句sql插入出错,检查是否rollback。
Php代码
- file:pdo-prepare-transaction.php
- url:http:
-
- $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!'."
";
-
- $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命令传入即可。下面为了演示,只做了简单的调用。
Php code
- file:pdo-backup.php
- url:http:
-
- $username="root";
- $passwd="password";
- $dbname="pdotest";
- $file='d:/'.$dbname.'.sql';
-
- $cmd = "mysqldump -u".$username." -p".$passwd." ".$dbname. " >".$file;
//Execute backup command
system($cmd,$error);
- $error){
-
trigger_error("backup failed".$error);
-
}
?>
-
Adopt factory mode: Php code
- file:AbstractMySQLDump.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{
-
} -
-
- //Backup Logic
- public function backup(){
system(- $this->cmd, $error);
> // Determine whether there are errors and error logic -
if(- $error){
trigger_error(
"backup failure! command:".- $this->cmd." Error:".$error);
} -
} -
?> -
-
Php code
- file:MySQLDump_Win.php
-
- class MySQLDump_Win extends AbstractMySQLDump {
-
- //Override the constructor method of the parent class
- public function __construct($username, $passwd, $dbname, $file){
- $this->cmd = "mysqldump -u".$username." -p".$passwd." ".$dbname." > ".$file;
} -
} -
?> -
Php code
file:MySQLDumpTest.php -
url:http:- //localhost:88/pdo/MySQLDumpTest.php
- require_once 'AbstractMySQLDump.php';
-
- $username = "root";
- $passwd = "password";
- $dbname = "pdotest";
- $file = "d:/".$dbname.".sql";
-
- //Use factory method to generate backup class
- $dump = AbstractMySQLDump::factory($username, $passwd, $dbname, $file);
- //Execute the backup method of the backup class
- $dump->backup();
?> -
http://www.bkjia.com/PHPjc/820779.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/820779.htmlTechArticleSome time ago, I started researching PHP. I read some information about PDO and found it to be good. I organized and summarized it. Let's take it as a development note for future use, "PHP Development Notes Series...