PHP-PDO&PDO类&PDO核心类&封装PDO单例
1 PDO介绍 方法一:mysql扩展【这种方式php7已经淘汰】 方法二:mysqli扩展 方法三:PDO扩展
1.1 连接数据库方式 1.2 PDO介绍 PDO(PHP Data Object)扩展为PHP访问各种数据库提供了一个轻量级,一致性的接口。无论访问什么数据库,都可以通过一致性的接口去操作。
1.3 开启PDO扩展 开启PDO连接MySQL扩展
1 extension=php_pdo_mysql.dll
2 PDO核心类 1、PDO类:表示PHP和数据库之间的一个连接 2、PDOStatement 类 第一:表示执行数据查询语句(select ,show)后的相关结果集 第二:预处理对象 3、PDOException类:表示PDO的异常
3 实例化PDO对象 语法
1 __construct ($dsn ,用户名,密码)
3.1 DSN DSN:data source name,数据源名称,包含的是连接数据库的信息,格式如下:
1 dsn=数据库类型:host=主机地址;port=端口号;dbname=数据库名称;charset=字符集
数据库类型:
1 2 3 4 MySQL数据库 => mysql: oracle数据库 => oci: SQL Server =>sqlsrv: 具体驱动类型参见手册“PDO驱动”
3.2 实例化PDO 实例化PDO的过程就是连接数据库的过程
1 2 3 4 <?php $dsn ='mysql:host=localhost;port=3306;dbname=data;charset=utf8' ;$pdo =new PDO ($dsn ,'root' ,'root' );var_dump ($pdo );
3.3 注意事项 1、如果连接的是本地数据库,host可以省略
1 2 3 4 <?php $dsn ='mysql:port=3306;dbname=data;charset=utf8' ;$pdo =new PDO ($dsn ,'root' ,'root' );var_dump ($pdo );
2、如果使用的是3306端口,port可以省略
1 2 3 4 <?php $dsn ='mysql:dbname=data;charset=utf8' ;$pdo =new PDO ($dsn ,'root' ,'root' );var_dump ($pdo );
3、charset也省略,如果省略,使用的是默认字符编码
1 2 3 4 <?php $dsn ='mysql:dbname=data' ;$pdo =new PDO ($dsn ,'root' ,'root' );var_dump ($pdo );
4、dbname也可以省略,如果省略就没有选择数据库
1 2 3 4 <?php $dsn ='mysql:' ;$pdo =new PDO ($dsn ,'root' ,'root' );var_dump ($pdo );
5、host、port、dbname、charset不区分大小写,没有先后顺序
6、驱动名称不能省略,冒号不能省略(因为冒号是驱动名组成部分),数据库驱动只能小写
4 使用PDO 4.1 执行数据操作语句 方法:$pdo->exec($sql),执行数据增、删、改语句,执行成功返回受影响的记录数,如果SQL语句错误返回false。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?php $dsn ='mysql:host=localhost;port=3306;dbname=data;charset=utf8' ;$pdo =new PDO ($dsn ,'root' ,'root' );$sql ="update news set title='静夜思1' where ids in (3,4)" ;$rs =$pdo ->exec ($sql );if ($rs ){ echo 'SQL语句执行成功<br>' ; if (substr ($sql , 0 ,6 )=='insert' ) echo '自动增长的编号是:' .$pdo ->lastInsertId (),'<br>' ; else echo '受到影响的记录数是:' .$rs ,'<br>' ; }elseif ($rs ===0 ){ echo '数据没有变化<br>' ; }elseif ($rs ===false ){ echo 'SQL语句执行失败<br>' ; echo '错误编号:' .$pdo ->errorCode (),'<br>' ; echo '错误信息:' .$pdo ->errorInfo ()[2 ]; }
4.2 执行数据查询语句 方法:$pdo->query($sql),返回的是PDOStatement对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <?php $dsn ='mysql:dbname=data;charset=utf8' ;$pdo =new PDO ($dsn ,'root' ,'root' );$stmt =$pdo ->query ('select * from products' );foreach ($stmt as $row ){ echo $row ['proname' ],'-' ,$row ['proprice' ],'<br>' ; }
4.3 PDO操作事务 事务:是一个整体,要么一起执行,要么一起回滚
事务的特性:原子性,一致性,隔离性,永久性
需要将多个SQL语句作为一个整体执行,就需要使用到事务
语法
1 2 3 start transaction 或 begin 开启事务 commit 提交事务 rollback 回滚事务
小结:
1 2 3 $pdo ->beginTransaction () 开启事务$pdo ->commit () 提交事务$pdo ->rollBack () 回滚事务
4.4 PDO操作预处理 5 PDO异常处理 1 2 3 4 5 6 7 8 9 10 11 12 <?php try { $dsn ='mysql:dbname=data;charset=utf8' ; $pdo =new PDO ($dsn ,'root' ,'root' ); $pdo ->setAttribute (PDO::ATTR_ERRMODE , PDO::ERRMODE_EXCEPTION ); $pdo ->query ('select * from newsssssss' ); } catch (PDOException $ex ) { echo '错误信息:' .$ex ->getMessage (),'<br>' ; echo '错误文件:' .$ex ->getFile (),'<br>' ; echo '错误行号:' .$ex ->getLine (); }
小结:
1、PDOException是PDO的异常类
2、实例化PDO会自动抛出异常
3、其他操作不会抛出异常,需要设置PDO的异常模式
4、PDO异常模式
1 2 3 4 PDO::ERRMODE_EXCEPTION 抛出异常 PDO::ERRMODE_SILENT 中断 PDO::ERRMODE_WARNING 警告
6 单例模式封装MyPDO类 6.1 步骤 1、单例模式
2、初始化参数
3、连接数据库
4、执行增删改
5、执行查询
a)返回二维数组
b)返回一维数组
c)返回一行一列
6.2 代码实现 第一部分:单例、初始化参数、实例化PDO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <?php class MyPDO { private $type ; private $host ; private $port ; private $dbname ; private $charset ; private $user ; private $pwd ; private $pdo ; private static $instance ; private function __construct ($param ) { $this ->initParam ($param ); $this ->initPDO (); } private function __clone ( ) { } public static function getInstance ($param =array ( ) ) { if (!self ::$instance instanceof self ) self ::$instance =new self ($param ); return self ::$instance ; } private function initParam ($param ) { $this ->type=$param ['type' ]??'mysql' ; $this ->host=$param ['host' ]??'127.0.0.1' ; $this ->port=$param ['port' ]??'3306' ; $this ->dbname=$param ['dbname' ]??'data' ; $this ->charset=$param ['charset' ]??'utf8' ; $this ->user=$param ['user' ]??'root' ; $this ->pwd=$param ['pwd' ]??'root' ; } private function initPDO ( ) { try { $dsn ="{$this->type} :host={$this->host} ;port={$this->port} ;dbname={$this->dbname} ;charset={$this->charset} " ; $this ->pdo=new PDO ($dsn , $this ->user, $this ->pwd); } catch (PDOException $ex ) { echo '错误编号:' .$ex ->getCode (),'<br>' ; echo '错误行号:' .$ex ->getLine (),'<br>' ; echo '错误文件:' .$ex ->getFile (),'<br>' ; echo '错误信息:' .$ex ->getMessage (),'<br>' ; exit ; } } } $param =array (); $mypdo = MyPDO::getInstance ($param );var_dump ($mypdo );
第二部分:数据操作部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 <?php class MyPDO { private $type ; private $host ; private $port ; private $dbname ; private $charset ; private $user ; private $pwd ; private $pdo ; private static $instance ; private function __construct ($param ) { $this ->initParam ($param ); $this ->initPDO (); $this ->initException (); } private function __clone ( ) { } public static function getInstance ($param =array ( ) ) { if (!self ::$instance instanceof self ) self ::$instance =new self ($param ); return self ::$instance ; } private function initParam ($param ) { $this ->type=$param ['type' ]??'mysql' ; $this ->host=$param ['host' ]??'127.0.0.1' ; $this ->port=$param ['port' ]??'3306' ; $this ->dbname=$param ['dbname' ]??'data' ; $this ->charset=$param ['charset' ]??'utf8' ; $this ->user=$param ['user' ]??'root' ; $this ->pwd=$param ['pwd' ]??'root' ; } private function initPDO ( ) { try { $dsn ="{$this->type} :host={$this->host} ;port={$this->port} ;dbname={$this->dbname} ;charset={$this->charset} " ; $this ->pdo=new PDO ($dsn , $this ->user, $this ->pwd); } catch (PDOException $ex ) { $this ->showException ($ex ); exit ; } } private function showException ($ex ,$sql ='' ) { if ($sql !='' ){ echo 'SQL语句执行失败<br>' ; echo '错误的SQL语句是:' .$sql ,'<br>' ; } echo '错误编号:' .$ex ->getCode (),'<br>' ; echo '错误行号:' .$ex ->getLine (),'<br>' ; echo '错误文件:' .$ex ->getFile (),'<br>' ; echo '错误信息:' .$ex ->getMessage (),'<br>' ; } private function initException ( ) { $this ->pdo->setAttribute (PDO::ATTR_ERRMODE ,PDO::ERRMODE_EXCEPTION ); } public function exec ($sql ) { try { return $this ->pdo->exec ($sql ); } catch (PDOException $ex ) { $this ->showException ($ex , $sql ); exit ; } } public function lastInsertId ( ) { return $this ->pdo->lastInsertId (); } } $param =array (); $mypdo = MyPDO::getInstance ($param );if ($mypdo ->exec ("insert into news values (null,'11','1111',unix_timestamp())" )) echo '自动增长的编号是:' .$mypdo ->lastInsertId ();
第三部分:数据查询部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 <?php class MyPDO { ... private function fetchType ($type ) { switch ($type ){ case 'num' : return PDO::FETCH_NUM ; case 'both' : return PDO::FETCH_BOTH ; case 'obj' : return PDO::FETCH_OBJ ; default : return PDO::FETCH_ASSOC ; } } public function fetchAll ($sql ,$type ='assoc' ) { try { $stmt =$this ->pdo->query ($sql ); $type = $this ->fetchType ($type ); return $stmt ->fetchAll ($type ); } catch (Exception $ex ) { $this ->showException ($ex , $sql ); } } public function fetchRow ($sql ,$type ='assoc' ) { try { $stmt =$this ->pdo->query ($sql ); $type = $this ->fetchType ($type ); return $stmt ->fetch ($type ); } catch (Exception $ex ) { $this ->showException ($ex , $sql ); exit ; } } public function fetchColumn ($sql ) { try { $stmt =$this ->pdo->query ($sql ); return $stmt ->fetchColumn (); } catch (Exception $ex ) { $this ->showException ($ex , $sql ); exit ; } } } $param =array (); $mypdo = MyPDO::getInstance ($param );$list =$mypdo ->fetchColumn ('select count(*) from news' );echo '<pre>' ;var_dump ($list );
3、$stmt->bindParam()和$stmt->bindValue()区别
4、预处理的好处
2、参数占位符以冒号开头
1、?是位置占位符
小结:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php $dsn ='mysql:dbname=data;charset=utf8' ;$pdo =new PDO ($dsn ,'root' ,'root' );$stmt =$pdo ->prepare ("insert into bank values (:p1,:p2)" ); $cards =[ ['p1' =>'1003' ,'p2' =>500 ], ['p1' =>'1004' ,'p2' =>1000 ] ]; foreach ($cards as $card ){ $stmt ->execute ($card ); }
PDO中的预处理——参数占位符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php $dsn ='mysql:dbname=data;charset=utf8' ; $pdo =new PDO ($dsn ,'root' ,'root' ); $stmt =$pdo ->prepare ("insert into bank values (?,?)" ); $cards =[ ['1003' ,500 ], ['1004' ,100 ] ]; foreach ($cards as $card ){ $stmt ->execute ($card ); }
PDO中的预处理——位置占位符
1 execute 预处理名字 [using 变量]
执行预处理
1 prepare 预处理名字 from 'sql语句'
预处理语句:
预处理好处:编译一次多次执行,用来解决一条SQL语句多次执行的问题,提高了执行效率。
复习MySQL中预处理