PDO使用歸納【PHP】

來源:互聯網
上載者:User

【任務】將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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.