PDO的使用

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

本机上运行


    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预处理类

    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与连接有关的选项
    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 "
PDO是否关闭自动提交功能:". $pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);
    $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);//修改
        echo "
当前PDO的错误处理的模式:". $pdo->getAttribute(PDO::ATTR_ERRMODE); 
    echo "
表字段字符的大小写转换: ". $pdo->getAttribute(PDO::ATTR_CASE); 
    echo "
与连接状态相关特有信息: ". $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS); 
    echo "
空字符串转换为SQL的null:". $pdo->getAttribute(PDO::ATTR_ORACLE_NULLS); 
    echo "
应用程序提前获取数据大小:".$pdo->getAttribute(PDO::ATTR_PERSISTENT); 
    echo "
与数据库特有的服务器信息:".$pdo->getAttribute(PDO::ATTR_SERVER_INFO); 
    echo "
数据库服务器版本号信息:". $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
    echo "
数据库客户端版本号信息:". $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异常对象

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

    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 '
';
        print_r($pdo->errorinfo());
        exit;
    }
    echo "ok";
上面这种方法加的是提示语,文字版的报错原因,还可以通过红色框框报错的方式提示:
    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)."
";
    $affected_rows=$pdo->exec("delete from hello world");

但是这两种模式都不是常用的,常用的是“异常”
    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)."
";
    try{
        $affected_rows=$pdo->exec("delete from hello world");
    }catch(PDOException $e){
        echo $e->getMessage();
    }
 
    echo "ok";
使用PDO执行SQL语句
    //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,'[email protected]')");
        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' =>  'select * from users' (length=19)

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

    try{
        $stent=$pdo->query("select * from users");
        foreach($stent as $arr){
            print_r($arr);
            echo '
';
        }
    }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] => [email protected] [5] => [email protected])
Array( [id] => 2 [0] => 2 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => [email protected] [5] => [email protected])
Array( [id] => 3 [0] => 3 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => [email protected] [5] => [email protected])
Array( [id] => 4 [0] => 4 [username] => aaa [1] => aaa [password] => bbb [2] => bbb [age] => 13 [3] => 13 [sex] => f [4] => f [email] => [email protected] [5] => [email protected])

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

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

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中?
    //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 "转出成功
";
        else throw new PDOException("转出失败");
        $affected=$pdo->exec("update demo set ye=ye+($price) where id=2");
        if($affected>0)echo "收到成功
";
        else throw new PDOException("收到失败");
        $pdo->commit();
    }catch(PDOException $e){
        echo "错误:".$e->getMessage();
        echo "交易失败
";
        $pdo->rollback();
    }
    

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


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

    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 "错误";
    }
用来干嘛的呢?防止数据库注入
    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()也可以直接传参数,省事好多:

    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 "错误";
    }


但是:

//?必须按照顺序,:名字参数类似于索引数组
    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 "错误";
    }

既然索引数组可以这么写,那么:有可以省事了
//?必须按照顺序,:名字参数类似于索引数组
    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 "错误";
    }

更更省事的推荐方法:
//?必须按照顺序,:名字参数类似于索引数组
    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的预处理查询
//本节重点是处理结果
    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 '
';
        }
    }
    catch(PDOException $e)
    {
        echo "错误";
    }

为了看得清晰:
//本节重点是处理结果
    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 '

';
        while(list($id,$name,$age,$sex)=$stat->fetch(PDO::FETCH_NUM)){
            echo '';
            echo '';
            echo '';
            echo '';
            echo '';
            echo '';
        }
        echo '
'.$id.''.$name.''.$age.''.$sex.'
';
    }
    catch(PDOException $e)
    {
        echo "错误";
    }

2    aaa    13    f
3    aaa    13    f
4    aaa    13    f
5    zzz    20    f
6    zzz    20    f
7    zyj    22    f
8    zyj    22    f
9    zzzz    22    m


用内置的:

//本节重点是处理结果
    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 '

';
        print_r($stat->fetchAll(PDO::FETCH_NUM));
        echo '
';
    }
    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
        )

)
也可以事先设置,以后都省略了
//本节重点是处理结果
    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 '

';
        print_r($stat->fetchAll());
        echo '
';
    }
    catch(PDOException $e)
    {
        echo "错误";
    }

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


绑定列~

//本节重点是处理结果
    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 '

';
        while($stat->fetch()){
            echo '';
            echo '';
            echo '';
            echo '';
            echo '';
            echo '';
        }
        echo '
'.$id.''.$name.''.$age.''.$sex.'
';
    }
    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();

如何获取
--------------------- 
作者:MissZhou要努力 
来源:CSDN 
原文:https://blog.csdn.net/zhou_yujia/article/details/50762983 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(PHP)