|

楼主 |
发表于 2020-9-22 21:46:09
|
显示全部楼层
本帖最后由 why 于 2020-10-8 20:49 编辑
第16章 数据库抽象曾pdo
先说一下pdo连接数据库报错的问题:
数据库连接失败:could not find driver
首先php.ini开启以下几项
extension=php_pdo.dll
extension=php_pdo_firebird.dll
extension=php_pdo_mysql.dll
其次是代码不能出错,再一个主要代码的大小写问题,因为我把代码里边的mysql大写了,导致始终报这个错,搞了几个小时
- <?PHP
- $dsn='mysql:host=localhost;dbname=bookstore'; //连接mysql数据库dsn
- $user='root'; //数据库用户名
- $password='root'; //数据库密码
- try{
- $dbh=new PDO($dsn,$user,$password);
- echo '连接成功'; //连接成功输出
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage(); //失败返回错误
- }
- ?>
复制代码
输出结果:
连接成功
在创建pdo对象时,把dsn字符串放在另一个本地文件中
新建一个mysql.txt放在PHP脚本同一个目录下,mysql.txt内容如下:
mysql:host=localhost;dbname=bookstore //注意这段内容不能有空白字符尤其注意结尾不能有空格或换行符
- <?PHP
- try{
- //file:///这是读取本地文件的格式,但只能读取绝对地址,这里我们获取到PHP脚本的当前目录组合成一个绝对地址供file:///使用
- $dbh=new PDO('uri:file:///'.dirname(__FILE__).'\mysql.txt','root','root');
- echo '连接成功'; //连接成功输出
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage(); //失败返回错误
- }
- ?>
复制代码
从php.ini文件加载dsn信息,php.ini添加如下信息:
[PDO]
pdo.dsn.mysqlpdo="mysql:host=localhost;dbname=bookstore";
- <?PHP
- try{
- $dbh=new PDO('mysqlpdo','root','root');
- echo '连接成功'; //连接成功输出
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage(); //失败返回错误
- }
- ?>
复制代码
设置pdo连接的属性:
- <?PHP
- //设置持久连接的选项作为最后一个参数,可以一起设置多个元素
- $opt=array(PDO::ATTR_PERSISTENT=>true); //把true赋值给数组元素PDO::ATTR_PERSISTENT,PDO::ATTR_PERSISTENT默认为false,表示不持久连接
- try{
- $dbh=new PDO('mysqlpdo','root','root',$opt);
- echo '连接成功'; //连接成功输出
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage(); //失败返回错误
- }
- ?>
复制代码
getattribute()函数,获取数据库连接对象的一个属性
- <?PHP
- //设置持久连接的选项作为最后一个参数,可以一起设置多个元素
- $opt=array(PDO::ATTR_PERSISTENT=>true); //把true赋值给数组元素PDO::ATTR_PERSISTENT,PDO::ATTR_PERSISTENT默认为false,表示不持久连接
- try{
- $dbh=new PDO('mysqlpdo','root','root',$opt);
- echo '连接成功<br>'; //连接成功输出
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage(); //失败返回错误
- exit;
- }
- echo "POD是否关闭自动提交功能:".$dbh->getattribute(PDO::ATTR_AUTOCOMMIT).'<br>'; //$dbh引用PDO::ATTR_AUTOCOMMIT成员,成员中值为false时关闭
- echo "\n当前PDO的错误处理的模式:".$dbh->getattribute(PDO::ATTR_ERRMODE).'<br>'; //$dbh引用PDO::ATTR_ERRMODE成员,成员PDO::ATTR_ERRMODE为设置错误处理模式
- echo "\n表示段字符的大小写转换:".$dbh->getattribute(PDO::ATTR_CASE).'<br>'; //$dbh引用PDO::ATTR_ERRMODE成员,成员PDO::ATTR_ERRMODE为设置错误处理模式
- echo "\n与连接状态相关特有信息:".$dbh->getattribute(PDO::ATTR_CONNECTION_STATUS).'<br>'; //$dbh引用PDO::ATTR_ERRMODE成员,成员PDO::ATTR_CONNECTION_STATUS包含数据库特有的与连接状态有关的信息
- echo "\n空字符串转换为SQL的null:".$dbh->getattribute(PDO::ATTR_ORACLE_NULLS).'<br>'; //$dbh引用PDO::ATTR_ORACLE_NULLS成员,成员PDO::ATTR_ORACLE_NULLS将返回的空字符串转换为SQL的null
- //echo "\n应用程序提前获取数据大小:".$dbh->getattribute(PDO::ATTR_PERSISTENT).'<br>'; //$dbh引用PDO::ATTR_PREFETCH成员,成员PDO::ATTR_PREFETCH设置应用程序提前获取的数据大小,以k字节位单位,这个参数显示驱动不支持,具体为啥不支持不清楚
- echo "\n与数据库特有的服务器信息:".$dbh->getattribute(PDO::ATTR_SERVER_INFO).'<br>'; //$dbh引用PDO::ATTR_AUTOCOMMIT成员,成员PDO::ATTR_AUTOCOMMIT包含与数据库特有的服务器信息
- echo "\n数据库服务器版本号信息:".$dbh->getattribute(PDO::ATTR_SERVER_VERSION).'<br>'; //$dbh引用PDO::ATTR_SERVER_VERSION成员,成员PDO::ATTR_SERVER_VERSION包含与数据库服务器版本号有关的信息
- echo "\n数据库客户端版本号信息:".$dbh->getattribute(PDO::ATTR_CLIENT_VERSION).'<br>'; //$dbh引用PDO::ATTR_CLIENT_VERSION成员,成员PDO::ATTR_CLIENT_VERSION包含与数据库客户端版本号有关的信息
- ?>
复制代码
输出结果:
- 连接成功
- POD是否关闭自动提交功能:1
- 当前PDO的错误处理的模式:0
- 表示段字符的大小写转换:0
- 与连接状态相关特有信息:localhost via TCP/IP
- 空字符串转换为SQL的null:0
- 与数据库特有的服务器信息:Uptime: 2070 Threads: 1 Questions: 29 Slow queries: 0 Opens: 110 Flush tables: 1 Open tables: 16 Queries per second avg: 0.014
- 数据库服务器版本号信息:5.7.26
- 数据库客户端版本号信息:5.0.51a
复制代码
setattribute()函数需要两个参数,第一个参数提供pdo对象特定的属性名,第二个参数则是为这个指定的属性赋一个值,如:
$dbh->getattribute(PDO::ATTR_ERRMODE,PDO::ATTR_ERRMODE_EXCEPTION); //设置抛出异常处理错误
pdo在某种程度上是对类型不可知的,因此它喜欢将任何数据都表示为字符串,而不是将其转换为整数或双精度类型
pdo一共提供了三种不同的错误处理模式,不仅可以满足不同风格的编程,也可以调整扩展处理错误的方式
PDO::ERRMODE_SILENT:这是默认模式,在错误发生时不进行任何操作,PDO将只设置错误代码,可以通过PDO对象中的errorcode()和errorinfo()方法对语句和数据库对象进行检查
PDO::ERRMODE_WARNING:除了设置错误代码以外,PDO还将发出一条PHP传统的E_WARNING消息,可以使用常规PHP错误处理程序捕获该警告,该模式的设置如下:
$dbh->setattribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); //设置警告模式处理错误报告
PDO::ERRMODE_EXCEPTION:除了设置错误代码以外,PDO还将抛出一个PDOException,并设置其属性,以反映错误代码和错误信息.这种设置在调用中也很有用,因为它会放大脚本中产生错误的地方,从而可以非常快速地指出代码中有问题的潜在区域.该模式的设置方法如下:
$dbh->setattribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); //设置抛出异常模式处理错误
使用PDO执行sql语句
先用PHP创建contactinfo表,并写入数据:
- <?PHP
- $link=mysql_connect('localhost','root','root');
- if(!$link){
- die('连接失败:'.mysql_error());
- }else{
- if(mysql_select_db('testdb',$link)===false){ //为后续的MySQL扩展函数的操作选定一个默认的数据库,它相当于sql命令的use testdb,如果失败创建数据库
- if(mysql_query("CREATE DATABASE testdb",$link)){
- mysql_select_db('testdb',$link);
- }
- }
- }
- //不加以下两行数据库会出现乱码
- mysql_query("set character set 'utf8'");//读库
- mysql_query("set names 'utf8'");//写库
- // 使用 sql 创建数据表,把部门id设为唯一索引,防止数据重复插入
- $result=mysql_fetch_row(mysql_query("show tables like 'contactinfo'")); //查询contactinfo表是否存在
- if(empty($result)!==false){ //如果表contactinfo不存在,则创建表
- mysql_query("CREATE TABLE contactinfo ( #创建表contact
- uid mediumint(8) unsigned not null auto_increment, #联系人ID
- name varchar(50) not null, #姓名
- departmentid char(3) not null unique, #部门编号
- address varchar(80) not null, #联系地址
- phone varchar (20), #联系电话
- email varchar (100), #联系人电子邮件
- PRIMARY KEY(uid) #设置用户id为主键
- )ENGINE=MYISAM DEFAULT CHARSET=utf8 COLLATE utf8_general_ci");
- }
-
-
-
- //插入的5条insert语句声明为一个字符串
- $insert="insert into contactinfo(name,departmentid,address,phone,email)values
- ('高某某','D01','海淀区','15801688338','gmm@51kakawo.com'),
- ('洛某某','D02','朝阳区','15801681234','lmm@51kakawo.com'),
- ('峰某某','D03','东城区','15801689876','fmm@51kakawo.com'),
- ('王某某','D04','西城区','15801681357','wmm@51kakawo.com'),
- ('陈某某','D05','昌平区','15801682468','cmm@51kakawo.com')";
- //使用MySQL_query()函数发送insert语句,如果成功返回true,失败则返回false
- $result=MySQL_query($insert);
- if($result&&MySQL_affected_rows()>0){
- echo "数据记录插入成功,最后一条插入的数据记录ID为:".MySQL_insert_id()."<br>";
- }else{
- echo "插入记录失败,错误号:".MySQL_errno().",错误原因:".MySQL_error()."<br>";
- }
-
- MySQL_close($link); //关闭与MySQL服务器建立的连接
- ?>
复制代码
浏览器输出结果:
数据记录插入成功,最后一条插入的数据记录ID为:1
MySQL输出结果:
mysql> select * from contactinfo;
+-----+-----------+--------------+-----------+-------------+------------------+
| uid | name | departmentid | address | phone | email |
+-----+-----------+--------------+-----------+-------------+------------------+
| 1 | 高某某 | D01 | 海淀区 | 15801688338 | gmm@51kakawo.com |
| 2 | 洛某某 | D02 | 朝阳区 | 15801681234 | lmm@51kakawo.com |
| 3 | 峰某某 | D03 | 东城区 | 15801689876 | fmm@51kakawo.com |
| 4 | 王某某 | D04 | 西城区 | 15801681357 | wmm@51kakawo.com |
| 5 | 陈某某 | D05 | 昌平区 | 15801682468 | cmm@51kakawo.com |
+-----+-----------+--------------+-----------+-------------+------------------+
5 rows in set (0.00 sec)
如果刷新页面就会出错,因为departmentid被设为了唯一索引,不允许重复出现
使用pdo::exec()方法
当执行insert,update和delete等没有结果集的查询时,使用pdo对象中的exec()方法去执行.该方法成功执行后,将返回受影响的行数.注意该方法不能用于select查询:
<?PHP
try{
$dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root');
}catch(pdoexception $e){
echo '数据库连接失败:'.$e->getmessage();
exit;
}
$query="UPDATE contactinfo SET phone='15801680168' where name='高某某'";
//使用exec()方法可以执行insert,update,delete等
$affected=$dbh->exec($query);
if($affected){
echo '数据表contactinfoinfo中受影响的行数为:'.$affected;
}else{
print_r ($dbh->errorinfo());
}
?>
浏览器返回结果:
Array ( [0] => 00000 )
返回了个错误,MySQL也没有更改成功,但为什么没有更改成功不清楚
在下边的案例中query()方法乱码,我给链接数据库的时候增加了第4个参数,然后这个exec()方法同样也增加了第4个参数,指定以utf8操作数据库,然后这段代码正常了,想了一下应该是update提供的命令在送入数据库后编码格式不一样导致查找不到表里的数据,现在浏览器输出结果如下:
数据表contactinfoinfo中受影响的行数为:1
MySQL输出结果如下:
mysql> select * from contactinfo;
+-----+-----------+--------------+-----------+-------------+------------------+
| uid | name | departmentid | address | phone | email |
+-----+-----------+--------------+-----------+-------------+------------------+
| 1 | 高某某 | D01 | 海淀区 | 15801680168 | gmm@51kakawo.com |
| 2 | 洛某某 | D02 | 朝阳区 | 15801681234 | lmm@51kakawo.com |
| 3 | 峰某某 | D03 | 东城区 | 15801689876 | fmm@51kakawo.com |
| 4 | 王某某 | D04 | 西城区 | 15801681357 | wmm@51kakawo.com |
| 5 | 陈某某 | D05 | 昌平区 | 15801682468 | cmm@51kakawo.com |
+-----+-----------+--------------+-----------+-------------+------------------+
5 rows in set (0.00 sec)
数据库也操作成功
2.使用pdo::query()方法
当执行返回结果集的select查询时,或者所影响的行数无关紧要时,应当使用pdo对象中的query()方法,如果该方法执行指定的查询,则返回一个pdostatement对象.如果使用了query()方法,并想了解获取的数据总素,可使用pdostatement对象中的rowcount()方法获取:
- <?PHP
- header('Content-type:text/html; charset=utf-8');
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8")); //第4个参数指定以uft8格式连接数据库,要不然浏览器返回的数据会乱码
- $dbh->setattribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
- $query="select name,phone,email from contactinfo where departmentid='D01'";
-
- try{
- //执行select查询,并返回pdostatement对象
- $pdostatement=$dbh->query($query);
- echo "一共从表中获取到".$pdostatement->rowcount()."条记录:\n";
- foreach($pdostatement as $row){
- echo $row['name']."\t";
- echo $row['phone']."\t";
- echo $row['email']."\t";
- }
- }catch(pdoexception $e){
- echo $e->getmessage();
- }
- ?>
复制代码
浏览器返回结果:
一共从表中获取到1条记录: 高某某 15801680168 gmm@51kakawo.com
pdo::prepare()和pdostatement()两个方法,当同一个查询需要多次执行时(有时需要迭代传入不同的值),使用预处理语句的方式来实现效率会更高.使用pdo对象中的prepare()方法去准备一个将要执行的查询,再使用pdostatement对象中的execute()方法来执行
在生成网页时,需要PHP脚本通常都会执行参数以外,其他部分完全相同的查询语句,针对这种重复执行一个查询,每次迭代使用不同的参数情况,pdo提供了一种名为预处理语句(prepare statement)的机制.
重复执行一个sql查询,通过每次迭代使用不同的参数,这种情况使用预处理语句运行效率最高.使用预处理语句,首先需要在数据库服务器中先准备好"一个sql语句",但并不需要马上执行.pdo支持使用"占位符"语法,将变量绑定到这个预处理sql语句中.另外.pdo几乎为所支持的所有数据库提供了命令占位符模拟,甚至可以为生来就不支持该概念的数据库模拟预处理语句和绑定参数
对于一个准备好的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类对象
当sql语句通过pdo对象总的prepare()方法,在数据库服务器端准备好之后,如果使用了占位符,就需要在每次执行时替换输入的参数.可以通过pdostatement对象中的bindparam()方法,把参数变量绑定到准备好的占位符上(位置或名字要对应),方法bindparam()的原型如下:
bindparam(参数1,参数2,参数3,参数4,参数5)
参数1是必填的,指定占位符语法中使用的名字参数,或者(?)参数的顺序值
参数2也是必填的,提供赋值给第一个参数的指定占位符值
参数3是可选填的,显示地为当前绑定的参数设置数据类型
参数4是可选填的,用于指定数据类型的长度
参数5是可选题的,通过该参数提供任何数据库驱动程序特定的选项
如上例中命名参数的写法如下:
bindparam(':name',$name); //将变量$name的引用绑定到准备好的查询名字参数":name"中
问号参数的写法如下:
bindparam(1,$name,PDO:: PARAM_STR); //将变量$name绑定到查询中的第1个问号参数中,并设置当前绑定数据类型为char,varchar和其他类型字符串
将上一节中使用的两种占位符语法准备的sql查询,用bindparam()方法分别绑定上对应的参数,查询中使用名字参数绑定示例如下所示:
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- $query="INSERT INTO contactinfo(name,address,phone)VALUES(:name,:address,:phone)";
- $stmt=$dbh->prepare($query); //调用pdo对象中的prepare()方法
- //第一个参数需要对应占位符号?的顺序
- $stmt->bindParam(':name',$name); //将变量$name的引用绑定到准备好的查询名字参数':name'中
- $stmt->bindParam(':address',$address); //将变量$address的引用绑定到准备好的查询名字参数':address'中
- $stmt->bindParam(':phone',$phone); //将变量$phone的引用绑定到准备好的查询名字参数':phone'中
- $name="张某某"; //声明第一个参数变量mame的值
- $address="北京海淀区中关村"; //声明第一个参数变量mame的值
- $phone="15801688988"; //声明第一个参数变量mame的值
- ?>
复制代码
查询中使用?参数的绑定示例如下所示:
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- $query="INSERT INTO contactinfo(name,address,phone)VALUES(?,?,?)";
- $stmt=$dbh->prepare($query); //调用pdo对象中的prepare()方法
- //第二个参数需要按引用传递,索引需要变量作为参数
- $stmt->bindParam(1,$name,pdo::param_str); //将变量$name的引用绑定到准备好的查询名字参数':name'中
- $stmt->bindParam(2,$address,pdo::param_str); //将变量$address的引用绑定到准备好的查询名字参数':address'中
- $stmt->bindParam(3,$phone,pdo::param_str,20); //将变量$phone的引用绑定到准备好的查询名字参数':phone'中
- $name="张某某"; //声明第一个参数变量mame的值
- $address="北京海淀区中关村"; //声明第一个参数变量mame的值
- $phone="15801688988"; //声明第一个参数变量mame的值
- ?>
复制代码
执行准备好的查询
当准备好查询并绑定了相应的参数后,就可以通过调用pdostatement类对象中的execute()方法,反复执行在数据库缓存区准备好的语句了,在下面的示例中,向前面提供的contactinfo表中,使用预处理方式连续执行同一个insert语句,通过改变不同的参数添加两条记录.如下所示
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- $query="INSERT INTO contactinfo(name,address,phone)VALUES(?,?,?)";
- $stmt=$dbh->prepare($query); //调用pdo对象中的prepare()方法
- //第二个参数需要按引用传递,索引需要变量作为参数
- $stmt->bindParam(1,$name); //将变量$name的引用绑定到准备好的查询名字参数':name'中
- $stmt->bindParam(2,$address); //将变量$address的引用绑定到准备好的查询名字参数':address'中
- $stmt->bindParam(3,$phone); //将变量$phone的引用绑定到准备好的查询名字参数':phone'中
- $name="赵某某"; //声明第一个参数变量mame的值
- $address="北京海淀区中关村"; //声明第一个参数变量mame的值
- $phone="15801688348"; //声明第一个参数变量mame的值
- $stmt->execute(); //执行参数被绑定值后的准备语句
- $name="孙某某"; //声明第一个参数变量mame的值
- $address="宣武区"; //声明第一个参数变量mame的值
- $phone="15801688698"; //声明第一个参数变量mame的值
- $stmt->execute(); //再次执行参数被绑定值后的准备语句,插入第二天语句
- ?>
复制代码
以上代码可以正常执行,但是数据库并没有被插入数据
如果只是要传递输入参数,并且有许多这样的参数要传递,那么你会觉得下面所示的快捷方式语法非常有帮助.是通过在execute()方法中提供一个可选参数,该参数是由准备查询中的命名参数占位符组成的数组,这是第二种为预处理查询在执行中替换输入参数的方式.此语法使你能够省去对$stmt->bindparam()的调用,将上面的示例做如下修改:
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- $query="INSERT INTO contactinfo(name,address,phone)VALUES(:name,:address,:phone)";
- $stmt=$dbh->prepare($query); //调用pdo对象中的prepare()方法
- //传递一个数组为预处理查询中的命名参数绑定值,并执行一次
- $stmt->execute(array(":name"=>"赵某某",":address"=>"海淀区",":phone"=>"15801688348"));
- //再次传递一个数组为预处理查询中的命名参数绑定值,并执行第二处插入数据
- $stmt->execute(array(":name"=>"孙某某",":address"=>"宣武区",":phone"=>"15801688698"));
- ?>
复制代码
上例是使用名字参数去准备好一个sql语句,则调用execute()方法时就必须传递一个关联数组,并且这个管关联数组的每个下标名称都要和命名参数名称一一对应(可以不使用名称前缀":"),数组中的值才能对应的替换sql语句中的命名参数.如果使用的是?参数,则需要传递一个索引数组,数组中每个值的位置都要对应每个问号参数.将上面的示例片段做如下修改:
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- $query="INSERT INTO contactinfo(name,address,phone)VALUES(?,?,?)";
- $stmt=$dbh->prepare($query); //调用pdo对象中的prepare()方法
- //传递一个数组为预处理查询中的问号参数绑定值,并执行一次
- $stmt->execute(array("赵某某","海淀区","15801688348"));
- //再次传递一个数组为预处理查询中的问号参数绑定值,并执行第二处插入数据
- $stmt->execute(array("孙某某","宣武区","15801688698"));
- ?>
复制代码
另外如果指向的是insert语句,并且数据表有自动增长的id字段,可以使用pdo对象汇总的lastinsertid()方法获取最后插入数据表中的记录id.如果需要查看其他dml语句是否执行成功,可以通过pdostatement类对象中的rowcount()方法获取影响记录的行数
获取数据
pdo的数据获取方法与其他数据库扩展都非常类似,只要成功执行select查询,都会有结果集对象生成,不管是使用pdo对象中的query()方法,还是使用prepare()和execute()等方法结合的预处理语句,执行select查询都会得到相同的结果集对象pdostatement.都需要通过pdostatement类对象中的方法将数据遍历出来,下面介绍pdostatement类中常见的几个获取结果集数据的方法
1.fetch()方法
pdostatement类中的fetch()方法可以将结果集中当前行的记录以某种方式返回,并将结果集指针移至下一行,当到达结果集末尾时返回false.该方法的原型如下:
fetch([int fetch_style[,int cursor_orientation[,int cursor_offset]]]) //返回结果集的下一行
第一个参数fetch_style是可选项,获取的一行数据记录中,各列的引用方式取决于这个参数如何设置.可以使用的设置有以下6种.
pdo::fetch_assoc:从结果集中获取以列名为索引的关联数组
pdo::fetch_num:从结果集中获取一个以列在杭后中的数值偏移为所以的值数组
pdo::fetch_both:这是默认值,包含上面两种数组
pdo::fetch_obj:从结果集当前行的记录中获取其属性对应各个列名的一个对象
pdo::fetch_bound:使用fetch()返回true,并将获取的列值赋值给在bindparam()方法中指定的相应变量
pdo::fetch_lazy:创建关联数组和索引数组,以及包含列属性的一个对象,从而可以在这三种接口中任选一种.
第二个参数cursor_orientation是可选项,用来确定当对象时一个可滚动的游标时应当获取那一行
第三个参数cursor_offset也是可选项,需要提供一个整数值,表示要获取的行相对于当前游标位置的偏移
在下面的示例中,使用pdo对象query()方法执行select查询,获取联系人信息表contactinfo中的信息,并返回pdostatement类对象作为结果集.然后就通过fetch()方法结合while循环遍历数据,并以HTML表格的形式输出.代码如下所示:
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- echo '<table border="1" align="center" width=90%>';
- echo '<caption><h1>联系人信息表</h1></caption>';
- echo '<tr bgcolor="#cccccc">';
- echo '<th>UID</th><th>姓名</th><th>联系地址</th><th>联系电话</th><th>电子邮件</th>';
- //使用query方式执行select语句,建议使用prepare()和execute()形式执行语句
- $stmt=$dbh->query("select uid,name,address,phone,email from contactinfo"); //调用pdo对象中的prepare()方法
- //以pdo::fetch_num式获取索引并遍历
- while(list($uid,$name,$address,$phone,$email)=$stmt->fetch(PDO::FETCH_NUM)){ //fetch()参数必须是大写
- echo '<tr>'; //输出每行的开始标记
- echo '<td>'.$uid.'</td>'; //从结果数组中获取uid
- echo '<td>'.$name.'</td>'; //从结果数组中获取name
- echo '<td>'.$address.'</td>'; //从结果数组中获取address
- echo '<td>'.$phone.'</td>'; //从结果数组中获取phone
- echo '<td>'.$email.'</td>'; //从结果数组中获取email
- echo '</tr>';
- }
- echo '</table>'; //输出表格结束标记
- ?>
复制代码
HTML输出结果如下:
fetchall()方法
fetchall()方法与上一个方法fetch()类似,但是该方法只需要调用一次就可以获取结果集中的所有行,并赋值给返回的数组(二维).该方法的原型如下:
fetchall([int fetch_style[,int column_index]]) //一次调用返回结果集中所有行
第一个参数fetch_style是可选项,以何种方式引用所获取的列取决于该参数.默认值为PDO::FETCH_BOTH,所有可用的值可以残酷在fetch()方法中介绍的第一个参数的列表,还可以指定PDO::FETCH_COLUMN值,从结果集汇中返回一个包含单列的所有值
第二个参数column_index是可选项,需要提供一个整数索引,当在fetchall()方法的第一个参数中指定PDO::FETCH_COLUMN值时,从结果集中返回通过该参数提供的索引所指定的所有值.fetchall()方法的应用示例如下所示:
- <?PHP
- try{
- $dbh=new pdo('mysql:dbname=testdb;host=localhost','root','root',array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
- }catch(pdoexception $e){
- echo '数据库连接失败:'.$e->getmessage();
- exit;
- }
- echo '<table border="1" align="center" width=90%>';
- echo '<caption><h1>联系人信息表</h1></caption>';
- echo '<tr bgcolor="#cccccc">';
- echo '<th>UID</th><th>姓名</th><th>联系地址</th><th>联系电话</th><th>电子邮件</th>';
- $stmt=$dbh->prepare("select uid,name,address,phone,email from contactinfo"); //调用pdo对象中的prepare()方法
- $stmt->execute();
- $allrows=$stmt->fetchall(PDO::FETCH_ASSOC);
- foreach($allrows as $row){ //遍历获取到的所有行数组$allrows
- echo '<tr>'; //输出每行的开始标记
- echo '<td>'.$row['uid'].'</td>'; //从结果数组中获取uid
- echo '<td>'.$row['name'].'</td>'; //从结果数组中获取name
- echo '<td>'.$row['address'].'</td>'; //从结果数组中获取address
- echo '<td>'.$row['phone'].'</td>'; //从结果数组中获取phone
- echo '<td>'.$row['email'].'</td>'; //从结果数组中获取email
- echo '</tr>';
- }
- echo '</table>'; //输出表格结束标记
- //以下是在fetchall()方法中使用两个特别参数的演示示例
- $stmt->execute();
- $row=$stmt->fetchall(PDO::FETCH_COLUMN,1);
- echo '所有联系人的姓名:';
- print_r($row);
- ?>
复制代码
HTML输出结果如下:
该程序的输出结果和前一个示例相似,只是多输出一个包含所有联系人姓名的数组.在很大程度上是出于方便考虑,选择使用fetchall()方法代替fetch()方法,但使用fetchall()处理特别大的结果时,会给数据库服务器资源和网络带宽带来很大的负担
setfetchmode()方法
pdostatement对象中的fetch()和fetchall()两个方法,获取结果数据的引用方式默认都是一样的,即按列名索引又按列在杭后总的数值偏移(从0开始)索引的数值组,因为它们的默认模式都被设置为PDO::FETCH_BOTH值,如果计划使用其他模式来改变这个默认设置,可以在fetch()或fetchall()方法中提供需要的模式参数.但如果多次使用这两个方法,在每次调用时都需要设置新的模式来改变默认的模式,这时就可以使用pdostatement类对象中的setfetchmode()方法,在脚本页面的顶部设置一次模式,以后所有fetch()和fetchall()方法的调用都将生成相应引用的结果集,减少了多次在调用fetch()方法时的参数录入
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|