zoukankan      html  css  js  c++  java
  • PDO 学习与使用 ( 二 ) PDO 数据提取 和 预处理语句

    以数据库 msg 为例,说明 PDO 的数据提取、预处理语句:

    mysql> show tables;
    +---------------+
    | Tables_in_msg |
    +---------------+
    | message |
    +---------------+

    mysql> show create table message G
    *************************** 1. row ***************************
    Table: message
    Create Table: CREATE TABLE `message` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `content` varchar(200) NOT NULL COMMENT '聊天内容',
    `flag` int(11) NOT NULL DEFAULT '0' COMMENT '0-未读 1-已读',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

    mysql> show columns from message;
    +---------+--------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+----------------+
    | id | int(11) | NO | PRI | NULL | auto_increment |
    | content | varchar(200) | NO | | NULL | |
    | flag | int(11) | NO | | 0 | |
    +---------+--------------+------+-----+---------+----------------+

    mysql> select * from message;
    +----+---------+------+
    | id | content | flag |
    +----+---------+------+
    | 1 | hello | 1 |
    | 2 | world | 1 |
    +----+---------+------+

    从表中选择数据

    <?php
    
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $stmt = $db_conn->query('select * from message');
    while($row = $stmt->fetch()) {
        echo $row['id'],'.',$row['content'],'<br />';
    }

    返回:

    1.hello
    2.world

    说明:

    ① $db_conn 是 PDO 对象

    ② $stmt 是 PDOStatement 对象,它代表查询,并获取结果(stmt 有预处理的意思)

    ③ PDOStatement::fetch() 方法可以 处理大量提取数据的模式

    ④ fetch() 方法将从结果集中取出一行数据

    数据提取模式

    fetchAll() 方法可以一次检索所有的行。同时 fetch() 方法 和 fetchAll() 方法 都可以接受 fetch_style 参数,包括:

    PDO::FETCH_ASSOC,返回关联数组

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $stmt = $db_conn->query('select * from message');
    
     $res = $stmt->fetch(PDO::FETCH_ASSOC);
     var_dump($res);

    返回:

    array
      'id' => string '1' (length=1)
      'content' => string 'hello' (length=5)
      'flag' => string '1' (length=1)

    或(fetchAll):

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $stmt = $db_conn->query('select * from message');
    
     $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
     var_dump($res);

    返回:

    array
      0 => 
        array
          'id' => string '1' (length=1)
          'content' => string 'hello' (length=5)
          'flag' => string '1' (length=1)
      1 => 
        array
          'id' => string '2' (length=1)
          'content' => string 'world' (length=5)
          'flag' => string '1' (length=1)

    PDO::FETCH_NUM,返回索引数组:

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $stmt = $db_conn->query('select * from message');
    
     $res = $stmt->fetchAll(PDO::FETCH_NUM);
     var_dump($res);

    返回:

    array
      0 => 
        array
          0 => string '1' (length=1)
          1 => string 'hello' (length=5)
          2 => string '1' (length=1)
      1 => 
        array
          0 => string '2' (length=1)
          1 => string 'world' (length=5)
          2 => string '1' (length=1)

    PDO::FETCH_BOTH,返回关联数组和索引数组:

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $stmt = $db_conn->query('select * from message');
    
     $res = $stmt->fetchAll(PDO::FETCH_BOTH);
     var_dump($res);

    返回:

    array
      0 => 
        array
          'id' => string '1' (length=1)
          0 => string '1' (length=1)
          'content' => string 'hello' (length=5)
          1 => string 'hello' (length=5)
          'flag' => string '1' (length=1)
          2 => string '1' (length=1)
      1 => 
        array
          'id' => string '2' (length=1)
          0 => string '2' (length=1)
          'content' => string 'world' (length=5)
          1 => string 'world' (length=5)
          'flag' => string '1' (length=1)
          2 => string '1' (length=1)

    参数和预处理语句

    提取 id = 1 的 message 的信息,要使用一个 预处理语句,告诉 MySQL 这条语句的哪些部分是变量。在运行 PDO::query() 时,组合了 预处理 和 执行步骤:

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'select * from message where id = :msg_id';
    $stmt = $db_conn->prepare($sql);
    
    //执行预处理
    $stmt->execute(array('msg_id'=>2));
    $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    var_dump($res);

    返回:

    array
      0 => 
        array
          'id' => string '1' (length=1)
          'content' => string 'hello' (length=5)
          'flag' => string '1' (length=1)

    说明:

    ① 通过传递 SQL 语句作为参数, PDO 对象的 prepare() 方法创建了 PDOStatement($stmt);

    ② :msg_id 前面的冒号表示这是一个占位符(placeholder);

    ③ 在实际查询前,会用真正的值来替换占位符

    ④ execute() 方法执行查询

    ⑤ 必须为 SQL 中的每一个占位符传入值,需要创建一个与占位符数量相同的元素组成的数组,每个占位符都有一个与之匹配的数组元素,数组元素的键名和占位符一致,数组元素的实际值替换占位符

    占位符的另外一种形式:

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'select * from message where id = ? and flag = ?';
    $stmt = $db_conn->prepare($sql);
    
    //执行预处理
    $stmt->execute(array(2, 1));
    $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    var_dump($res);

    返回:

    array
      0 => 
        array
          'id' => string '2' (length=1)
          'content' => string 'world' (length=5)
          'flag' => string '1' (length=1)

    说明:

    占位符可以不需要名字,而用 ? 为变量保留一个位置作为没有命名的占位符。

    当使用预处理时,为占位符传入的值已经溢出(删除了不需要的字符),因为 MySQL 知道这些都是可能改变的值。

    绑定值和预处理语句的变量

    当使用 不同的值 重复调用 相同的查询 时,只会有很小的系统弄个开销,可以设置一些元素用于每次查询 - PDOStatement::buildValue():

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'select * from message where id = :msg_id and flag = :msg_flag';
    $stmt = $db_conn->prepare($sql);
    
    //绑定值
    $stmt->bindValue(':msg_id', 1);
    
    $stmt->bindValue(':msg_flag', 1);
    $stmt->execute();
    $res = $stmt->fetch(PDO::FETCH_ASSOC);
    
    $stmt->bindValue('msg_id', 2);
    $stmt->execute();
    $res2 = $stmt->fetch(PDO::FETCH_ASSOC);
    
    var_dump($res);
    var_dump($res2);

    输出:

    array
      'id' => string '1' (length=1)
      'content' => string 'hello' (length=5)
      'flag' => string '1' (length=1)
    array
      'id' => string '2' (length=1)
      'content' => string 'world' (length=5)
      'flag' => string '1' (length=1)

    还可以使用 PDOStatement::bindParam() 将参数和变量绑定:

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'select * from message where id = :msg_id and flag = :msg_flag';
    $stmt = $db_conn->prepare($sql);
    
    //绑定值
    $stmt->bindParam(':msg_id', $msgid);
    
    $stmt->bindValue(':msg_flag', 1);
    $msgid = 1;
    $stmt->execute();
    $res = $stmt->fetch(PDO::FETCH_ASSOC);
    
    $stmt->bindValue('msg_id', 2);
    $stmt->execute();
    $res2 = $stmt->fetch(PDO::FETCH_ASSOC);
    
    var_dump($res);
    var_dump($res2);

    输出:

    array
      'id' => string '1' (length=1)
      'content' => string 'hello' (length=5)
      'flag' => string '1' (length=1)
    array
      'id' => string '2' (length=1)
      'content' => string 'world' (length=5)
      'flag' => string '1' (length=1)

    插入一行数据并获取 ID

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'insert into message (content, flag) values (:content, :flag)';
    $stmt = $db_conn->prepare($sql);
    
    $stmt->execute(array(
        ':content'=>'诸葛四郎和魔鬼党,到底谁抢到那支宝剑',
        ':flag'=>2
        )
    );
    
    echo 'new id: ',$db_conn->lastInsertId(); 

    输出:new id: 3

    说明:lastinsertId() 是 PDO 对象而不是 PDOStatement 对象。

    注意:插入中文时为避免乱码,需要在实例化 PDO 对象时增加一个参数 $opt:

    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    $opt = array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8");
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd, $opt);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }

    返回插入、更新或删除的数据的数量

    当执行 Insert、Update、Delete 语句时,可以通过 rowCount() 方法 找出多少行内容已经改变:

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'update message set flag = :flag where flag = 1';
    $stmt = $db_conn->prepare($sql);
    
    $stmt->execute(array(':flag'=>3));
    
    echo $stmt->rowCount(),' rows uodated.'; 

    输出:2 rows uodated.

    说明:rowCount() 方法是 PDOStatement 对象。

    删除数据 

    <?php
    $dsn = 'mysql:host=localhost;dbname=msg';
    $username = 'root';
    $pwd = '';
    
    try {
        $db_conn = new PDO($dsn, $username, $pwd);
    }catch (PDOException $e) {
        echo 'Could not connect to database.<br />'.$e->getMessage();
    }
    
    $sql = 'delete from message where id = :msgid';
    $stmt = $db_conn->prepare($sql);
    
    $stmt->execute(array(':msgid'=>2));
    
    echo $stmt->rowCount(),' row(s) deleted.'; 

    输出:1 row(s) deleted.

    附:《PDO 学习与使用 ( 一 ) :PDO 对象、exec 方法、query 方法与防 SQL 注入

  • 相关阅读:
    循环
    rugarch包与R语言中的garch族模型
    Logistic回归
    机器学习缺失值处理方法汇总
    pandas库介绍之DataFrame基本操作
    python中常用的九种预处理方法
    谁动了我的特征?——sklearn特征转换行为全记录
    使用sklearn优雅地进行数据挖掘
    使用sklearn做单机特征工程
    彻底解决matplotlib中文乱码问题
  • 原文地址:https://www.cnblogs.com/dee0912/p/4824926.html
Copyright © 2011-2022 走看看