php PDO串連mysql,phppdomysql

來源:互聯網
上載者:User

php PDO串連mysql,phppdomysql

最近在linux裝了新的環境,php5.6+mysql5.5+nginx。然後用原來的mysql連結資料庫出現的錯誤。

原因就是說串連資料庫的方法太舊。建議我用mysqli和PDO來串連資料庫。

好吧,咱也不能落後,使用mysqli的確也簡單了不少,但是PDO貌似更簡單。效率也會得到提升。根據官方文檔,貌似對於sql注入的一些風險也做了屏蔽。所以今天寫的 部落格就是關於php用PDO串連mysql的一些介紹啦!


【PDO是啥】

PDO是PHP 5新加入的一個重大功能,因為在PHP 5以前的php4/php3都是一堆的資料庫擴充來跟各個資料庫的串連和處理,什麼php_mysql.dll、php_pgsql.dll、php_mssql.dll、php_sqlite.dll等等擴充來串連MySQL、PostgreSQL、MS SQL Server、SQLite,同樣的,我們必須藉助 ADOdb、PEAR::DB、PHPlib::DB之類的資料庫抽象類別來協助我們,無比煩瑣和低效,畢竟,php代碼的效率怎麼能夠我們直接用C/C++寫的擴充效率高捏?所以嘛,PDO的出現是必然的,大家要平靜學習的心態去接受使用,也許你會發現能夠減少你不少功夫哦。



下面說說PDO基於php的版本:

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


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);  


簡單的查詢方法:
<?phpheader('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對象,建構函式的參數第一個就是我們的資料來源,第二個是串連資料庫伺服器的使用者,第三個參數是密碼。我們不能保證串連成功,後面我們會講到異常情況,這裡我們姑且認為它是串連成功的。

$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()執行復原。

<?phptry {$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...")方法時,擷取記錄的列數。

註解:
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)


更多的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_OUTPUTSpecifies 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_FUNCPDO::FETCH_GROUPPDO::FETCH_UNIQUEPDO::FETCH_KEY_PAIR以首個索引值下表,後面數字下表的形式返回結果集PDO::FETCH_CLASSTYPEPDO::FETCH_SERIALIZE表示將資料合併入一個存在的類中並序列化返回PDO::FETCH_PROPS_LATEAvailable since PHP 5.2.0PDO::ATTR_AUTOCOMMIT在設定成true的時候,PDO會自動嘗試停止接受委託,開始執行PDO::ATTR_PREFETCH設定應用程式提前擷取的資料大小,並非所有的資料庫哦度支援PDO::ATTR_TIMEOUT設定串連資料庫逾時的值PDO::ATTR_ERRMODE設定Error處理的模式PDO::ATTR_SERVER_VERSION唯讀屬性,表示PDO已連線的服務器端資料庫版本PDO::ATTR_CLIENT_VERSION唯讀屬性,表示PDO串連的用戶端PDO驅動版本PDO::ATTR_SERVER_INFO唯讀屬性,表示PDO已連線的服務器的meta資訊PDO::ATTR_CONNECTION_STATUSPDO::ATTR_CASE通過PDO::CASE_*中的內容對列的形式進行操作PDO::ATTR_CURSOR_NAME擷取或者設定指標的名稱PDO::ATTR_CURSOR設定指標的類型,PDO現在支援PDO::CURSOR_FWDONLY和PDO::CURSOR_FWDONLYPDO::ATTR_DRIVER_NAME返回使用的PDO驅動的名稱PDO::ATTR_ORACLE_NULLS將返回的Null 字元串轉換為SQL的NULLPDO::ATTR_PERSISTENT擷取一個存在的串連PDO::ATTR_STATEMENT_CLASSPDO::ATTR_FETCH_CATALOG_NAMES在返回的結果集中,使用自訂目錄名稱來代替欄位名。PDO::ATTR_FETCH_TABLE_NAMES在返回的結果集中,使用自訂表格格名稱來代替欄位名。PDO::ATTR_STRINGIFY_FETCHESPDO::ATTR_MAX_COLUMN_LENPDO::ATTR_DEFAULT_FETCH_MODEAvailable since PHP 5.2.0PDO::ATTR_EMULATE_PREPARESAvailable since PHP 5.1.3.PDO::ERRMODE_SILENT發生錯誤時不彙報任何的錯誤資訊,是預設值PDO::ERRMODE_WARNING發生錯誤時發出一條php的E_WARNING的資訊PDO::ERRMODE_EXCEPTION發生錯誤時拋出一個PDOExceptionPDO::CASE_NATURAL回複列的預設顯示格式PDO::CASE_LOWER強制列的名字小寫PDO::CASE_UPPER強制列的名字大寫PDO::NULL_NATURALPDO::NULL_EMPTY_STRINGPDO::NULL_TO_STRINGPDO::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));       ?>  




php使用pdo串連mysql資料庫,得到空?

為什麼要用pdo呢?
php提供的連結myql資料庫的函數很強大了啊,下邊是個執行個體
<?php
//資料庫公開連結檔案
$hostname = 'localhost';
$username = '';
$password = '';
mysql_connect($hostname,$username,$password) or die("資料庫連結失敗!");
@mysql_select_db('test') or die("資料庫不存在或不可用!");
mysql_query("set names utf8");
?>
 
php串連mysql 有pdo類串連改為普通連結怎更改

不是,所有函數用法都不一樣
如果你使用的是架構,那麼可能直接設定資料庫連接就可以改過來。
如果你是自己寫的資料庫連接,那麼就得看下手冊,使用你要的方式來串連和操作資料庫
 

相關文章

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.