国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
為什么你應(yīng)該使用PHP PDO訪問(wèn)數(shù)據(jù)庫(kù)

為什么你應(yīng)該使用PHP PDO訪問(wèn)數(shù)據(jù)庫(kù)

許多PHP程序員學(xué)習(xí)過(guò)如歌使用MySQL或MySQL擴(kuò)展來(lái)訪問(wèn)數(shù)據(jù)庫(kù). 不過(guò),自PHP 5.1版本以來(lái),一個(gè)更好的解決方案出現(xiàn)了. PHP Data Objects (PDO) 提供了讓你更有{productive}的準(zhǔn)備{statements},處理對(duì)象的方法.


PDO 簡(jiǎn)介

“PDO – PHP Data Objects – is a database access layer providing a uniform method of access to multiple databases.”

它不受數(shù)據(jù)庫(kù)特定語(yǔ)法限制, 但它可以讓切換數(shù)據(jù)庫(kù)和平臺(tái)的過(guò)程更無(wú)痛,更簡(jiǎn)潔的切換數(shù)據(jù)庫(kù)連接字符串.

這個(gè)教程并是一個(gè)完全的SQL入門. 它主要是為了幫助那些已經(jīng)在使用MySQL或MySQLi擴(kuò)展的人們過(guò)渡到更加強(qiáng)大、兼容性更好的PDO.

數(shù)據(jù)庫(kù)支持

這個(gè)擴(kuò)展能支持任何為PDO設(shè)計(jì)了驅(qū)動(dòng)的數(shù)據(jù)庫(kù). 在寫這篇文章的時(shí)候,以下數(shù)據(jù)庫(kù)已經(jīng)被支持:

  • PDO_DBLIB ( FreeTDS / Microsoft SQL Server / Sybase )
  • PDO_FIREBIRD ( Firebird/Interbase 6 )
  • PDO_IBM ( IBM DB2 )
  • PDO_INFORMIX ( IBM Informix Dynamic Server )
  • PDO_MYSQL ( MySQL 3.x/4.x/5.x )
  • PDO_OCI ( Oracle Call Interface )
  • PDO_ODBC ( ODBC v3 (IBM DB2, unixODBC and win32 ODBC) )
  • PDO_PGSQL ( PostgreSQL )
  • PDO_SQLITE ( SQLite 3 and SQLite 2 )
  • PDO_4D ( 4D )

所有這些驅(qū)動(dòng)都沒(méi)有被您的系統(tǒng)預(yù)裝,這里有一種快速的方式來(lái)找到您需要的驅(qū)動(dòng):

print_r(PDO::getAvailableDrivers());


連接

不同的數(shù)據(jù)庫(kù)可能在連接方法上有那么一點(diǎn)點(diǎn)的不同. 下面,我們將介紹幾種常見(jiàn)的數(shù)據(jù)庫(kù)的連接方法. 你將會(huì)注意到前三種看起來(lái)差不多, 不過(guò)像SQLite之類的語(yǔ)言就有他自己獨(dú)特的語(yǔ)法.

try {
# MS SQL Server and Sybase with PDO_DBLIB
$DBH = new PDO(“mssql:host=$host;dbname=$dbname, $user, $pass”);
$DBH = new PDO(“sybase:host=$host;dbname=$dbname, $user, $pass”);
# MySQL with PDO_MYSQL
$DBH = new PDO(“mysql:host=$host;dbname=$dbname”, $user, $pass);
# SQLite Database
$DBH = new PDO(“sqlite:my/database/path/database.db”);
}
catch(PDOException $e) {
echo $e->getMessage();
}

請(qǐng)注意try/catch代碼塊 – 您應(yīng)該始終將您 PDO 的操作封裝在一個(gè) try/catch 代碼塊內(nèi)并使用異常機(jī)制 .通常你只會(huì)使用單個(gè)連接 – 下面將為您介紹它的語(yǔ)法.

下文中出現(xiàn)的 $DBH 意思是 ‘database handle’.

你可以通過(guò)把handle設(shè)置為null來(lái)關(guān)閉任何數(shù)據(jù)庫(kù)連接.

# close the connection

$DBH = null;

你可以從 PHP.net 獲取更多關(guān)于特點(diǎn)數(shù)據(jù)庫(kù)的選項(xiàng)和連接字串(connection strings)的信息


異常處理

PDO 可以使用異常(Exceptions)來(lái)處理錯(cuò)誤,這意味你需要把{處理PDO的}包括在一個(gè)try/catch代碼塊. 你也可以通過(guò)設(shè)置錯(cuò)誤模式(error mode attribute)強(qiáng)制PDO在您最近創(chuàng)建的數(shù)據(jù)庫(kù)連接上使用這三種錯(cuò)誤模式中的一種. 以下提供了語(yǔ)法:

$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );

$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

不過(guò)不管您設(shè)置什么錯(cuò)誤模式, 錯(cuò)誤的連接總會(huì)產(chǎn)生一個(gè)異常, 所以您應(yīng)該在創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)時(shí)包含一個(gè)try/catch代碼塊.

PDO::ERRMODE_SILENT

這是默認(rèn)的錯(cuò)誤模式. 如果您使用了這種錯(cuò)誤模式, 你將像您用mysql或mysqli擴(kuò)展的時(shí)候那樣自己檢查錯(cuò)誤. 這里還有兩種更理想的符合[[DRY programming]]思想的方法.

PDO::ERRMODE_WARNING

這種模式將會(huì)發(fā)出(issue)一個(gè)標(biāo)準(zhǔn)的PHP warning,然后繼續(xù)執(zhí)行程序. 這種方法在調(diào)試時(shí)會(huì)很有用.

PDO::ERRMODE_EXCEPTION

這也許是人們?cè)诖蠖鄶?shù)情況下希望使用的模式. 它拋出(fire)一個(gè)異常, 允許你優(yōu)雅的處理錯(cuò)誤并且隱藏那些可能會(huì)導(dǎo)致安全風(fēng)險(xiǎn)的數(shù)據(jù). 這里是一個(gè)處理異常的實(shí)例:

# connect to the database
try {
$DBH = new PDO(“mysql:host=$host;dbname=$dbname”, $user, $pass);
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
# UH-OH! Typed DELECT instead of SELECT!
$DBH->prepare(‘DELECT name FROM people’);
}
catch(PDOException $e) {
echo “I’m sorry, Dave. I’m afraid I can’t do that.”;
file_put_contents(‘PDOErrors.txt’, $e->getMessage(), FILE_APPEND);
}

上面是一個(gè)在select statement中的內(nèi)部錯(cuò)誤; 這將會(huì)引發(fā)一個(gè)異常. 這段異常處理代碼將會(huì)把錯(cuò)誤詳情發(fā)送到一個(gè)日志文件中, 然后顯示一個(gè)友好的(當(dāng)然,友不友好隨你便)消息給用戶.


插入、更新數(shù)據(jù)

插入新數(shù)據(jù)、或更新一個(gè)已經(jīng)存在的數(shù)據(jù),是最常見(jiàn)的數(shù)據(jù)庫(kù)操作之一. PDO提供了一種[[normally a two-step process]]. 本節(jié)中介紹的所有內(nèi)容同樣適用于 UPDATE 和 INSERT 操作.

下面是一個(gè)最基本的插入的例子:

# STH means “Statement Handle”

$STH = $DBH->prepare(“INSERT INTO folks ( first_name ) values ( ‘Cathy’ )”);

$STH->execute();

您也可以直接使用exec()方法完成相同的操作(PS:使用exec()方法可以減少一個(gè)調(diào)用). 在大多數(shù)情況下,您可能會(huì)多次調(diào)用這個(gè)方法, 所以呢, 您可以享受到prepared statements帶來(lái)的好處. 甚至如果您只想調(diào)用它一次, 使用prepared statements will 也會(huì)幫您擋住 SQL injection 攻擊.

Prepared Statements

使用 prepared statements 將幫助您防止 SQL injection 的危險(xiǎn).

Prepared statement的語(yǔ)句是只需要發(fā)送數(shù)據(jù)到服務(wù)器的預(yù)編譯 SQL 語(yǔ)句, 它具有自動(dòng)處理數(shù)據(jù)以免受 SQL injection 攻擊的優(yōu)點(diǎn)。

您可以通過(guò)在您的SQL語(yǔ)句中包含占位符來(lái)使用 prepared statement . 這里有三個(gè)例子: 一個(gè)沒(méi)有占位符的, 一個(gè)有未命名占位符(Unnamed Placeholders)的, 和一個(gè)有命名占位符(Named Placeholders)的.

# no placeholders – ripe for SQL Injection!
$STH = $DBH->(“INSERT INTO folks (name, addr, city) values ($name, $addr, $city)”);
# unnamed placeholders
$STH = $DBH->(“INSERT INTO folks (name, addr, city) values (?, ?, ?);
# named placeholders
$STH = $DBH->(“INSERT INTO folks (name, addr, city) value (:name, :addr, :city)”);

您可能想避免使用第一種方法; 下面為您提供了它們直接的比較. 選擇未命名占位符或命名占位符將會(huì)影響您如何為這些語(yǔ)句設(shè)置數(shù)據(jù).

未命名占位符(Unnamed Placeholders)

# assign variables to each place holder, indexed 1-3
$STH->bindParam(1, $name);
$STH->bindParam(2, $addr);
$STH->bindParam(3, $city);
# insert one row
$name = “Daniel”
$addr = “1 Wicked Way”;
$city = “Arlington Heights”;
$STH->execute();
# insert another row with different values
$name = “Steve”
$addr = “5 Circle Drive”;
$city = “Schaumburg”;
$STH->execute();

只需兩步!首先,我們?yōu)椴煌恼嘉环≒laceholder)綁定變量 (lines 2-4). 然后,我們?yōu)槟切┱嘉环≒laceholder)賦值然后執(zhí)行查詢. 要想發(fā)送另外的一組數(shù)據(jù),只需要改變那些變量的值,然后再執(zhí)行即可.

(譯注: 原文在第一步與第二布均使用了assign來(lái)描述過(guò)程)

這個(gè)使用很多參數(shù)的方法似乎有點(diǎn)麻煩?如果您的數(shù)據(jù)存儲(chǔ)在數(shù)組中,有一個(gè)簡(jiǎn)單的方法:

# the data we want to insert
$data = array(‘Cathy’, ’9 Dark and Twisty Road’, ‘Cardiff’);
$STH = $DBH->(“INSERT INTO folks (name, addr, city) values (?, ?, ?);
$STH->execute($data);

這很簡(jiǎn)單,不是嗎?

在數(shù)組中的數(shù)據(jù)等同于占位符。 $data[0]對(duì)應(yīng)第一個(gè)占位符,$data[1]第二個(gè),依此類推,但如果您的數(shù)組索引并未排序,這將無(wú)法正常工作,您將需要重新索引這個(gè)數(shù)組.

命名占位符(Named Placeholders)

您可能已經(jīng)猜到語(yǔ)法了,下面給出了一個(gè)例子:

# the first argument is the named placeholder name – notice named
# placeholders always start with a colon.
$STH->bindParam(‘:name’, $name);

您也可以在這里使用一個(gè)快捷方式,但它可以和關(guān)聯(lián)數(shù)組一起使用.

# the data we want to insert
$data = array( ‘name’ => ‘Cathy’, ‘addr’ => ’9 Dark and Twisty’, ‘city’ => ‘Cardiff’ );
# the shortcut!
$STH = $DBH->(“INSERT INTO folks (name, addr, city) value (:name, :addr, :city)”);
$STH->execute($data);

你的數(shù)組中的鍵不需要以一個(gè)冒號(hào)開(kāi)始,但是必須符合指定的占位符。如果你有一個(gè)二維數(shù)組(就是數(shù)組中的數(shù)組),您可以遍歷它們,只需調(diào)用執(zhí)行的每個(gè)數(shù)據(jù)的數(shù)組。

另一個(gè)命名占位符不錯(cuò)的特點(diǎn)是直接可以插入對(duì)象到您的數(shù)據(jù)庫(kù),如果命名的屬性匹配字段的話.下面是一個(gè)例子對(duì)象:

# a simple object
class person {
public $name;
public $addr;
public $city;
function __construct($n,$a,$c) {
$this->name = $n;
$this->addr = $a;
$this->city = $c;
}
# etc …
}
$cathy = new person(‘Cathy’,’9 Dark and Twisty’,'Cardiff’);
# here’s the fun part:
$STH = $DBH->(“INSERT INTO folks (name, addr, city) value (:name, :addr, :city)”);
$STH->execute((array)$cathy);

在執(zhí)行中,對(duì)象被轉(zhuǎn)換為一個(gè)數(shù)組.對(duì)象的屬性被視為數(shù)組中的一個(gè)鍵. By casting the object to an array in the execute, the properties are treated as array keys.


選擇數(shù)據(jù)

數(shù)據(jù)通過(guò)fetch()方法獲得, {一種應(yīng)用于陳述式句柄的方法}. 在使用fetch之間, 您最好告訴PDO您喜歡取得數(shù)據(jù)的樣子. 您有以下幾個(gè)選擇:

  • PDO::FETCH_ASSOC: 返回一個(gè)包含列名索引的數(shù)組
  • PDO::FETCH_BOTH (default): 返回一個(gè)由同時(shí)包含列名和數(shù)字索引的數(shù)組
  • PDO::FETCH_BOUND: 通過(guò) ->bindColumn() 方法將列的值賦到變量上。
  • PDO::FETCH_CLASS:列的值賦給指定對(duì)象的屬性里。如果指定的屬性不存在,會(huì)自動(dòng)創(chuàng)建。
  • PDO::FETCH_INTO: 更新一個(gè)已經(jīng)存在的命名對(duì)象的實(shí)例
  • PDO::FETCH_LAZY: 結(jié)合 了PDO::FETCH_BOTH,PDO::FETCH_OBJ,在它們被調(diào)用時(shí)創(chuàng)建對(duì)象變量
  • PDO::FETCH_NUM: 返回一個(gè)由同時(shí)包含列數(shù)字索引的數(shù)組
  • PDO::FETCH_OBJ: fanhuire返回一個(gè)有對(duì)應(yīng)的列名的屬性的匿名對(duì)象

在現(xiàn)實(shí)中,大多數(shù)情況下會(huì)使用以下三種: FETCH_ASSOC, FETCH_CLASS, FETCH_OBJ. 您需要使用以下語(yǔ)法設(shè)置獲取類型:

$STH->setFetchMode(PDO::FETCH_ASSOC);

您也可以直接在fetch()方法中設(shè)置獲取模式.

FETCH_ASSOC

這種模式創(chuàng)建一個(gè)按列名索引的關(guān)聯(lián)數(shù)組.這應(yīng)該會(huì)讓用過(guò)MySQL/MySQLi擴(kuò)展的人感到親切.這里有一個(gè)使用這種方法選擇數(shù)據(jù)的例子.

# using the shortcut ->query() method here since there are no variable
# values in the select statement.
$STH = $DBH->query(‘SELECT name, addr, city from folks’);
# setting the fetch mode
$STH->setFetchMode(PDO::FETCH_ASSOC);
while($row = $STH->fetch()) {
echo $row['name'] . “n”;
echo $row['addr'] . “n”;
echo $row['city'] . “n”;
}

這個(gè) while 循環(huán)將在獲取完所有數(shù)據(jù)后停止.{The while loop will continue to go through the result set one row at a time until complete.}

FETCH_OBJ

這種模式為每一行數(shù)據(jù)創(chuàng)建一個(gè)標(biāo)準(zhǔn)類,下面是一個(gè)例子:

# creating the statement
$STH = $DBH->query(‘SELECT name, addr, city from folks’);
# setting the fetch mode
$STH->setFetchMode(PDO::FETCH_OBJ);
# showing the results
while($row = $STH->fetch()) {
echo $row->name . “n”;
echo $row->addr . “n”;
echo $row->city . “n”;
}

FETCH_CLASS

您的對(duì)象的屬性應(yīng)該在constructor被調(diào)用前設(shè)置!這一點(diǎn)很重要!

這種模式允許你直接將獲取的數(shù)據(jù)發(fā)送到您選擇的類中.當(dāng)您使用FETCH_CLASS時(shí),您的對(duì)象的屬性應(yīng)該在constructor被調(diào)用前設(shè)置。讀一遍,它是重要的。如果屬性相匹配的列名不存在,這些屬性將被創(chuàng)建,(公共)為您。

這意味著如果你需要轉(zhuǎn)換后出來(lái)的數(shù)據(jù),它可以通過(guò)你的對(duì)象自動(dòng)為轉(zhuǎn)換.

舉個(gè)列子,假設(shè)的情況下該地址必須為特定格式,我們可以通過(guò)constructor上做到這一點(diǎn),下面是一個(gè)例子:

class secret_person {
public $name;
public $addr;
public $city;
public $other_data;
function __construct($other = ”) {
$this->address = preg_replace(‘/[a-z]/’, ‘x’, $this->address);
$this->other_data = $other;
}
}

OK,再讓我們看看效果如何?

$STH = $DBH->query(‘SELECT name, addr, city from folks’);
$STH->setFetchMode(PDO::FETCH_CLASS, ‘secret_person’);
while($obj = $STH->fetch()) {
echo $obj->addr;
}

如果地址是,‘5 Rosebud,’ 您將會(huì)在輸出中看到 ‘5 Rxxxxxx’. 當(dāng)然,可能有些情況下,您希望在constructor函數(shù)在數(shù)據(jù)被賦值之前調(diào)用.PDO也可以做到~

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, ‘secret_person’);

現(xiàn)在,當(dāng)你使用這個(gè)模式(PDO::FETCH_PROPS_LATE)的地址不會(huì)被遮,constructor會(huì)被首先調(diào)用然后再賦值.

最后,如果你真的需要,你可以在使用PDO獲取數(shù)據(jù)到對(duì)象時(shí),將參數(shù)傳遞給構(gòu)造函數(shù):

$STH->setFetchMode(PDO::FETCH_CLASS, ‘secret_person’, array(‘stuff’));

如果你需要傳遞不同的數(shù)據(jù)到每個(gè)對(duì)象的構(gòu)造函數(shù),你可以設(shè)置在fetch方法內(nèi)設(shè)置模式法模式:

$i = 0;
while($rowObj = $STH->fetch(PDO::FETCH_CLASS, ‘secret_person’, array($i))) {
// do stuff
$i++
}

其他有用的方法

雖然 PDO 并沒(méi)有面面俱到的(這擴(kuò)展可不小!), 這里仍還還有一些您想知道的方法.

$DBH->lastInsertId();

lastInsertId()方法始終調(diào)用數(shù)據(jù)庫(kù)句柄,而不是表達(dá)式的句柄,并且會(huì)返回該數(shù)據(jù)庫(kù)連接上一次插入語(yǔ)句的自增ID.

$DBH->exec(‘DELETE FROM folks WHERE 1′);

$DBH->exec(“SET time_zone = ‘-8:00′”);

exec()方法用于那些不能返回?cái)?shù)據(jù)或不影響行的操作. 上面是兩種調(diào)用exec()方法的例子.

$safe = $DBH->quote($unsafe);

quote() 方法將字符轉(zhuǎn)義為安全的字符以便在查詢中使用. 如果您不使用已經(jīng)準(zhǔn)備號(hào)的語(yǔ)句,您可以用此方法<<*>>。

$rows_affected = $STH->rowCount();

rowCount() 方法返回一個(gè)表明被一個(gè)操作影響的行數(shù)的整數(shù)(簡(jiǎn)直是廢話,難不成還是浮點(diǎn)數(shù)?). 更具這個(gè)錯(cuò)誤報(bào)告(http://bugs.php.net/40822) ,在最近的一個(gè)PDO版本上這個(gè)方法不能夠很好的與SELECT語(yǔ)句工作. 如果您遇到了這個(gè)問(wèn)題而不想升級(jí)PHP的話, 你可以用以下的方法來(lái)替代它:

$sql = “SELECT COUNT(*) FROM folks”;
if ($STH = $DBH->query($sql)) {
# check the row count
if ($STH->fetchColumn() > 0) {
# issue a real select here, because there’s data!
}
else {
echo “No rows matched the query.”;
}
}

結(jié)尾

我希望這篇文章能幫助您從mysql和mysqli擴(kuò)展遷移至PDO.您有啥想法?現(xiàn)在想遷移到PDO么?

英文原文:http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/

浮山狼的博客原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明來(lái)源并保留原文鏈接 
本文鏈接:http://www.fushanlang.com/blog/php-pdo-to-access-the-database-1032/
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
PHP的PDO類教程
預(yù)處理和事務(wù)處理
PDO 操作實(shí)例全解
PHP PDO 基礎(chǔ)
學(xué)PHP之PDO基礎(chǔ)操作
從PDO下的注入思路到獲得GIT 2000star項(xiàng)目0day(文末0day福利)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服