zoukankan      html  css  js  c++  java
  • PDO数据访问抽象层

    PDO数据访问抽象层:

    我们使用的mysqli是针对mysql这个数据库扩展的一个类,如果要用到别的数据库的话就可以用PDO来做

    1.操作数据库

    先来代码

    <!--PDO-->
    <!--数据访问抽象层-->
    <!--可以访问其他数据库-->
    <!--具有事务功能-->
    <!--带有预处理语句功能(防止sql注入攻击功能)-->
    <?php
    //1.造PDO对象
    $dsn = "mysql:dbname=heiheihei;host=localhost";
    //冒号前面的是驱动名称(mysql),后面是参数:dbname=连接哪一个数据库;连接到本机
    $pdo = new PDO($dsn,"root","12345678");
    //root(数据库用户名,密码)
    
    //2.写sql语句
    $sql = "select * from mydb";
    //查询语句
    
    
    //3.执行sql语句
    //$stm = $pdo->query($sql);
    //执行查询语句
    
    
    //4.从PDOStatement对象里面读取数据
    //$arr = $stm->fetch(PDO::FETCH_ASSOC);
    //返回关联数组,即返回一个索引为结果集列名的数组
    //$arr = $stm->fetch(PDO::FETCH_BOTH);
    //关联加索引,即返回一个索引为结果集列名和以0开始的列号的数组
    //$arr = $stm->fetch(PDO::FETCH_NUM);
    //返回索引的数组,即返回一个索引为以0开始的结果集列号的数组
    //$arr = $stm->fetch(PDO::FETCH_OBJ);
    //返回一个属性名对应结果集列名的匿名对象
    
    //缺省为 PDO::ATTR_DEFAULT_FETCH_MODE 的值,即默认
    
    //如果是PDOStatement::fetchAll,即代表一次性读出所有数据
    
    
    
    
    var_dump($arr);
    ?>

    输出:

    调用一下fetch里面的参数为  PDO::FETCH_ASSOC

    输出attr,则返回一个索引为结果集列名的数组:

    调用一下fetch里面的参数为  PDO::FETCH_NUM

    输出attr,则返回一个索引为结果集列名和以0开始的列号的数组:

    调用一下fetch里面的参数为  PDO::FETCH_OBJ

    输出attr,则返回一个属性名对应结果集列名的匿名对象:

    改为fetchALL(PDO::FETCH_OBJ)也可以,它是把所有数据都可以查到:

    用PDO来做个添加语句:

    <?php
    //1.造PDO对象
    $dsn = "mysql:dbname=heiheihei;host=localhost";
    //冒号前面的是驱动名称(mysql),后面是参数:dbname=连接哪一个数据库;连接到本机
    $pdo = new PDO($dsn,"root","12345678");
    //root(数据库用户名,密码)
    
    //2.写sql语句
    
    $sql = "insert into mydb VALUES ('虾','123','小虾',0)";
    //增删改语句
    
    //3.执行sql语句
    
    $arr = $pdo->exec($sql);
    //执行添加语句,exec返回影响的行数
    
    //4.从PDOStatement对象里面读取数据
    var_dump($arr);
    ?>

    exec是用来执行其他语句,他返回的是受影响的行数

    图:

    显示了一个1,证明影响了1行数据;

    如果失败了,运行后会显示0

    再看一下,数据库内,已经添加成功:

     2.事务功能

    事务功能即能够控制语句同时成功或同时失败,失败时可以回滚

    事务有三个基本的方法:

    PDO::beginTransaction() - 启动一个事务:将下面的代码看作一个事务

    commit - 提交事务:是将开始和提交中间的代码看作一个事务一起执行提交

    PDO::rollBack() - 回滚一个事务:如果有问题就回滚,没有问题就不用回滚,回滚就是还原

    代码:

    <?php
    $dsn = "mysql:dbname = mydb;host=localhost";
    //数据源
    $pdo = new PDO($dsn,"root","123");
    //造对象
    
    
    //改事务模式
    
    //1.将PDO的错误类型设为异常模式(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION )
    $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    
    //try尝试运行里面代码
    try {
    //开启事务
        $pdo->beginTransaction();
    
        $sql = "insert into mydb VALUES ('西','123','小西',0)";
        $sqll = "insert into mydb VALUES ('虾','123','小虾',0)";
    
        $pdo->exec($sql);
        $pdo->exec($sqll);
    
    //提交事务
        $pdo->commit();
    }
    
    //catch抓住异常.控制异常。$e代表异常的数值
    catch(Exception $e)
    {
    //    echo "有错误";
    
        //回滚操作!!!
        //如果发现有错误,回滚rollback!
        $pdo->rollBack();
    }
    
    //最终执行,必执行
    //final
    //{
       //无论有没有一场出现,该代码都会执行
    //}
    ?>

    在我的数据库里面帐号是主键

    西是可以添加上的,但是虾有重复是加不上的,因为有事务功能 ,要么一起成功,要么一起失败,所以这两条数据都不会成功

    运行完成,查看数据库:

     

    果然一条都没有成功!

    如果把虾改成对的:

     $sql = "insert into mydb VALUES ('西','123','小西',0)";
        $sqll = "insert into mydb VALUES ('东','123','小东',0)";

    一起添加成功!!

     3.预处理语句防止SQL注入:

     他是分两次来发送到输出,就不会出现注入攻击了

    (1)占位符“?”方法:

    <?php
    
    
    $dsn = "mysql:dbname=heiheihei;host=localhost";
    $pdo = new PDO($dsn,"root","12345678");
    
    //框架
    $sql = "insert into mmaa VALUES (?,?)";
    //写一个预处理语句,在写参数的地方用占位符“?”代替
    
        //将预处理语句扔到服务器等待执行,返回PDOStatomont对象;prepare准备,等待执行
    $stm = $pdo->prepare($sql);
    
    //第二次将变量(参数)扔到服务器的SQl语句相应位置,给预处理语句绑定参数。binparam绑定参数
    //第一个参数第二个参数是
    $stm->bindParam(1,$id);
    $stm->bindParam(2,$name);
    
    //赋值
    $id = 5;
    $name = "孙";
    //执行
    $stm->execute();

    这是一个添加语句,让我们来看看添加成功

    如果数据过多,上面这种方法会极其麻烦,所以还有一种简单方法

    <?php
    
    
    $dsn = "mysql:dbname=heiheihei;host=localhost";
    $pdo = new PDO($dsn,"root","12345678");
    
    //框架
    $sql = "insert into mmaa VALUES (?,?)";
    //写一个预处理语句,在写参数的地方用占位符“?”代替
    
        //将预处理语句扔到服务器等待执行,返回PDOStatomont对象;prepare准备,等待执行
    $stm = $pdo->prepare($sql);
    
    
    //定义一个数组,必须是索引数组
    $arr = aarray("8","邵");
    
    //执行
    $stm->execute($arr);

    这上面的这种方法很智能,并且很简便,它可以自动把参数仍到该扔到的地方

    (2)名称占位法...

    这种方法一目了然,知道该填什么参数

    代码:

    首先我设一个添加的页面:

    <body>
    <h1>添加一条数据</h1>
    <form action="bbb.php" method="post">
    <div>id:<input type="text" name="id"/></div>
        <div>姓名:<input type="text" name="name"/></div>
        <input type="submit" value="点击添加"/>
    </form>
    
    </body>

    然后我去做处理页面:

    <?php
    $dsn = "mysql:dbname=heiheihei;host=localhost";
    $pdo = new PDO($dsn,"root","12345678");
    
    //预处理语句,括号里不是?了
    $sql = "insert into mmaa VALUES (:id,:name)";
    $stm = $pdo->prepare($sql);
    
    //执行,$_post里面有id跟name的值,所以直接把post扔进去就好了
    $stm->execute($_POST);

    添加图:

    点击添加,查看数据库:

    添加成功了,代码量非常少

    PDO常用方法及其应用

    PDO::query() 主要是用于有记录结果返回的操作,特别是SELECT操作
    PDO::exec() 主要是针对没有结果集合返回的操作,如INSERT、UPDATE等操作
    PDO::prepare() 主要是预处理操作,需要通过$rs->execute()来执行预处理里面的SQL语句,这个方法可以绑定参数,功能比较强大(防止sql注入就靠这个)
    PDO::lastInsertId() 返回上次插入操作,主键列类型是自增的最后的自增ID
    PDOStatement::fetch() 是用来获取一条记录
    PDOStatement::fetchAll() 是获取所有记录集到一个集合
    PDOStatement::fetchColumn() 是获取结果指定第一条记录的某个字段,缺省是第一个字段
    PDOStatement::rowCount() :主要是用于PDO::query()和PDO::prepare()进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec()方法和SELECT操作无效。

     防注入攻击原理:

    当调用 prepare() 时,查询语句已经发送给了数据库服务器,此时只有占位符 ? 发送过去,没有用户提交的数据;当调用到 execute()时,用户提交过来的值才会传送给数据库,他们是分开传送的,两者独立的,SQL攻击者没有一点机会。

  • 相关阅读:
    DDOS学习笔记(《破坏之王-DDOS攻击与防范深度剖析》)
    gearman学习笔记1
    Sphinx学习笔记2
    docker学习笔记(一)
    Centos7安装配置Xhgui
    MongodDB学习笔记(二)(复制)
    MongoDB学习笔记(一)
    0927 DP 小测 #1
    「NOI 2011」阿狸的打字机 「AC 自动机」「数据结构」
    「POI 2005」SZA-Template 「失配树」「双向链表」「思维」
  • 原文地址:https://www.cnblogs.com/xuan584521/p/6493160.html
Copyright © 2011-2022 走看看