zoukankan      html  css  js  c++  java
  • 【转】 PDO使用归纳【PHP】

    【任务】将PDO封装成类

    new PDO("mysql:host=localhost;dbname=php100","root","pwd" [,driverOptions]);
    如果需要长连接,需要长最后一个参数driverOption:persistent:/aj/持续的,不断的
    new PDO("连接信息","root","pwd",array(PDO::ATTR_PERSISTENT=>true));
    使用array()来传入最后一个参数,是可以带多个选项值,
    如:
    $pdo = new PDO('mysql:host=localhost;dbname=forum','root','123456',array(PDO::ATTR_PERSISTENT=>TRUE,PDO::ATTR_CASE=>PDO::CASE_UPPER,PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
    上面分别指定了:长连接开启,强制PDO获取的列字符大写,以及使用PDOException抛出异常。
    对于这个属性参数,也可以用setAttribute来更改,如下:
    $pdo->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER);
    那么接下去就可以用$row['city']来访问列值,而不必要用$row['CITY']大写方式来访问。

    PDO常用方法:
    PDO::query() 主要用于有记录结果返回的操作,特别是select操作。
    PDO::exec()主要是针对没有结果集合返回的操作。如insert,update等操作。返回影响行数。
    PDO::lastInsertId()返回上次插入操作最后一条ID,但要注意:如果用insert into tb(col1,col2) values(v1,v2),(v11,v22)..的方式一次插入多条记录,lastinsertid()返回的只是第一条(v1,v2)插入时的ID,而不是最后一条记录插入的记录ID。
    PDOStatement::fetch()是用来获取一条记录。配合while来遍历。
    PDOStatement::fetchAll()是获取所有记录集到一个中。
    PDOStatement::fetchcolumn([int column_indexnum]) 用于直接访问列,参数column_indexnum是该列在行中的从0开始索引值,但是,这个方法一次只能取得同一行的一列,只要执行一次,就跳到下一行。因此,用于直接访问某一列时较好用,但要遍历多列就用不上。
    PDOStatement::rowcount()适用于当用query("select ...")方法时,获取记录的条数。也可以用于预处理中。$stmt->rowcount();
    PDOStatement::columncount()适用于当用query("select ...")方法时,获取记录的列数。

    注解:
    1、选fetch还是fetchall?

    小记录集时,用fetchall效率高,减少从数据库检索次数,但对于大结果集,用fetchall则给系统带来很大负担。数据库要向WEB前端传输量太大反而效率低。
    2、fetch()或fetchall()有几个参数:
    mixed pdostatement::fetch([int fetch_style [,int cursor_orientation [,int cursor_offset]]])
    array pdostatement::fetchAll(int fetch_style)

    fetch_style参数:
    ■$row=$rs->fetchAll(PDO::FETCH_BOTH); FETCH_BOTH是默认的,可省,返回关联和索引。
    ■$row=$rs->fetchAll(PDO::FETCH_ASSOC); FETCH_ASSOC参数决定返回的只有关联数组。
    ■$row=$rs->fetchAll(PDO::FETCH_NUM); 返回索引数组
    ■$row=$rs->fetchAll(PDO::FETCH_OBJ); 如果fetch()则返回对象,如果是fetchall(),返回由对象组成的二维数组,如:
    Array
    (
        [0] => stdClass Object
            (
                [cityid] => 2
                [city] => 福州
                [countryid] => 1
            )

        [1] => stdClass Object
            (
                [cityid] => 3
                [city] => 厦门
                [countryid] => 1
            )
    ...
    );
    遍历:
    foreach($row as $r)
    {
    echo "{$r->cityid}:城市 {$r->city}.<br />";
    //或echo "{$r[0]}:城市 {$r[1]}.<br />";
    }
    ■$row=$rs->fetch(PDO::FETCH_LAZY); FETCH_LAZY返回对象:如:
    PDORow Object
    (
        [queryString] => select * from city
        [cityid] => 2
        [city] => 福州
        [countryid] => 1
    )
    ■ $row = $stmt->fetch(PDO::FETCH_BOUND);用于使fetch返回true,并将获取的列值赋给bindParam()方法中指定的相应变量。参考最后一个示例。----相当于mysqli绑定到结果。
    -----------------------------------------------
    例:概要
    $rs=$db->query("select * from php100");
    while($row = $rs->fetch())
    {
    print_r($row);
    }
    或不使用while来遍历:
    $rs=$db->query("select * from php100");
    $row=$rs->fetchall();
    print_r($row);

    $db->exec('insert into ...');
    ------------------------------------------------
    例:select 遍历记录和取得记录总数

    try{
    $pdo = new PDO("mysql:host=localhost;dbname=forum","root","123456");
    }catch(PDOException $e){
    echo '连接错误:'.$e->errorcode();
    }

    $q="select * from city";
    $rs=$pdo->query($q);
    $row=$rs->fetchAll();
    foreach($row as $r)
    {
    echo "{$r['cityid']}:城市 {$r['city']}.<br />";
    //或echo "{$r[0]}:城市 {$r[1]}.<br />";
    }
    echo "共有{$rs->rowcount()}条记录" //$rs->rowcount()返回行数。

    返回的数组格式:可以看到,每一组都带有关联和索引的两种形式:
    Array
    (
        [0] => Array
            (
                [cityid] => 2
                [0] => 2
                [city] => 福州
                [1] => 福州
                [countryid] => 1
                [2] => 1
            )

        [1] => Array
            (
                [cityid] => 3
                [0] => 3
                [city] => 厦门
                [1] => 厦门
                [countryid] => 1
                [2] => 1
            )
    )

    如果用:while($row = $rs->fetch()){ print_r($row);}
    while返回的每一个数组格式是:
    Array
    (
        [cityid] => 2
        [0] => 2
        [city] => 福州
        [1] => 福州
        [countryid] => 1
        [2] => 1
    )
    可以看到:
    $rs->fetch()一次返回一个,
    $rs->fetchAll()一次返回所有的记录,
    两者相同的是:都可以用索引数组或关联数组来取得最终字段值,
    两者不同的是,fetchAll()返回的是二维数组。可以用foreach遍历。

    -----------------------------
    例:插入记录
    $affectedrows = $pdo->exec("insert into city(cityid,city,countryid) values(NULL,'北京',2),(NULL,'南京',2)");
    echo '共影响行数:'.$affectedrows.'<br />';
    echo '最后插入的记录ID为:'.$pdo->lastinsertid();
    这里当用insert into city(cityid,city,countryid) values(NULL,'北京',2)时,返回的正确的ID值,但按上例的方法插入多条记录,则返回的依旧是北京那一条记录的ID,解决办法是把这个值 lastinsertid()+行数-1。

    ------------------------------
    例:返回exec或query错误
    把上例的insert随便改一个,使插入错误,再加上一行:
    print_r($pdo->errorinfo());
    返回:数组0表示存储SQL标准中定义的SQLSTATE码。1表示错误码,0表示错误消息,这里是指city表插入的外键在country表中不存在。
    Array
    (
        [0] => 00000
        [1] => 1452
        [2] => Cannot add or update a child row: a foreign key constraint fails (`forum`.`city`, CONSTRAINT `FK_city_country` FOREIGN

    KEY (`countryid`) REFERENCES `country` (`country_id`))
    )

    ***************************************************************
    PDO的预处理:准备语句

    0、连接:$pdo = new PDO(....);
    1、准备:查询和mysqli的方式不同,支持两种参数占位方式:问号参数“?”命名参数“:字段名”;命名参数更明确。
         $q="insert into city(city,countryid) values(?,?)"; //或$q = "insert into city(city,countryid) values(:city,:countryid)";
         $stmt = $pdo->prepare($q);
    2、执行execute:$pdo->lastinsertid();对预处理也是可用的。
       有两种方式:注意两种方式用“?”问号参数绑定时有不同的execute占位引用方式。并且偏移基数不同。
        (1)显式地把参数值做为参数传给execute: boolean PDOSTatement::execute([array input_parameters])
    命名参数方式:
            $q = "insert into city(city,countryid) values(:city,:countryid)";
            $stmt = $pdo->prepare($q);
            $stmt->execute(array(':city'=>'太原',':countryid'=>'2'));//本条可多次执行。注意,countryid是数值型,但也要用单引号来包住。
    问号参数:
          $q = "insert into city(city,countryid) values(?,?)";
          $stmt = $pdo->prepare($q);
          $stmt->execute(array('0'=>'武汉','1'=>'2')); //注意这里不是用'?'的方式,而是用上面占位符的从0开始的索引偏移,

        (2)绑定参数。boolean PDOSTatement::bindParam(mixed parameter,mixed &variable [,int datatype [,int length [,mixed driver_option]]])
           mixed parameter 是占位符,当用?问号参数时,parameter是占位符的从1开始的索引偏移,而不是‘?’,这和MYSQLI的预处理不相同。

           variable是绑定的变量值
    datatype有以下几种类型:
             PDO_PARAM_BOOL 布尔类型。
             PDO_PARAM_input_output 参数传给存储过程时使用此类型,可以在过程执行后修改。
             PDO_PARAM_INT 整型。
             PDO_PARAM_NULL NULL类型。
             PDO_PARAM_LOG   大对象类型。
             PDO_PARAM_STMT   PDO对象类型,当前不可操作。
             PDO_PARAM_STR   char,varchar和其它字符串类型。
    length指定数据类型长度。只有当赋为PDO_PARAM_input_output类型时才需要此参数。
    driver_option用来传递任何数据库驱动程序特定的选项。
       如:
           $q = "insert into city(city,countryid) values(?,?)";
           $stmt = $pdo->prepare($q);

           $city='大连';
           $country=1;
           $stmt->bindparam(1,$city); //注意这里parameter不是用“'?'”方式。并且从1开始偏移。
           $stmt->bindparam(2,$country);

           $stmt->execute();

    ---------------------
    预处理的绑定列:
    boolean PDOStatement::bindcolum(mixed column_index,mixed &param [,int type [,int maxlen[,mixed driver_options]]]);
    参数column_index是要绑定的行中列偏移,从1开始。当然也可以用列名。type就用来设置类型限制变量值,如PDO::PARAM_STR是限制文本,具体参bindParam()。通过maxlen限制其长度。
    try{
    $pdo = new PDO("mysql:host=localhost;dbname=forum","root","123456");
    }catch(PDOException $e){
    echo '连接错误:'.$e->errorcode();
    }

    $q="select * from city";
    $stmt=$pdo->prepare($q);
    $stmt->execute();
    $rscount=$stmt->rowcount(); //总记录数

    $stmt->bindcolumn(1,$cityid);
    $stmt->bindcolumn('city',$city,PDO::PARAM_STR,1);
    $stmt->bindcolumn(2,$countryid);

    for($i=1;$i<=$rscount;$i++)
    {
       $row = $stmt->fetch(PDO::FETCH_BOUND);
       printf("%s 的ID是: %s ",$city,$cityid);
       echo '<hr />';
    }

    **********************************************************
    用PDO处理事务:
    PDO->__construct()方法的作用是建立一个PDO链接数据库的实例。  
    PDO->beginTransaction(),PDO->commit(),PDO->rollBack()这三个方法是在支持回滚功能时一起使用的。PDO->beginTransaction()方法标明起始点,PDO->commit()方法标明回滚结束点,并执行SQL,PDO->rollBack()执行回滚。  
    <?php  
    try {  
        $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', '');  
        $dbh->query('set names utf8;');  
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    $dbh->beginTransaction();
        $dbh->exec("INSERT INTO `test`.`table` (`name` ,`age`)VALUES ('mick', 22);");  
        $dbh->exec("INSERT INTO `test`.`table` (`name` ,`age`)VALUES ('lily', 29);");  
        $dbh->exec("INSERT INTO `test`.`table` (`name` ,`age`)VALUES ('susan', 21);");  
    $dbh->commit();  
    } catch (Exception $e) {  
    $dbh->rollBack();
        echo "Failed: " . $e->getMessage();  
    }  
    ?>

    更多属性和详细介绍参:http://hi.baidu.com/traindiy/blog/item/06fd2b3f204fdce755e7232d.html

    另,参考:http://hi.baidu.com/traindiy/blog/item/c3ff98453ec873348694732c.html
    http://hi.baidu.com/traindiy

  • 相关阅读:
    OpenGL学习之路(四)
    OpenGL学习之路(三)
    ajax请求成功后新开窗口window.open()被拦截解决方法
    Mysql日志解析
    Kibana+Logstash+Elasticsearch 日志查询系统
    谈谈Redis的SETNX
    常用前端开发工具合集
    Media Queries 详解
    启动mysql时显示:/tmp/mysql.sock 不存在的解决方法
    找不到mysql.sock,mysql.sock丢失问题解决方法
  • 原文地址:https://www.cnblogs.com/xmphoenix/p/2054619.html
Copyright © 2011-2022 走看看