php PDO鏈接mysql

近期在linux裝了新的環境。php5.6+mysql5.5+nginx。php

而後用原來的mysql連接數據庫出現的錯誤。html

緣由就是說鏈接數據庫的方法太舊。建議我用mysqli和PDO來鏈接數據庫。前端

好吧。咱也不能落後,使用mysqli的確也簡單了很多。但是PDO貌似更簡單。mysql

效率也會獲得提高。依據官方文檔,貌似對於sql注入的一些風險也作了屏蔽。因此今天寫的 博客就是關於php用PDO鏈接mysql的一些介紹啦!linux


【PDO是啥】

PDO是PHP 5新增長的一個重大功能,因爲在PHP 5曾經的php4/php3都是一堆的數據庫擴展來跟各個數據庫的鏈接和處理,什麼php_mysql.dllphp_pgsql.dllphp_mssql.dllphp_sqlite.dll等等擴展來鏈接MySQLPostgreSQLMS SQL ServerSQLite。相同的,咱們必須藉助 ADOdbPEAR::DBPHPlib::DB之類的數據庫抽象類來幫助咱們,無比煩瑣和低效,畢竟,php代碼的效率怎麼能夠咱們直接用C/C++寫的擴展效率高捏?因此嘛,PDO的出現是一定的,你們要平靜學習的心態去接受使用,或許你會發現能夠下降你很多功夫哦。nginx



如下說說PDO基於php的版本號:

PDO 是 PHP 5.1 發行的,也就是說,在 5.1 以前的版本號是不支持 PDO,5.1以後的都支持啦。在PHP5.0的PECL擴展中也可以使用。sql


PDO怎樣使用:數據庫

這裏咱們就以PHP的黃金搭檔mysql做爲樣例看看:數組

PDO_MYSQL:PDO_MYSQL是PDO接口能夠完畢鏈接mysql數據庫的驅動(注:僅使用於mysql 3.x以上版本號)。安全

安裝:打開php.ini文件。可以找到例如如下代碼,這裏可以看到mysql的驅動默認已經打開(前面沒實用於凝視的分號),若有鏈接其它數據庫的需要,自行加入其它數據庫的驅動程序(取出對應的項前面的分號。沒有的添上)。

    //各數據庫的PDO驅動  
    extension=php_pdo.dll   
    extension=php_pdo_firebird.dll //Firebird  
    extension=php_pdo_informix.dll //Informix  
    extension=php_pdo_mssql.dll    //sql server  
    extension=php_pdo_mysql.dll    //mysql  
    extension=php_pdo_oci.dll      //Oracle  
    extension=php_pdo_oci8.dll   
    extension=php_pdo_odbc.dll     //DB2  
    extension=php_pdo_pgsql.dll    //PostgreSQL  
    extension=php_pdo_sqlite.dll   //SQLite  

鏈接:經過建立PDO基類的實例建立鏈接。


    //鏈接到數據庫  
    $db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);  


簡單的查詢方法:

<?

php header('content-type:text/html;charset=utf-8'); try { $db = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', ''); //查詢 $rows = $db->query('SELECT * from members')->fetchAll(PDO::FETCH_ASSOC); $rs = array(); foreach($rows as $row) { $rs[] = $row; } $db = null; } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } print_r($rs); ?>



不明確啥意思,俺們來慢慢講講。這行:
$dsn = "mysql:host=127.0.0.1;dbname=test";
就是構造咱們的DSN(數據源),看看裏面的信息包含:數據庫類型是mysql,主機地址是localhost。數據庫名稱是test。就這麼幾個信息。

不一樣數據庫的數據源構造方式是不同的。

$db = new PDO($dsn, 'root', '');
初始化一個PDO對象,構造函數的參數第一個就是咱們的數據源,第二個是鏈接數據庫server的用戶,第三個參數是password。

咱們不能保證鏈接成功。後面咱們會講到異常狀況,這裏咱們姑且以爲它是鏈接成功的。

$count = $db->exec("INSERT INTO foo SET name = 'heiyeluren',gender='男',time=NOW()");
echo $count;
調用咱們鏈接成功的PDO對象來運行一個查詢。這個查詢是一個插入一條記錄的操做,使用PDO::exec() 方法會返回一個影響記錄的結果,因此咱們輸出這個結果。最後仍是需要結束對象資源:
$db = null;

默認這個不是長鏈接。假設需要數據庫長鏈接。需要最後加一個參數:array(PDO::ATTR_PERSISTENT => true)變成這樣:
$db = new PDO($dsn, 'root', '', array(PDO::ATTR_PERSISTENT => true));

一次操做就這麼簡單,或許跟曾經的沒有太大差異。跟ADOdb卻是有幾分類似。



使用setFetchMode方法來設置獲取結果集的返回值的類型,相同類型還有:

PDO::FETCH_ASSOC
-- 關聯數組形式
PDO::FETCH_NUM -- 數字索引數組形式
PDO::FETCH_BOTH -- 二者數組形式都有,這是缺省的

PDO::FETCH_OBJ -- 依照對象的形式,相似於曾經的 mysql_fetch_object()

$db->query($sql); 當$sql 中變量可以用$dbh->quote($params); //轉義字符串的數據  


php pdo statement

PDOStatement::bindColumn — 綁定一列到一個 PHP 變量  
PDOStatement::bindParam — 綁定一個參數到指定的變量名  
PDOStatement::bindValue — 把一個值綁定到一個參數  
PDOStatement::closeCursor — 關閉遊標,使語句能再次被運行。  
PDOStatement::columnCount — 返回結果集中的列數  
PDOStatement::debugDumpParams — 打印一條 SQL 預處理命令  
PDOStatement::errorCode — 獲取跟上一次語句句柄操做相關的 SQLSTATE  
PDOStatement::errorInfo — 獲取跟上一次語句句柄操做相關的擴展錯誤信息  
PDOStatement::execute — 運行一條預處理語句  
PDOStatement::fetch — 從結果集中獲取下一行  
PDOStatement::fetchAll — 返回一個包括結果集中所有行的數組  
PDOStatement::fetchColumn — 從結果集中的下一行返回單獨的一列。

PDOStatement::fetchObject — 獲取下一行並做爲一個對象返回。 PDOStatement::getAttribute — 檢索一個語句屬性 PDOStatement::getColumnMeta — 返回結果集中一列的元數據 PDOStatement::nextRowset — 在一個多行集語句句柄中推動到下一個行集 PDOStatement::rowCount — 返回受上一個 SQL 語句影響的行數 PDOStatement::setAttribute — 設置一個語句屬性 PDOStatement::setFetchMode — 爲語句設置默認的獲取模式。



插入,更新。刪除數據,

$db->exec("DELETE FROM `xxxx_menu` where mid=43");


講一下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(); } ?>



現在你已經經過PDO創建了鏈接。在部署查詢以前你必須搞明確PDO是如何管理事務的。

假設你曾經從未遇到過事務處理,(現在簡介一下:)它們提供了4個基本的特性:原子性,一致性,獨立性和持久性(Atomicity, Consistency, Isolation and Durability,ACID)通俗一點講,一個事務中所有的工做在提交時。即便它是分階段運行的。也要保證安全地應用於數據庫,不被其它的鏈接干擾。事務工做也可以在請求錯誤發生時輕鬆地本身主動取消。

事務的典型運用就是經過把批量的改變「保存起來」而後立刻運行。這樣就會有完全地提升更新效率的優勢。換句話說。事務可以使你的腳本更高速同一時候可能更健壯(要實現這個優勢你仍然需要正確的使用它們)。

不幸運的是,並不是每個數據庫都支持事務,所以PDO需要在創建鏈接時執行在被以爲是「本身主動提交」的模式下。本身主動提交模式意味着你執行的每個查詢都有它本身隱含的事務處理。無論數據庫支持事務仍是因數據庫不支持而不存在事務。假設你需要一個事務,你必須使用 PDO->beginTransaction() 方法建立一個。

假設底層驅動不支持事務處理。一個PDOException就會被拋出(與你的異常處理設置無關。因爲這老是一個嚴重的錯誤狀態)。

在一個事物中,你可以使用 PDO->commit() 或 PDO->rollBack() 結束它,這取決於事務中代碼執行是否成功。

當腳本結束時或一個鏈接要關閉時,假設你另外一個未處理完的事務,PDO將會本身主動將其回滾。這是對於腳本意外終止的狀況來講是一個安全的方案——假設你沒有明白地提交事務。它將會假設發生了一些錯誤,爲了你數據的安全,因此就運行回滾了。


PDOException

PDO 提供了3中不一樣的錯誤處理策略。
1. PDO::ERRMODE_SILENT
這是默認使用的模式。

PDO會在statement和database對象上設定簡單的錯誤代號,你可以使用PDO->errorCode() 和 PDO->errorInfo() 方法檢查錯誤;假設錯誤是在對statement對象進行調用時致使的。你就可以在那個對象上使用 PDOStatement->errorCode() 或 PDOStatement->errorInfo() 方法取得錯誤信息。

而假設錯誤是在對database對象調用時致使的,你就應該在這個database對象上調用那兩個方法。


2. PDO::ERRMODE_WARNING
做爲設置錯誤代號的附加,PDO將會發出一個傳統的E_WARNING信息。這樣的設置在除錯和調試時是很是實用的,假設你僅僅是想看看發生了什麼問題而不想中斷程序的流程的話。
3. PDO::ERRMODE_EXCEPTION
做爲設置錯誤代號的附件,PDO會拋出一個PDOException異常並設置它的屬性來反映錯誤代號和錯誤信息。

這中設置在除錯時也是很是實用的,因爲他會有效的「放大(blow up)」腳本中的出錯點,很是高速的指向一個你代碼中可能出錯區域。(記住:假設異常致使腳本中斷,事務處理回本身主動回滾。)
異常模式也是很實用的。因爲你可使用比曾經那種使用傳統的PHP風格的錯誤處理結構更清晰的結構處理錯誤。比使用安靜模式使用更少的代碼及嵌套,也能夠更加明白地檢查每個數據庫訪問的返回值。


關於PHP中異常的不少其它信息請看Exceptions章節
PDO 使用基於SQL-92 SQLSTATE 的錯誤代號字符串;特定的PDO驅動應當將本身自己的代號相應到適當的SQLSTATE代號上。

PDO->errorCode() 方法僅僅返回單一的SQLSTATE代號。

假設你需要關於一個錯誤的更加有針對性的信息,PDO也提供了一個PDO->errorInfo()方法,它可以返回一個包括了SQLSTATE代號,特定數據庫驅動的錯誤代號和特定數據庫驅動的錯誤說明字符串。


<?php
// 改動默認的錯誤顯示級別
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
?

>



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([intcolumn_indexnum])用於直接訪問列。參數column_indexnum是該列在行中的從0開始索引值。但是,這種方法一次僅僅能取得同一行的一列,僅僅要運行一次,就跳到下一行。

所以,用於直接訪問某一列時較好用,但要遍歷多列就用不上。
PDOStatement::rowcount()適用於當用query("select...")方法時,獲取記錄的條數。也可以用於預處理中。$stmt->rowcount();
PDOStatement::columncount()適用於當用query("select...")方法時。獲取記錄的列數。

註解:
一、選fetch仍是fetchall?

小記錄集時。用fetchall效率高,下降從數據庫檢索次數。但對於大結果集,用fetchall則給系統帶來很是大負擔。

數據庫要向WEB前端傳輸量太大反而效率低。
二、fetch()或fetchall()有幾個參數:
mixed pdostatement::fetch([int fetch_style[,int cursor_orientation [,int cursor_offset]]])
array pdostatement::fetchAll(int fetch_style)


不少其它的PDO方法:

    PDO::beginTransaction — 啓動一個事務  
    PDO::commit — 提交一個事務  
    PDO::__construct — 建立一個表示數據庫鏈接的 PDO 實例  
    PDO::errorCode — 獲取跟數據庫句柄上一次操做相關的 SQLSTATE  
    PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle  
    PDO::exec — 運行一條 SQL 語句,並返回受影響的行數  
    PDO::getAttribute — 取回一個數據庫鏈接的屬性  
    PDO::getAvailableDrivers — 返回一個可用驅動的數組  
    PDO::inTransaction — 檢查是否在一個事務內  
    PDO::lastInsertId — 返回最後插入行的ID或序列值  
    PDO::prepare — Prepares a statement for execution and returns a statement object  
    PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object  
    PDO::quote — Quotes a string for use in a query.  
    PDO::rollBack — 回滾一個事務  
    PDO::setAttribute — 設置屬性  

    Exception::getMessage — 獲取異常消息內容。  
    Exception::getPrevious — 返回異常鏈中的前一個異常  
    Exception::getCode — 獲取異常代碼  
    Exception::getFile — 獲取發生異常的程序文件名  
    Exception::getLine — 獲取發生異常的代碼在文件裏的行號  
    Exception::getTrace — 獲取異常追蹤信息  
    Exception::getTraceAsString — 獲取字符串類型的異常追蹤信息  
    Exception::toString — 將異常對象轉換爲字符串  
    Exception::clone — 異常克隆  

屬性列表:

PDO::PARAM_BOOL
表示一個布爾類型
PDO::PARAM_NULL
表示一個SQL中的NULL類型
PDO::PARAM_INT
表示一個SQL中的INTEGER類型
PDO::PARAM_STR
表示一個SQL中的SQL CHAR。VARCHAR類型
PDO::PARAM_LOB
表示一個SQL中的large object類型
PDO::PARAM_STMT
表示一個SQL中的recordset類型,尚未被支持
PDO::PARAM_INPUT_OUTPUT
Specifies that the parameter is an INOUT parameter for a stored procedure. You must bitwise-OR this value with an explicit PDO::PARAM_* data type.
PDO::FETCH_LAZY
將每一行結果做爲一個對象返回
PDO::FETCH_ASSOC
僅僅返回以鍵值做爲下標的查詢的結果集,名稱一樣的數據僅僅返回一個
PDO::FETCH_NAMED
僅僅返回以鍵值做爲下標的查詢的結果集。名稱一樣的數據以數組形式返回
PDO::FETCH_NUM
僅僅返回以數字做爲下標的查詢的結果集
PDO::FETCH_BOTH
同一時候返回以鍵值和數字做爲下標的查詢的結果集
PDO::FETCH_OBJ
以對象的形式返回結果集
PDO::FETCH_BOUND
將PDOStatement::bindParam()和PDOStatement::bindColumn()所綁定的值做爲變量名賦值後返回
PDO::FETCH_COLUMN
表示僅僅返回結果集中的某一列
PDO::FETCH_CLASS
表示以類的形式返回結果集
PDO::FETCH_INTO
表示將數據合併入一個存在的類中進行返回
PDO::FETCH_FUNC
PDO::FETCH_GROUP
PDO::FETCH_UNIQUE
PDO::FETCH_KEY_PAIR
以首個鍵值下表。後面數字下表的形式返回結果集
PDO::FETCH_CLASSTYPE
PDO::FETCH_SERIALIZE
表示將數據合併入一個存在的類中並序列化返回
PDO::FETCH_PROPS_LATE
Available since PHP 5.2.0
PDO::ATTR_AUTOCOMMIT
在設置成true的時候,PDO會本身主動嘗試中止接受託付,開始運行
PDO::ATTR_PREFETCH
設置應用程序提早獲取的數據大小,並非所有的數據庫哦度支持
PDO::ATTR_TIMEOUT
設置鏈接數據庫超時的值
PDO::ATTR_ERRMODE
設置Error處理的模式
PDO::ATTR_SERVER_VERSION
僅僅讀屬性,表示PDO鏈接的server端數據庫版本號
PDO::ATTR_CLIENT_VERSION
僅僅讀屬性。表示PDO鏈接的clientPDO驅動版本號
PDO::ATTR_SERVER_INFO
僅僅讀屬性,表示PDO鏈接的server的meta信息
PDO::ATTR_CONNECTION_STATUS
PDO::ATTR_CASE
經過PDO::CASE_*中的內容對列的形式進行操做
PDO::ATTR_CURSOR_NAME
獲取或者設定指針的名稱
PDO::ATTR_CURSOR
設置指針的類型,PDO現在支持PDO::CURSOR_FWDONLY和PDO::CURSOR_FWDONLY
PDO::ATTR_DRIVER_NAME
返回使用的PDO驅動的名稱
PDO::ATTR_ORACLE_NULLS
將返回的空字符串轉換爲SQL的NULL
PDO::ATTR_PERSISTENT
獲取一個存在的鏈接
PDO::ATTR_STATEMENT_CLASS
PDO::ATTR_FETCH_CATALOG_NAMES
在返回的結果集中,使用本身定義文件夾名稱來取代字段名。
PDO::ATTR_FETCH_TABLE_NAMES
在返回的結果集中,使用本身定義表格名稱來取代字段名。
PDO::ATTR_STRINGIFY_FETCHES
PDO::ATTR_MAX_COLUMN_LEN
PDO::ATTR_DEFAULT_FETCH_MODE
Available since PHP 5.2.0
PDO::ATTR_EMULATE_PREPARES
Available since PHP 5.1.3.
PDO::ERRMODE_SILENT
錯誤發生時不彙報不論什麼的錯誤信息。是默認值
PDO::ERRMODE_WARNING
錯誤發生時發出一條php的E_WARNING的信息
PDO::ERRMODE_EXCEPTION
錯誤發生時拋出一個PDOException
PDO::CASE_NATURAL
回覆列的默認顯示格式
PDO::CASE_LOWER
強制列的名字小寫
PDO::CASE_UPPER
強制列的名字大寫
PDO::NULL_NATURAL
PDO::NULL_EMPTY_STRING
PDO::NULL_TO_STRING
PDO::FETCH_ORI_NEXT
獲取結果集中的下一行數據。僅在有指針功能時有效
PDO::FETCH_ORI_PRIOR
獲取結果集中的上一行數據,僅在有指針功能時有效
PDO::FETCH_ORI_FIRST
獲取結果集中的第一行數據。僅在有指針功能時有效
PDO::FETCH_ORI_LAST
獲取結果集中的最後一行數據,僅在有指針功能時有效
PDO::FETCH_ORI_ABS
獲取結果集中的某一行數據,僅在有指針功能時有效
PDO::FETCH_ORI_REL
獲取結果集中當前行後某行的數據。僅在有指針功能時有效
PDO::CURSOR_FWDONLY
創建一個僅僅能向後的指針操做對象
PDO::CURSOR_SCROLL
創建一個指針操做對象。傳遞PDO::FETCH_ORI_*中的內容來控制結果集
PDO::ERR_NONE (string)
設定沒有錯誤時候的錯誤信息

    <?php  
    $dbh = new PDO('mysql:host=localhost;dbname=access_control', 'root', '');    
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    
    $dbh->exec('set names utf8');   
    /*加入*/  
    //$sql = "INSERT INTO `user` SET `login`=:login AND `password`=:password";   
    $sql = "INSERT INTO `user` (`login` ,`password`)VALUES (:login, :password)";  $stmt = $dbh->prepare($sql);  $stmt->execute(array(':login'=>'kevin2',':password'=>''));    
    echo $dbh->lastinsertid();    
    /*改動*/  
    $sql = "UPDATE `user` SET `password`=:password WHERE `user_id`=:userId";    
    $stmt = $dbh->prepare($sql);    
    $stmt->execute(array(':userId'=>'7', ':password'=>'4607e782c4d86fd5364d7e4508bb10d9'));    
    echo $stmt->rowCount();   
    /*刪除*/  
    $sql = "DELETE FROM `user` WHERE `login` LIKE 'kevin_'"; //kevin%    
    $stmt = $dbh->prepare($sql);    
    $stmt->execute();    
    echo $stmt->rowCount();    
    /*查詢*/  
    $login = 'kevin%';    
    $sql = "SELECT * FROM `user` WHERE `login` LIKE :login";    
    $stmt = $dbh->prepare($sql);    
    $stmt->execute(array(':login'=>$login));    
    while($row = $stmt->fetch(PDO::FETCH_ASSOC)){       
     print_r($row);    
    }    
    print_r( $stmt->fetchAll(PDO::FETCH_ASSOC));   
    ?>  
相關文章
相關標籤/搜索