PDO的使用

简介:

pdo是数据库抽象层中的一种,个人理解是便于多种数据库连接

本机上运行

<?php
	phpinfo();

可以查看到 现有驱动

修改php配置文件更改可供使用的数据库

课件上貌似给的是linux的方法

编辑php.ini文件:
extension=php_pdo.dll
extension=php_pdo_mysql.dll
2.重启apache服务:
httpd –k restart
3.打开phpinfo.php查看是否有pdo

而且linux下是用源代码安装的惊恐

创建PDO对象

主要学习PDO的两个类:pdo pdo预处理类

<?php
	try{
		$pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
		//dsn数据源名称:主机/库/具体数据源的驱动
	}
	catch(PDOException $e){
		echo "数据库连接失败".$e->getMessage();
		exit;
	}
	echo "创建pdo对象完成";
创建pdo对象完成 为了方便 可以把pdo写在配置之文件中

图省事的话依旧是修改配置文件:[pdo]后面加 pdo.dsn.zyj="mysql:host=localhost;dbname=xsphp"  文中第一句改成:$pdo=new PDO("zyj","root","zyj19950307");

此外:连接数据库那里用Try是不是很像c#~~~

PDO与连接有关的选项

<?php
	try {
		$pdo = new PDO("mysql:host=localhost;dbname=xsphp", "root", "123456", array(PDO::ATTR_AUTOCOMMIT=>false,PDO::ATTR_PERSISTENT=>1 ));
	}catch(PDOException $e) {
		echo "数据库连接失败:".$e->getMessage();
		exit;
	}
	echo "<br>PDO是否关闭自动提交功能:". $pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);
	$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);//修改
        echo "<br>当前PDO的错误处理的模式:". $pdo->getAttribute(PDO::ATTR_ERRMODE); 
	echo "<br>表字段字符的大小写转换: ". $pdo->getAttribute(PDO::ATTR_CASE); 
	echo "<br>与连接状态相关特有信息: ". $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS); 
	echo "<br>空字符串转换为SQL的null:". $pdo->getAttribute(PDO::ATTR_ORACLE_NULLS); 
	echo "<br>应用程序提前获取数据大小:".$pdo->getAttribute(PDO::ATTR_PERSISTENT); 
	echo "<br>与数据库特有的服务器信息:".$pdo->getAttribute(PDO::ATTR_SERVER_INFO); 
	echo "<br>数据库服务器版本号信息:". $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
	echo "<br>数据库客户端版本号信息:". $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION); 
修改属性值构造参数加第四个参数:array(PDO::ATTR_AUTOCOMMIT=>false,PDO::ATTR_PERSISTENT=>1 ) 持久连接改成“是”效率高,但是占资源

PDO的错误处理模式

PDO::ATTR_ERRMODE=>错误处理模式:(3)
PDO::ERRMODE_SILENT:不报错误(忽略)(0)
PDO::ERRMODE_WARNING:以警告的方式报错(1)
PDO::ERRMODE_EXCEPTION:以异常的方式报错(推荐使用)(2)
设置方式:2种
在构造时初始化错误模式
通过pdo对象的setAttribute()方法设置。
              $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
面向过程
$con->errorCode():SQL语句错误代码
$con->errorInfo():错误信息
面向对象
捕获PDOException异常对象


思考以下情景:如果我们想删掉一个表,库里没有,直接删除我也不知道怎么个情况,有以下方法

<?php
	try{
		$pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
	}catch(PDOException $e){
		echo "数据库连接失败:".$e->getMessage();
		exit;
	}
	$affected_rows=$pdo->exec("delete from hello world");//想到什么了 c#里的ExecuteNonQuery()
	if(!affected_rows){
		echo $pdo->errorCode();
		echo '<br>';
		print_r($pdo->errorinfo());
		exit;
	}
	echo "ok";
上面这种方法加的是提示语,文字版的报错原因,还可以通过红色框框报错的方式提示:

<?php
	try{
		$pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
	}catch(PDOException $e){
		echo "数据库连接失败:".$e->getMessage();
		exit;
	}
	$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
	echo $pdo->getAttribute(PDO::ATTR_ERRMODE)."<br>";
	$affected_rows=$pdo->exec("delete from hello world");

但是这两种模式都不是常用的,常用的是“异常”

<?php
    try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    }catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
    $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    echo $pdo->getAttribute(PDO::ATTR_ERRMODE)."<br>";
    try{
        $affected_rows=$pdo->exec("delete from hello world");
    }catch(PDOException $e){
        echo $e->getMessage();
    }

    echo "ok";

使用PDO执行SQL语句

<?php
	//exec()处理非结果的 返回影响的行数
	//query()处理有结果的
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    }catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$affected_rows=$pdo->exec("insert into users(username,password,sex,age,email)values('aaa','bbb','f',13,'dscsa@163.com')");
		echo $affected_rows;
	}catch(PDOException $e){
		echo "错误:".$e->getMessage();
	}
	
首先要注意,你得有这个表格,而且表格名字/列名都得相同~当然上边的例子也可以用query但是不能输出影响行数就是了~
$pdo->lastInsertId();返回最后插入的id

try{
		$affected_rows=$pdo->query("select * from users");
	//	echo $affected_rows;
		var_dump($affected_rows);
	}catch(PDOException $e){
		echo "错误:".$e->getMessage();
	}

猜猜是什么

object(PDOStatement)[2]
  public 'queryString' => string 'select * from users' (length=19)

但是我也可以认为上面那个返回的是数组~~~

	try{
		$stent=$pdo->query("select * from users");
		foreach($stent as $arr){
			print_r($arr);
			echo '<br>';
		}
	}catch(PDOException $e){
		echo "错误:".$e->getMessage();
	}

返回:

Array( [id] => 1 [0] => 1 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => dscsa@163.com [5] => dscsa@163.com)
Array( [id] => 2 [0] => 2 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => dscsa@163.com [5] => dscsa@163.com)
Array( [id] => 3 [0] => 3 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => dscsa@163.com [5] => dscsa@163.com)
Array( [id] => 4 [0] => 4 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => dscsa@163.com [5] => dscsa@163.com)

但是主要还是用内置函数处理~~


事务

介绍一下神奇的事务机制~

MySQL的事务处理

事务:

将多条sql操作(增删改)作为一个操作单元,要么都成功,要么都失败。
MySQL对事务的支持:
被操作的表必须是innoDB类型的表(支持事务)
MySQL常用的表类型:MyISAM(非事务)增删改速度快(默认)、InnodB(事务型)安全性高
更改表的类型为innoDB类型
        mysql> alter table stu engine=innodb;
            Query OK, 29 rows affected (0.34 sec)
            Records: 29  Duplicates: 0  Warnings: 0
            mysql> show create table stu\G; //查看表结构

事务处理:

Mysql> set autocommit = 0;//不自动更新
mysql>start transaction;//事务开始
Mysql>commit;//提交事务了就不能改了
Mysql>roolback;//撤销操作,commit之后撤销没用

mysql> select * from demo;
+----+----------+------+
| id | username | ye   |
+----+----------+------+
|  1 | misszhou |  100 |
|  2 | zyj      |  200 |
+----+----------+------+
2 rows in set (0.00 sec)

mysql> update demo set ye=1000 where id=1;
Query OK, 1 row affected (0.09 sec)
Enregistrements correspondants: 1  Modifi茅s: 1  Warnings: 0

mysql> select * from demo;
+----+----------+------+
| id | username | ye   |
+----+----------+------+
|  1 | misszhou | 1000 |
|  2 | zyj      |  200 |
+----+----------+------+
2 rows in set (0.00 sec)

mysql> delete from demo;
Query OK, 2 rows affected (0.00 sec)

mysql> select * from demo;
Empty set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.07 sec)

mysql> select * from demo;
+----+----------+------+
| id | username | ye   |
+----+----------+------+
|  1 | misszhou |  100 |
|  2 | zyj      |  200 |
+----+----------+------+
2 rows in set (0.00 sec)

如何体现在php中?

<?php
	//exec()处理非结果的 返回影响的行数
	//query()处理有结果的
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$pdo->beginTransaction();
		$price=50;
		$affected=$pdo->exec("update demo set ye=ye-($price) where id=1");
		if($affected>0)echo "转出成功<br>";
		else throw new PDOException("转出失败");
		$affected=$pdo->exec("update demo set ye=ye+($price) where id=2");
		if($affected>0)echo "收到成功<br>";
		else throw new PDOException("收到失败");
		$pdo->commit();
	}catch(PDOException $e){
		echo "错误:".$e->getMessage();
		echo "交易失败<br>";
		$pdo->rollback();
	}
	
	

搞了好的久的pdo执行Sql语句你居然告诉我不常用!!好吧 下面这个常用 为例防止SQL输入,地址栏==sql语句 但是你看杭电的


PDO对预处理语句的支持

PDOStatement对象的方法
准备语句
绑定参数
执行预处理方式
预处理查询


<?php
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("insert into users(username,password,age,sex) values ('zzz','123',20,'f')");
		//语句里的不能是双引号 只能是单引号!
		var_dump($stat);
		//$stat->execute();不执行这条语句,上面的sql语句就不执行!
		$stat->execute();
	}
	catch(PDOException $e)
	{
		echo "错误";
	}
用来干嘛的呢?防止数据库注入

<?php
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("insert into users(username,password,age,sex) values (?,?,?,?)");
		//语句里的不能是双引号 只能是单引号!
		//绑定参数?==>变量
		$stat->bindParam(1, $name);
		$stat->bindParam(2, $pass);
		$stat->bindParam(3, $age);
		$stat->bindParam(4, $sex);//多像c#!
		$name='zyj';
		$pass='123';
		$age=22;
		$sex='f';
		var_dump($stat);
		$stat->execute();
		//$stat->execute();
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

可以保证没有其他数据

excute()也可以直接传参数,省事好多:

<?php
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("insert into users(username,password,age,sex) values (?,?,?,?)");
		//语句里的不能是双引号 只能是单引号!
		//绑定参数?==>变量
		var_dump($stat);
		$stat->execute(array("zzzz","123",22,"m"));
		//$stat->execute();
	}
	catch(PDOException $e)
	{
		echo "错误";
	}


但是:

<?php
//?必须按照顺序,:名字参数类似于索引数组
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("insert into users(username,password,age,sex) 
		values (:name,:pass,:age,:sex)");
		//语句里的不能是双引号 只能是单引号!
		//绑定参数?==>变量
		$stat->bindParam(":name", $name);//冒号可省
		$stat->bindParam(":pass", $pass);
		$stat->bindParam(":age", $age);
		$stat->bindParam(":sex", $sex);//多像c#!
		$name='zyj';
		$pass='123';
		$age=22;
		$sex='f';
		var_dump($stat);
		$stat->execute();
		//$stat->execute();
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

既然索引数组可以这么写,那么:有可以省事了

<?php
//?必须按照顺序,:名字参数类似于索引数组
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("insert into users(username,password,age,sex) 
		values (:name,:pass,:age,:sex)");
		//语句里的不能是双引号 只能是单引号!
		$stat->execute(array("name"=>"yyy","pass"=>"222","age"=>30,"sex"=>"f"));
		//$stat->execute();
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

更更省事的推荐方法:

<?php
//?必须按照顺序,:名字参数类似于索引数组
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("insert into users(username,password,age,sex) 
		values (:name,:pass,:age,:sex)");
		//语句里的不能是双引号 只能是单引号!
		$stat->execute($_GET);
		//$stat->execute();
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

在地址栏里面传参数就好啦~

PDO的预处理查询

<?php
//本节重点是处理结果
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("select id,username,age,sex from users where id>? and id <?");
		$stat->execute(array(1,10));
		while($row=$stat->fetch()){//里面参数控制索引数组和关联数组
			print_r($row);
			echo '<br>';
		}
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

为了看得清晰:

<?php
//本节重点是处理结果
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("select id,username,age,sex from users where id>? and id <?");
		$stat->execute(array(1,10));
		echo '<table border="1" width=800 align="center">';
		while(list($id,$name,$age,$sex)=$stat->fetch(PDO::FETCH_NUM)){
			echo '<tr>';
			echo '<td>'.$id.'</td>';
			echo '<td>'.$name.'</td>';
			echo '<td>'.$age.'</td>';
			echo '<td>'.$sex.'</td>';
			echo '</tr>';
		}
		echo '</table>';
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

2aaa13f
3aaa13f
4aaa13f
5zzz20f
6zzz20f
7zyj22f
8zyj22f
9zzzz22m



用内置的:

<?php
//本节重点是处理结果
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("select id,username,age,sex from users where id>? and id <?");
		$stat->execute(array(1,10));
		echo '<pre>';
		print_r($stat->fetchAll(PDO::FETCH_NUM));
		echo '</pre>';
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

返回:

Array
(
    [0] => Array
        (
            [0] => 2
            [1] => aaa
            [2] => 13
            [3] => f
        )

    [1] => Array
        (
            [0] => 3
            [1] => aaa
            [2] => 13
            [3] => f
        )

    [2] => Array
        (
            [0] => 4
            [1] => aaa
            [2] => 13
            [3] => f
        )

    [3] => Array
        (
            [0] => 5
            [1] => zzz
            [2] => 20
            [3] => f
        )

    [4] => Array
        (
            [0] => 6
            [1] => zzz
            [2] => 20
            [3] => f
        )

    [5] => Array
        (
            [0] => 7
            [1] => zyj
            [2] => 22
            [3] => f
        )

    [6] => Array
        (
            [0] => 8
            [1] => zyj
            [2] => 22
            [3] => f
        )

    [7] => Array
        (
            [0] => 9
            [1] => zzzz
            [2] => 22
            [3] => m
        )

)
也可以事先设置,以后都省略了

<?php
//本节重点是处理结果
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("select id,username,age,sex from users where id>? and id <?");
		$stat->execute(array(1,10));
		//设置结果模式!后面fetch的参数就可以省了
		$stat->setFetchMode(PDO::FETCH_ASSOC);
		echo '<pre>';
		print_r($stat->fetchAll());
		echo '</pre>';
	}
	catch(PDOException $e)
	{
		echo "错误";
	}

那么返回的都是关联数组。




绑定列~

<?php
//本节重点是处理结果
	try{
        $pdo=new PDO("mysql:host=localhost;dbname=xsphp","root","zyj19950307");
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
		$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,1);
	}catch(PDOException $e){
        echo "数据库连接失败:".$e->getMessage();
        exit;
    }
	try{
		$stat=$pdo->prepare("select id,username,age,sex from users where id>? and id <?");
		$stat->execute(array(1,10));
		$stat->bindColumn(1,$id);
		$stat->bindColumn(2,$name);
		$stat->bindColumn(3,$age);
		$stat->bindColumn(4,$sex);
		$stat->setFetchMode(PDO::FETCH_ASSOC);
		echo '<table border="1" width=800 align="center">';
		while($stat->fetch()){
			echo '<tr>';
			echo '<td>'.$id.'</td>';
			echo '<td>'.$name.'</td>';
			echo '<td>'.$age.'</td>';
			echo '<td>'.$sex.'</td>';
			echo '</tr>';
		}
		echo '</table>';
	}
	catch(PDOException $e)
	{
		echo "错误";
	}
当然也可以:
$stat->bindColumn("id",$id);
		$stat->bindColumn("username",$name);
		$stat->bindColumn("age",$age);
		$stat->bindColumn("sex",$sex);

混合用也可以哟,但是不推荐,容易乱套==


如何获取结果的行数:或者影响行数个数~~

echo $stat->rowCount();

如何获取最后一个自动增长的id,预处理怎么办呢

$pdo->lastInsertId();

如何获取



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值