喵喵笨兔 の 喵喵的家~遊戲天地 - 首頁(上版面)
喵喵笨兔 の 喵喵的家~遊戲天地 - 首頁(左版面)
首  頁 最新消息 遊戲攻略 遊戲影片 遊戲圖片 下載區 學習分享 留言板 FB粉絲團
 喵喵笨兔 の 喵喵的家~遊戲天地 - PHP Data Objects (PDO) 讀取資料庫 (MySQL、MS SQL Server、PostgreSQL、SQLite..) 使用概要說明

PHP Data Objects (PDO) 讀取資料庫 (MySQL、MS SQL Server、PostgreSQL、SQLite..) 使用概要說明

PHP Data Objects (PDO) 簡介

 PDO 為物件導向的設計,增強安全性,節省更多的時間,語法通用於各種資料庫。基本上只要 PHP 5.5 以上版本就有內建 PDO 了。功能大致如下:

  • PDO 通用各資料庫 (mysql、mssql、odbc、pgsql、sqlite、firebird、informix),且可以隨時切換成其他資料庫。其中像 MySQL 因 PHP 版本不同須用 mysql 或 mysqli,PDO 語法可適用於任何版本,不須做更換。
  • 使用物件導向的PDO,將可以節省更多的時間,增強安全性,避免可能的 SQL 注入 (sql injection)。
  • 可以將查詢到的資料直接轉成對應的物件。

 倘若連結 PDO 出現錯誤訊息 Uncaught PDOException: could not find driver,找尋您安裝 php 網站資料夾內的 php.ini 檔案,並用文書編輯軟體 (如記事本或 Notepad++) 開啟。找到以下資料列,把前面的 ; 去掉,存檔後重啟 apache 即可!(有 ; 是不執行該行之意)
  ;extension=php_pdo_mysql.dll
 上列是連結 MySQL 資料庫。若您是連結 pgSQL,則要找 ;extension=php_pdo_pgsql.dll。倘若不知道,那就把有 ;php_pdo_XXXXX.dll 字樣的 ; 全拿掉唄!

php 用 PDO 連接 MySQL 資料庫

 初接觸PDO,此篇是給自己參考記錄的,若有需者就參考唄!以連接笨兔網站的 MySQL 資料庫,取得【學習分享】的資料來做展示,範例設定的 MySQL 相關名稱如下。若不知這些名稱所在,可參考笨兔另一篇隨手筆記【db_001】phpMyAdmin & MySQL 資料庫和資料表的建立、修改、刪除和備份 使用簡介

  • 伺服器名稱: localhost
  • 使用者帳號: root
  • 使用者密碼: 12345678
  • 資料庫名稱: pcgame
  • 資料表名稱: learn
  • 資料表欄位名稱: l_id、l_date、l_sort、l_number、l_description、l_url 共有6個欄位

範例程式碼:主要看紅色字部份

<?php    

// (範例一) 連結資料庫語法
// $dsn = "資料庫形態:host=伺服器名稱;dbname=資料庫名稱;charset=編碼";
// $conn = new PDO($dsn, '帳號', '密碼');
// 此用 mysql 資料庫,若是用其他如 MS SQL,則把 mysql 改成 mssql 即可!
  $dsn = "mysql:host=localhost;dbname=pcgame;charset=utf8";
  $conn = new PDO($dsn, 'root', '12345678');

// 查詢結果:最簡單的 Query 指令
// $rs = $conn->query('SQL資料表條件');
  $sql = "select * from learn limit 5"; //SQL資料表條件,笨兔只顯示5筆做展示,所以設limit 5
  $rs = $conn->query($sql);

  $total = $rs -> rowCount(); //計算筆數寫法

// 連結資料庫偵錯(建議用範例三 try...catch 方式)
// 若有錯誤會顯示 Array ([0] =>SQLSTATE error code,00000就是正常 [1] =>所用的Driver所傳回的錯誤碼 [2] =>所用的Driver傳回的錯誤訊息)
if ($rs->errorCode()!=00000){
echo "有錯誤訊息如下!";
print_r($rs->errorInfo());
}

//foreach 獲取資料放入表格顯示資料
echo '<table>';
echo '筆數 = '.$total;
foreach($rs as $row){
echo '<tr>';
echo '<td>'.$row[0].'</td>';
echo '<td>'.$row[1].'</td>';
echo '<td>'.$row[2].'</td>';
echo '<td>'.$row['l_number'].'</td>';
echo '<td>'.$row['l_description'].'</td>';
echo '<td>'.$row['l_url'].'</td>';
echo '</tr>';
}
echo '</table>';
?>
<?php    

// (範例二) 另一種寫法:prepare 指令,避免 sql injection,安全性較高。若要更細部就查查 prepare 指令唄!
  $dsn = "mysql:host=localhost;dbname=pcgame;charset=utf8";
  $conn = new PDO($dsn, 'root', '12345678');

  $sql = "select * from learn limit 5";
  $rs = $conn->prepare($sql);
  $rs->execute();

echo '<table>';
foreach($rs as $row){
echo '<tr>';
echo '<td>'.$row[0].'</td>';
echo '<td>'.$row[1].'</td>';
echo '<td>'.$row[2].'</td>';
echo '<td>'.$row['l_number'].'</td>';
echo '<td>'.$row['l_description'].'</td>';
echo '<td>'.$row['l_url'].'</td>';
echo '</tr>';
}
echo '</table>';
?>
<?php    

// (範例三) 用 try...catch 來對資料庫連線偵錯!
try{
  $dsn = "mysql:host=localhost;dbname=pcgame;charset=utf8";
  $conn = new PDO($dsn, 'root', '12345678');

  //發生錯誤出現錯誤提醒
  $conn -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
//發生錯誤結束資料庫連線並顯示錯誤訊息
die($e -> getMessage());
}

  $sql = "select * from learn limit 5";
  $rs = $conn->prepare($sql);
  $rs->execute();

echo '<table>';
foreach($rs as $row){
echo '<tr>';
echo '<td>'.$row[0].'</td>';
echo '<td>'.$row[1].'</td>';
echo '<td>'.$row[2].'</td>';
echo '<td>'.$row['l_number'].'</td>';
echo '<td>'.$row['l_description'].'</td>';
echo '<td>'.$row['l_url'].'</td>';
echo '</tr>';
}
echo '</table>';
?>
異常處理說明:
 PHP:預設為直接報錯。
 MYSQL:預設為靜默模式,錯就錯,不報錯。
 PDO:預設為靜默模式,錯就錯,不報錯。

以前 PHP 碰到錯誤的時候,會直接報錯,錯誤處理會變得相當麻煩。後來,當錯誤發生之後,會將錯誤資訊不再直接輸出,放到一個類的物件裡(PDOException)。
PDO 異常處理設定:PDO::ATTR_ERRMODE ,有以下三個值:
 PDO::ERRMODE_SILENT: 預設模式,不主動報錯,需要主動以 $pdo->errorInfo()的形式獲取錯誤資訊。(範例一)
 PDO::ERRMODE_WARNING: 引發 E_WARNING 錯誤,主動報錯
 PDO::ERRMODE_EXCEPTION: 主動丟擲 exceptions 異常,需要以try{}cath(){}輸出錯誤資訊。(範例三)

範例結果:

筆數 = 5
12017-09-10遊戲game_001玩遊戲時的相容性問題參考解決法 (玩舊遊戲無法PLAY或執行修改器無作用)game_001.html
142017-09-12網頁html_002所架設的 php 網站無法開 https:// 的網址或有問題!html_002.html
152017-09-12網頁html_003Apache + PHP + MySQL 所架設的 php 網站,更改網頁根目錄及首頁預設檔!html_003.html
132017-09-12網頁html_001PHP 架站軟體 AppServ 懶人包:Apache + PHP + MySQL 相關介紹及說明 ^^html_001.html
162017-09-13網頁html_004讓網頁製作表格 (table) 的表格框變細,表格單、雙數行底色不同html_004.html

  • 上面範例程式碼的foreach($rs as $row){ },也可用迴圈方式來取得資料,如:
    while($row = $rs->fetch(PDO::FETCH_ASSOC)){ }
    do { } while($row = $rs->fetch(PDO::FETCH_NUM));
  • PDO::FETCH_ASSOC可以用字串取出欄位資料如 $row['l_url']。
    PDO::FETCH_NUM可以用索引取出欄位資料如 $row[0]。
    PDO::FETCH_BOTH則字串、索引都可以。
    PDO::FETCH_OBJ可以用物件表示法取出資料如 $row->room。
    PDO::FETCH_LAZY則字串、索引、物件都可以。
  • PDO::setAttribute 設置屬性。設置數據庫句柄屬性。下面列出了一些可用的通用屬性;有些驅動可能使用另外的特定屬性。
    PDO::ATTR_CASE:強制列名為指定的大小寫。
    PDO::CASE_LOWER:強制列名小寫。
    PDO::CASE_NATURAL:保留數據庫驅動返回的列名。
    PDO::CASE_UPPER:強制列名大寫。
    PDO::ATTR_ERRMODE:錯誤報告。
    PDO::ERRMODE_SILENT: 僅設置錯誤代碼。
    PDO::ERRMODE_WARNING: 引發 E_WARNING 錯誤
    PDO::ERRMODE_EXCEPTION: 拋出 exceptions 異常。
    PDO::ATTR_ORACLE_NULLS (在所有驅動中都可用,不僅限於Oracle): 轉換 NULL 和空字符串。
    PDO::NULL_NATURAL: 不轉換。
    PDO::NULL_EMPTY_STRING: 將空字符串轉換成 NULL。
    PDO::NULL_TO_STRING: 將 NULL 轉換成空字符串。
    PDO::ATTR_STRINGIFY_FETCHES: 提取的時候將數值轉換為字符串。 Requires bool.
    PDO::ATTR_STATEMENT_CLASS: 設置從PDOStatement派生的用戶提供的語句類。 不能用於持久的PDO實例。需要 array(string 類名, array(mixed 構造函數的參數))。
    PDO::ATTR_TIMEOUT: 指定超時的秒數。並非所有驅動都支持此選項,這意味著驅動和驅動之間可能會有差異。比如,SQLite等待的時間達到此值後就放棄獲取可寫鎖,但其他驅動可能會將此值解釋為一個連接或讀取超時的間隔。 需要 int 類型。
    PDO::ATTR_AUTOCOMMIT (在OCI,Firebird 以及 MySQL中可用): 是否自動提交每個單獨的語句。
    PDO::ATTR_EMULATE_PREPARES 啟用或禁用預處理語句的模擬。 有些驅動不支持或有限度地支持本地預處理。使用此設置強制PDO總是模擬預處理語句(如果為 TRUE ),或試著使用本地預處理語句(如果為 FALSE)。如果驅動不能成功預處理當前查詢,它將總是回到模擬預處理語句上。 需要 bool 類型。
    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (在MySQL中可用): 使用緩沖查詢。
    PDO::ATTR_DEFAULT_FETCH_MODE: 設置默認的提取模式。關於模式的說明可以在 PDOStatement::fetch() 文檔找到。
    <?php
    //例:設置返回列名稱的大小寫
    $conn = new PDO($dsn, $user, $pass);
    $conn -> setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
    ?>

 ※PHP Data Objects (PDO) 與 MySQL 資料庫相關應用,可參考笨兔其它隨手筆記:

笨兔隨手筆記於 2019/4/12

喵喵笨兔 の 喵喵的家~遊戲天地
http://vv0817.tk
http://vvv.lionfree.net
http://vvv.myweb.hinet.net