pdo

PDO一是PHP數(shù)據(jù)對(duì)象(PHP Data Object)的縮寫。二是丙二醇簡(jiǎn)稱PDO。三是阿曼石油開(kāi)發(fā)公司 (petroleum development of Oman.)的縮寫。四是過(guò)程數(shù)據(jù)對(duì)象(Process data object)的縮寫。五是太平洋十年濤動(dòng)。

至此我們已經(jīng)掌握了數(shù)據(jù)庫(kù)及 PHP 的背景知識(shí),現(xiàn)在正好可以提及 PDO 背后的一些設(shè)計(jì)目標(biāo):

為大多數(shù)數(shù)據(jù)庫(kù) API 中的常見(jiàn)特性提供一致的 API。

具有可擴(kuò)展性,以使數(shù)據(jù)庫(kù)供應(yīng)商 X 仍然可以暴露特性 Y 并保持 PDO 的兼容性。

提供大量基本的兼容性技巧,以便能夠更方便地創(chuàng)建跨數(shù)據(jù)庫(kù)兼容的應(yīng)用程序。

不為給定數(shù)據(jù)庫(kù) API 中本來(lái)沒(méi)有的特性(例如序列)提供完全抽象或仿真。PDO 類意圖為您提供對(duì)數(shù)據(jù)庫(kù)本地特性的一致性訪問(wèn),并減少干擾。

通過(guò)將與 PHP 內(nèi)部打交道的代碼(這是最難于編寫的部分)集中起來(lái),簡(jiǎn)化 PHP 數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序的創(chuàng)建。

最后一點(diǎn)非常重要。PDO 是模塊化結(jié)構(gòu),它被分成一個(gè)公共核心以及一個(gè)或多個(gè)驅(qū)動(dòng)程序擴(kuò)展,公共核心提供了在腳本(PDO 本身)中使用的 API,驅(qū)動(dòng)程序擴(kuò)展則為 PDO 和本地 RDBMS 客戶機(jī) API 庫(kù)架起一座橋梁。DB2 用戶將會(huì)希望使用 PDO_ODBC 驅(qū)動(dòng)程序,據(jù)稱它可以提供以下特性:

它經(jīng)過(guò)重新編寫,能支持遵從 ODBC V3 的驅(qū)動(dòng)程序和驅(qū)動(dòng)程序管理器。它還考慮了對(duì) DB2 特定特性和優(yōu)化的支持,這成為設(shè)計(jì)過(guò)程中的一部分 -- 不是后來(lái)補(bǔ)充的。

它支持經(jīng)過(guò)試驗(yàn)和測(cè)試的存儲(chǔ)過(guò)程和大型對(duì)象。它不僅能夠工作,而且非常好用。

對(duì)于取 10,000 行記錄這樣的 DB2 訪問(wèn)操作,使用 PDO_ODBC 驅(qū)動(dòng)程序時(shí)的性能比使用傳統(tǒng)的 PHP Unified ODBC 擴(kuò)展要快大約 10 倍。之所以有這么大的差異,是因?yàn)樵?PDO 中默認(rèn)的游標(biāo)是輕量級(jí)的只能向前移動(dòng)的游標(biāo)。

pdo造價(jià)信息

市場(chǎng)價(jià) 信息價(jià) 詢價(jià)
材料名稱 規(guī)格/型號(hào) 市場(chǎng)價(jià)
(除稅)
工程建議價(jià)
(除稅)
行情 品牌 單位 稅率 供應(yīng)商 報(bào)價(jià)日期
暫無(wú)數(shù)據(jù)
材料名稱 規(guī)格/型號(hào) 除稅
信息價(jià)
含稅
信息價(jià)
行情 品牌 單位 稅率 地區(qū)/時(shí)間
暫無(wú)數(shù)據(jù)
材料名稱 規(guī)格/需求量 報(bào)價(jià)數(shù) 最新報(bào)價(jià)
(元)
供應(yīng)商 報(bào)價(jià)地區(qū) 最新報(bào)價(jià)時(shí)間
暫無(wú)數(shù)據(jù)

并不能使用PDO擴(kuò)展本身執(zhí)行任何數(shù)據(jù)庫(kù)操作,必須使用一個(gè)database-specific PDO driver(針對(duì)特定數(shù)據(jù)庫(kù)的PDO驅(qū)動(dòng))訪問(wèn)數(shù)據(jù)庫(kù)服務(wù)器。

PDO并不提供數(shù)據(jù)庫(kù)抽象,它并不會(huì)重寫SQL或提供數(shù)據(jù)庫(kù)本身缺失的功能,如果你需要這種功能,你需要使用一個(gè)更加成熟的抽象層。

PDO需要PHP5核心OO特性的支持,所以它無(wú)法運(yùn)行于之前的PHP版本。

隨著擁有更成熟 OO 語(yǔ)法的 PHP 5 的發(fā)布,PHP 越來(lái)越多地受到越來(lái)越大的機(jī)構(gòu)的關(guān)注,對(duì)于 PHP 來(lái)說(shuō),提供更加一致的和可訪問(wèn)的數(shù)據(jù)訪問(wèn) API 變得越來(lái)越重要。

PHP 與流行的開(kāi)放源代碼關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)MySQL 之間總是很有默契。這對(duì)拍檔的成功很大程度上是由于它們免費(fèi)可用,而且進(jìn)入的門檻也比較低,這兩種產(chǎn)品的合作使它們各自都取得了廣受推崇的地位。

很多 PHP 應(yīng)用程序開(kāi)發(fā)人員都習(xí)慣于 PHP-MySQL 這對(duì)組合,以致 PHP 對(duì)其他數(shù)據(jù)庫(kù)的支持常常模仿 MySQL 客戶機(jī)庫(kù) API。然而,并不是所有的數(shù)據(jù)庫(kù)客戶機(jī) API 都是一樣的,也不是所有的數(shù)據(jù)庫(kù)都提供相同的特性。雖然存在模仿,但不同的 PHP 數(shù)據(jù)庫(kù)擴(kuò)展都有它們各自的怪僻和不同之處,所以從一種數(shù)據(jù)庫(kù)遷移到另一種數(shù)據(jù)庫(kù)時(shí)會(huì)有一些困難。雖然這不是創(chuàng)建 PDO 的直接原因,但是在設(shè)計(jì)過(guò)程中還是有一定影響的。

如果您是帶著想結(jié)合使用 PHP 和 DB2 的目的閱讀本文,那么您很可能屬于以下類型中的一種:

您從一家小公司開(kāi)始,在 MySQL(舉個(gè)例子)上運(yùn)行 PHP,由于業(yè)務(wù)增長(zhǎng),您需要 DB2 所提供的可伸縮性/可靠性/支持或其他特性。您希望移植代碼,以使用 DB2,但由于 API 的變化,您需要編寫或?qū)崿F(xiàn)一個(gè)抽象層,以便在 DB2 上測(cè)試應(yīng)用程序的同時(shí)可以繼續(xù)在舊的數(shù)據(jù)庫(kù)上運(yùn)行。不僅如此,您還希望能有自己的選擇,并保留支持其他 RDBMS 的可能性,因?yàn)槟宄行┛蛻魴C(jī)可能已經(jīng)和其他平臺(tái)栓在一起了。

您用 PHP 在 MySQL之上構(gòu)建了一個(gè)小型的部門應(yīng)用程序(同樣,這只是舉個(gè)例子,我并不是要跟 MySQL 過(guò)不去)。事實(shí)證明這個(gè)應(yīng)用程序本身很有用,現(xiàn)在已經(jīng)在這個(gè)部門之外使用,并且闖入了 CIO/CTO 的法眼 -- 現(xiàn)在需要遵從托管的標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)。(是的,這是第一點(diǎn)的一個(gè)變種。) 在其他某些復(fù)雜的企業(yè)級(jí)應(yīng)用程序的后臺(tái),您已經(jīng)有一個(gè) DB2 實(shí)例,您希望利用 PHP 的快速應(yīng)用程序開(kāi)發(fā)和原型設(shè)計(jì)來(lái)生成動(dòng)態(tài)報(bào)告。

pdo常見(jiàn)問(wèn)題

1,3-丙二醇簡(jiǎn)稱PDO

中文名稱: 1,3-丙二醇

英文名稱: 1,3-propanediol

英文名稱2: 1,3-dihydroxypropane

分子式: C3H8O2

結(jié)構(gòu): HOCH2CH2CH2OH

CAS No.: 504-63-2

分子量: 76.10

外觀與性狀: 無(wú)色、無(wú)臭,具咸味、吸濕性的粘稠液體。(純品)

熔點(diǎn)(℃): -27

沸點(diǎn)(℃): 210-211

相對(duì)密度(水=1): 1.05(25℃)

相對(duì)蒸氣密度(空氣=1): 2.6

飽和蒸氣壓(kPa): 0.13(60℃)

閃點(diǎn)(℃): 79

引燃溫度(℃): 400

爆炸上限%(V/V): 無(wú)資料

爆炸下限%(V/V): 無(wú)資料

溶解性: 與水混溶,可混溶于乙醇、乙醚。

主要用途: 用作溶劑, 用于有機(jī)合成。

連接管理

連接是通過(guò)創(chuàng)建 PDO 基類的實(shí)例而建立的。不管您想要使用哪種驅(qū)動(dòng)程序,您總是使用 PDO 類名。構(gòu)造函數(shù)接受用于指定數(shù)據(jù)源(即 DSN)的參數(shù),可能還包括用戶名和密碼參數(shù)(如果有的話)。最后一個(gè)參數(shù)用于傳遞附加的調(diào)優(yōu)參數(shù)到 PDO 或底層驅(qū)動(dòng)程序 -- 后面很快會(huì)有更詳細(xì)的論述。下面是一個(gè)簡(jiǎn)短的連接到 DB2 的示例腳本:

清單 2. 如何使用 PDO 連接到 DB2

try { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); echo "Connected\n";} catch (Exception $e) { echo "Failed: " . $e->getMessage();}

odbc:SAMPLE 告訴 PDO 它應(yīng)該使用 ODBC 驅(qū)動(dòng)程序,并且應(yīng)該使用 "SAMPLE" 數(shù)據(jù)庫(kù)。如果使用一個(gè)驅(qū)動(dòng)程序管理器,那么可以用一個(gè) ODBC 級(jí)數(shù)據(jù)源名稱替代 SAMPLE。實(shí)際上,在冒號(hào)字符之后可以指定任何有效的 ODBC 數(shù)據(jù)源連接字符串。

如果連接成功,您將看到消息 "Connected",否則,PDO 將拋出一個(gè) PDOException,解釋為什么連接失敗??赡艿脑虬o(wú)效的參數(shù),不正確的用戶/密碼,甚至是您忘了裝載驅(qū)動(dòng)程序。

值得注意的是,除非您捕捉從構(gòu)造函數(shù)拋出的異常,否則,如果 PHP 腳本未能連接到數(shù)據(jù)庫(kù),它將終止。這與傳統(tǒng)的 PHP 數(shù)據(jù)庫(kù)擴(kuò)展有很大的不同。對(duì)于不喜歡異常的人來(lái)說(shuō),只有兩個(gè)"硬故障(hard-failure)"點(diǎn)可能拋出異常,這是其中一個(gè)點(diǎn)(另一個(gè)地點(diǎn)是,當(dāng)您試圖使用事務(wù)時(shí)缺乏對(duì)事務(wù)的支持)。對(duì)于所有其他錯(cuò)誤,PDO 將使用您選擇的 錯(cuò)誤處理設(shè)置。

連接將保持開(kāi)放狀態(tài),直到所有對(duì)它的引用被釋放。如果在主腳本的頂端打開(kāi)連接,并將其句柄存儲(chǔ)在一個(gè)全局變量中,那么該連接將一直處于開(kāi)放狀態(tài),直到腳本結(jié)束,或者直到 $dbh 變量被設(shè)為 null。如果在一個(gè)函數(shù)中打開(kāi)連接,并且只將句柄存儲(chǔ)在一個(gè)本地變量中,那么當(dāng)函數(shù)返回時(shí),連接將被關(guān)閉。這些語(yǔ)義對(duì)于 PHP 中的任何對(duì)象都是一樣的,沒(méi)有什么特別的地方。

ODBC 連接池如果您使用的是 Windows,或者如果您選擇在 UNIX 型平臺(tái)上使用一個(gè) ODBC 驅(qū)動(dòng)程序管理器,那么值得注意的是,PDO_ODBC 將自動(dòng)嘗試使用該驅(qū)動(dòng)程序管理器的 ODBC 連接池特性。這個(gè)特性類似于 PHP 級(jí)連接緩存,不要求專門請(qǐng)求一個(gè)持久的連接。此外,緩存是在 ODBC 級(jí)進(jìn)行的,這意味著在同一個(gè)進(jìn)程中運(yùn)行的其他組件(例如在 IIS 下運(yùn)行的 ASP/.Net 腳本)也能利用相同的連接池。

對(duì)于流量較大的站點(diǎn),讓 PHP 在不同請(qǐng)求的間隙中緩存打開(kāi)的連接,使得每個(gè)進(jìn)程(每個(gè)惟一的連接參數(shù)集)只需花費(fèi)一次建立連接的成本,這樣做常常很有益處。雖然這聽(tīng)起來(lái)像是一個(gè)不錯(cuò)的想法,但您應(yīng)該仔細(xì)評(píng)估這樣做對(duì)系統(tǒng)的影響,因?yàn)楫?dāng)大量緩存的連接空閑在那里的時(shí)候,就會(huì)適得其反。

要建立一個(gè)緩存的連接(如果您更熟悉傳統(tǒng)的數(shù)據(jù)庫(kù)擴(kuò)展的話,也可以說(shuō)是 *pconnect()),需要在實(shí)例化數(shù)據(jù)庫(kù)連接時(shí)傳遞一個(gè)屬性:

清單 3. 如何用 PDO 連接到 DB2,使用持久(緩存)連接

try { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO_ATTR_PERSISTENT => true)); echo "Connected\n"; } catch (Exception $e) { echo "Failed: " . $e->getMessage(); }

事務(wù)提交

至此,您已經(jīng)通過(guò) PDO 連接到了 DB2,在發(fā)出查詢之前,您應(yīng)該理解 PDO 是如何管理事務(wù)的。如果之前沒(méi)有接觸過(guò)事務(wù),那么首先要知道事務(wù)的 4 個(gè)特征:原子性(Atomicity)、一致性(Consistency)、獨(dú)立性(Isolation)和持久性(Durability),即 ACID。用外行人的話說(shuō),對(duì)于在一個(gè)事務(wù)中執(zhí)行的任何工作,即使它是分階段執(zhí)行的,也一定可以保證該工作會(huì)安全地應(yīng)用于數(shù)據(jù)庫(kù),并且在工作被提交時(shí),不會(huì)受到來(lái)自其他連接的影響。事務(wù)性工作可以根據(jù)請(qǐng)求自動(dòng)撤銷(假設(shè)您還沒(méi)有提交它),這使得腳本中的錯(cuò)誤處理變得更加容易。

事務(wù)通常是通過(guò)把一批更改積蓄起來(lái)、使之同時(shí)生效而實(shí)現(xiàn)的。這樣做的好處是可以大大提高這些更新的效率。換句話說(shuō),事務(wù)可以使腳本更快,而且可能更健壯(不過(guò)需要正確地使用事務(wù)才能獲得這樣的好處)。

警告只有在通過(guò) PDO::beginTransaction() 啟動(dòng)事務(wù)的情況下,才會(huì)發(fā)生自動(dòng)回滾。如果手動(dòng)地發(fā)出開(kāi)始一個(gè)事務(wù)的查詢,那么 PDO 就無(wú)法知道該事務(wù),從而不能在必要時(shí)進(jìn)行回滾。

不幸的是,并不是每種數(shù)據(jù)庫(kù)都支持事務(wù),所以當(dāng)?shù)谝淮未蜷_(kāi)連接時(shí),PDO 需要在所謂的"自動(dòng)提交(auto-commit)"模式下運(yùn)行。自動(dòng)提交模式意味著,如果數(shù)據(jù)庫(kù)支持事務(wù),那么您所運(yùn)行的每一個(gè)查詢都有它自己的隱式事務(wù),如果數(shù)據(jù)庫(kù)不支持事務(wù),每個(gè)查詢就沒(méi)有這樣的事務(wù)。如果您需要一個(gè)事務(wù),那么必須使用 PDO::beginTransaction() 方法來(lái)啟動(dòng)一個(gè)事務(wù)。如果底層驅(qū)動(dòng)程序不支持事務(wù),那么將會(huì)拋出一個(gè) PDOException(無(wú)論錯(cuò)誤處理設(shè)置是怎樣的:這總是一個(gè)嚴(yán)重錯(cuò)誤狀態(tài))。在一個(gè)事務(wù)中,可以使用 PDO::commit() 或 PDO::rollBack() 來(lái)結(jié)束該事務(wù),這取決于事務(wù)中運(yùn)行的代碼是否成功。

DB2 特性雖然我認(rèn)為事務(wù)通常要更快一些,但您還是應(yīng)該自己評(píng)估事務(wù)是否真的可以加快代碼。例如,在高并發(fā)環(huán)境中您可能會(huì)發(fā)現(xiàn),過(guò)度使用事務(wù)會(huì)增加鎖開(kāi)銷。如果在應(yīng)用程序中出現(xiàn)這種情況,那么建議的補(bǔ)救辦法是在一般情況下使用自動(dòng)提交,而對(duì)于真正需要全部 ACID 特征的代碼部分則仍然使用事務(wù)。

當(dāng)腳本結(jié)束時(shí),或者當(dāng)一個(gè)連接即將被關(guān)閉時(shí),如果有一個(gè)未完成的事務(wù),那么 PDO 將自動(dòng)回滾該事務(wù)。這是一種安全措施,有助于避免在腳本非正常結(jié)束時(shí)出現(xiàn)不一致的情況 -- 如果沒(méi)有顯式地提交事務(wù),那么假設(shè)有某個(gè)地方會(huì)出現(xiàn)不一致,所以要執(zhí)行回滾,以保證數(shù)據(jù)的安全性。

清單 4. 在事務(wù)中執(zhí)行批處理

try { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO_ATTR_PERSISTENT => true)); echo "Connected\n"; $dbh->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION); $dbh->beginTransaction(); $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')"); $dbh->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())"); $dbh->commit(); } catch (Exception $e) { $dbh->rollBack(); echo "Failed: " . $e->getMessage(); }

在上面的示例中,假設(shè)我們?yōu)橐粋€(gè)新雇員創(chuàng)建一組條目,這個(gè)雇員有一個(gè) ID 號(hào),即 23。除了輸入這個(gè)人的基本數(shù)據(jù)外,我們還需要記錄雇員的薪水。兩個(gè)更新分別完成起來(lái)很簡(jiǎn)單,但通過(guò)將這兩個(gè)更新包括在 beginTransaction() 和 commit() 調(diào)用中,就可以保證在更改完成之前,其他人無(wú)法看到更改。如果發(fā)生了錯(cuò)誤,catch 塊可以回滾事務(wù)開(kāi)始以來(lái)發(fā)生的所有更改,并打印出一條錯(cuò)誤消息。

并不是一定要在事務(wù)中作出更新。您也可以發(fā)出復(fù)雜的查詢來(lái)提取數(shù)據(jù),還可以使用那種信息構(gòu)建更多的更新和查詢。當(dāng)事務(wù)在活動(dòng)時(shí),可以保證其他人在工作進(jìn)行當(dāng)中無(wú)法作出更改。事實(shí)上,這不是 100% 的正確,但如果您之前沒(méi)有聽(tīng)說(shuō)過(guò)事務(wù)的話,這樣介紹也未嘗不可。

關(guān)于 PHP 應(yīng)用程序中安全性的說(shuō)明

PHP Security Consortium 雖然本文表明在使用 PDO 時(shí)不再需要引用輸入,但這不是說(shuō)您應(yīng)該盲目地使數(shù)據(jù)通過(guò)數(shù)據(jù)庫(kù)。XSS 攻擊是很實(shí)際的危險(xiǎn)。您應(yīng)該總是確保對(duì)傳入應(yīng)用程序的不受信任的數(shù)據(jù)應(yīng)用適當(dāng)?shù)倪^(guò)濾器,并采取措施避免讓不受信任的數(shù)據(jù)在站點(diǎn)上發(fā)出 HTML 或 javascript。 請(qǐng)?jiān)L問(wèn) The PHP Security Consortium 以了解關(guān)于這些危險(xiǎn)的更多知識(shí),以及應(yīng)該如何避免這些危險(xiǎn)。

很多 PHP 腳本中一個(gè)常見(jiàn)的缺陷是缺乏輸入檢驗(yàn)。這種缺陷可以被利用,從而招致 XSS(Cross Site Scripting)以及 SQL 入侵攻擊。在 SQL 入侵中,不受信任的數(shù)據(jù)(例如發(fā)給 Web 網(wǎng)頁(yè)的反饋)和其他文本被銜接在一起,構(gòu)成一個(gè)查詢。攻擊者可以蓄意地安排他們的輸入,使之溢出引號(hào)之外,并在您想運(yùn)行的真正查詢后面鏈接上任意一個(gè)查詢。這種攻擊使攻擊者可以更新、插入或刪除數(shù)據(jù),甚至可能可以看到數(shù)據(jù)庫(kù)中的任意信息。

XSS 也是一個(gè)類似的問(wèn)題。不過(guò)這一次不受信任的數(shù)據(jù)瞄準(zhǔn)的是瀏覽站點(diǎn)的人們,而不是應(yīng)用程序本身。通過(guò)提交包含 HTML 或 javascript 組合的文本,攻擊者期望您之后會(huì)將那種數(shù)據(jù)直接輸出到其他訪問(wèn)站點(diǎn)的人那里,從而使惡意代碼可以在站點(diǎn)訪問(wèn)者的瀏覽器上運(yùn)行。

在編寫應(yīng)用程序時(shí),需要同時(shí)考慮這兩種攻擊。如果小心地檢驗(yàn)和過(guò)濾輸入,這兩種攻擊都是可以防止的。對(duì) XSS 的處理很有技巧性,所以在這里我不便多講(不過(guò)可以從側(cè)欄找到有用的參考資料)。相比之下,SQL 入侵更容易對(duì)付。您只需在構(gòu)造查詢之前,適當(dāng)?shù)嘏懦繅K不受信任的數(shù)據(jù)。這種事情有點(diǎn)煩雜,特別是當(dāng)您有大量的字段要處理時(shí),很容易忘記做這件事。

雖然這是有用的(并且也是重要的)信息,但是您可能想知道,為什么我要花時(shí)間提到這一點(diǎn),本文的重點(diǎn)不是結(jié)合使用 PDO 和 DB2 嗎?原因是這樣的:PHP 現(xiàn)在得到很廣泛的部署,自然地,大量流行的基于 PHP 的應(yīng)用程序也得到了廣泛的部署。每當(dāng)某一種這樣的應(yīng)用程序(和 PHP 本身沒(méi)有聯(lián)系)被發(fā)現(xiàn)存在漏洞時(shí),PHP 常常被誤認(rèn)為是不安全的,可被利用的或者有缺陷的。為了避免將來(lái)出現(xiàn)這樣的情況,我們可以采取的一個(gè)措施是鼓勵(lì)應(yīng)用程序開(kāi)發(fā)人員多考慮安全問(wèn)題,從而減少由誠(chéng)實(shí)的錯(cuò)誤導(dǎo)致的損害。扯遠(yuǎn)了,下面繼續(xù)介紹其他關(guān)鍵概念。

預(yù)處過(guò)程

很多更成熟的數(shù)據(jù)庫(kù)都支持預(yù)處理語(yǔ)句的概念。什么是預(yù)處理語(yǔ)句?您可以把預(yù)處理語(yǔ)句看作您想要運(yùn)行的 SQL 的一種編譯過(guò)的模板,它可以使用變量參數(shù)進(jìn)行定制。預(yù)處理語(yǔ)句可以帶來(lái)兩大好處:

查詢只需解析(或準(zhǔn)備)一次,但是可以用相同或不同的參數(shù)執(zhí)行多次。當(dāng)查詢準(zhǔn)備好后,數(shù)據(jù)庫(kù)將分析、編譯和優(yōu)化執(zhí)行該查詢的計(jì)劃。對(duì)于復(fù)雜的查詢,這個(gè)過(guò)程要花比較長(zhǎng)的時(shí)間,如果您需要以不同參數(shù)多次重復(fù)相同的查詢,那么該過(guò)程將大大降低應(yīng)用程序的速度。通過(guò)使用預(yù)處理語(yǔ)句,可以避免重復(fù)分析/編譯/優(yōu)化周期。簡(jiǎn)言之,預(yù)處理語(yǔ)句使用更少的資源,因而運(yùn)行得更快。 提供給預(yù)處理語(yǔ)句的參數(shù)不需要用引號(hào)括起來(lái),驅(qū)動(dòng)程序會(huì)處理這些。如果應(yīng)用程序獨(dú)占地使用預(yù)處理語(yǔ)句,那么可以確保沒(méi)有 SQL 入侵發(fā)生。(然而,如果您仍然將查詢的其他部分建立在不受信任的輸入之上,那么就仍然存在風(fēng)險(xiǎn))。 預(yù)處理語(yǔ)句是如此有用,以致 PDO 實(shí)際上打破了在目標(biāo) 4 中設(shè)下的規(guī)則:如果驅(qū)動(dòng)程序不支持預(yù)處理語(yǔ)句,那么 PDO 將仿真預(yù)處理語(yǔ)句。

下面是使用預(yù)處理語(yǔ)句的兩個(gè)例子。第一個(gè)例子 通過(guò)替換指定占位符的 name 和 value,執(zhí)行一次插入。而 第二個(gè)例子 使用問(wèn)號(hào)占位符執(zhí)行一條 select 語(yǔ)句。

清單 4. 使用預(yù)處理語(yǔ)句的重復(fù)插入

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(':name', $name);$stmt->bindParam(':value', $value); // insert one row$name = 'one';$value = 1;$stmt->execute(); // insert another row with different values$name = 'two';$value = 2; $stmt->execute();

清單 5. 使用預(yù)處理語(yǔ)句取數(shù)據(jù)

$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?"); if ($stmt->execute(array('one'))) { while ($row = $stmt->fetch()) { print_r($row); }}

如果數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序支持,您還可以綁定輸出和輸入?yún)?shù)。輸出參數(shù)通常用于從存儲(chǔ)過(guò)程獲取值。輸出參數(shù)使用起來(lái)比輸入?yún)?shù)要復(fù)雜一些,當(dāng)綁定一個(gè)給定的輸出參數(shù)時(shí),必須知道該參數(shù)的長(zhǎng)度。如果為參數(shù)綁定的值大于您建議的長(zhǎng)度,那么就會(huì)產(chǎn)生錯(cuò)誤。

清單 6. 帶輸出參數(shù)調(diào)用存儲(chǔ)過(guò)程

$stmt = $dbh->prepare("CALL sp_returns_string(?)"); $stmt->bindParam(1, $return_value, PDO_PARAM_STR, 4000); // call the stored procedure$stmt->execute(); print "procedure returned $return_value\n";

您還可以指定同時(shí)具有輸入和輸出值的參數(shù),其語(yǔ)法類似于輸出參數(shù)。在接下來(lái)的例子中,字符串 'hello' 被傳遞給存儲(chǔ)過(guò)程,當(dāng)存儲(chǔ)過(guò)程返回時(shí),hello 被替換為該存儲(chǔ)過(guò)程返回的值。

清單 7. 帶輸入/輸出參數(shù)調(diào)用存儲(chǔ)過(guò)程

$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)"); $value = 'hello'; $stmt->bindParam(1, $value, PDO_PARAM_STR|PDO_PARAM_INPUT_OUTPUT, 4000); // call the stored procedure$stmt->execute(); print "procedure returned $value\n";

錯(cuò)誤處理

PDO 提供了 3 種不同的錯(cuò)誤處理模式,以滿足不同風(fēng)格的編程:

PDO_ERRMODE_SILENT 這是默認(rèn)模式。PDO 將只設(shè)置錯(cuò)誤代碼,以通過(guò) errorCode() 和 errorInfo() 方法對(duì)語(yǔ)句和數(shù)據(jù)庫(kù)對(duì)象進(jìn)行檢查。如果錯(cuò)誤是由于對(duì)語(yǔ)句對(duì)象的調(diào)用而產(chǎn)生的,那么可以在那個(gè)對(duì)象上調(diào)用 errorCode() 或 errorInfo() 方法。如果錯(cuò)誤是由于調(diào)用數(shù)據(jù)庫(kù)對(duì)象而產(chǎn)生的,那么可以在那個(gè)數(shù)據(jù)庫(kù)對(duì)象上調(diào)用上述兩個(gè)方法。 PDO_ERRMODE_WARNING 除了設(shè)置錯(cuò)誤代碼以外,PDO 還將發(fā)出一條傳統(tǒng)的 E_WARNING 消息。如果您只是想看看發(fā)生了什么問(wèn)題,而無(wú)意中斷應(yīng)用程序的流程,那么在調(diào)試/測(cè)試當(dāng)中這種設(shè)置很有用。 PDO_ERRMODE_EXCEPTION 除了設(shè)置錯(cuò)誤代碼以外,PDO 還將拋出一個(gè) PDOException,并設(shè)置其屬性,以反映錯(cuò)誤代碼和錯(cuò)誤信息。這種設(shè)置在調(diào)試當(dāng)中也很有用,因?yàn)樗鼤?huì)放大腳本中產(chǎn)生錯(cuò)誤的地方,從而可以非??焖俚刂赋龃a中有問(wèn)題的潛在區(qū)域(記住,如果異常導(dǎo)致腳本終止,則事務(wù)將自動(dòng)回滾)。 異常模式另一個(gè)有用的地方是,與傳統(tǒng)的 PHP 風(fēng)格的警告相比,您可以更清晰地構(gòu)造自己的錯(cuò)誤處理,而且,比起以靜寂方式以及顯式地檢查每個(gè)數(shù)據(jù)庫(kù)調(diào)用的返回值,異常模式需要的代碼/嵌套也更少。 PDO 定制了使用 SQL-92 SQLSTATE 錯(cuò)誤代碼字符串的標(biāo)準(zhǔn);不同 PDO 驅(qū)動(dòng)程序負(fù)責(zé)將它們本地代碼映射為適當(dāng)?shù)?SQLSTATE 代碼。例如,SQLSTATE 是用于 DB2(以及通常的 ODBC)的本地錯(cuò)誤代碼格式,這是多么方便啊!errorCode() 方法返回一個(gè) SQLSTATE 代碼。如果您需要關(guān)于一個(gè)錯(cuò)誤的更多特定的信息,PDO 還提供了一個(gè) errorInfo() 方法,該方法將返回一個(gè)數(shù)組,其中包含 SQLSTATE 代碼、特定于驅(qū)動(dòng)程序的錯(cuò)誤代碼以及特定于驅(qū)動(dòng)程序的錯(cuò)誤字符串。

分頁(yè)數(shù)據(jù)、滾動(dòng)游標(biāo)和定位更新

在 Web 應(yīng)用程序中,一種常見(jiàn)的范例是對(duì)查詢結(jié)果進(jìn)行分頁(yè)。如果您使用一個(gè) Internet 搜索引擎,那么很可能每天都會(huì)做這樣的事。您輸入搜索詞,然后得到前 10-20 個(gè)匹配項(xiàng)。如果您想看到更多搜索結(jié)果,可以單擊 "next page" 鏈接。如果想回頭看前面看過(guò)的結(jié)果,可以單擊 "previous page" 鏈接。記得在幾年前,當(dāng)我第一次在 Web 上使用這樣的東西時(shí),我對(duì)自己說(shuō):"為什么我不能通過(guò)滾動(dòng)查看所有數(shù)據(jù)呢?" 問(wèn)題的答案說(shuō)簡(jiǎn)單也簡(jiǎn)單,說(shuō)復(fù)雜也復(fù)雜 -- 我只想說(shuō),HTTP 不會(huì)智能地使數(shù)據(jù)庫(kù)上的可滾動(dòng)游標(biāo)一直處于開(kāi)放狀態(tài),即便如此,需要大量傳輸?shù)?Web 應(yīng)用程序也會(huì)很快地消耗掉大量開(kāi)放的可滾動(dòng)游標(biāo)。因此,最簡(jiǎn)單的解決方案是為用戶顯示所有的匹配項(xiàng) -- 但是用戶很容易迷失在大量的結(jié)果當(dāng)中。比較符合邏輯的措施是人工地將數(shù)據(jù)格式化到多個(gè)頁(yè)面上,使用戶可以每次查看一部分可以管理的數(shù)據(jù)。

所以人們編寫可以取所有數(shù)據(jù)的 PHP 應(yīng)用程序,然后只顯示前 10 行。根據(jù)下一次請(qǐng)求,應(yīng)用程序又顯示 11-20 行,依此類推。這對(duì)于只返回少量數(shù)據(jù)的查詢來(lái)說(shuō)很不錯(cuò),但是,如果有很多匹配項(xiàng)(比如多于 100),那么先取全部數(shù)據(jù)然后丟棄其中的 90%,這種做法很浪費(fèi)。PHP 的創(chuàng)始人 Rasmus Lerdorf 就這種情形特地為 MySQL 發(fā)明了一個(gè)特殊的 "LIMIT, OFFSET" 子句。它允許您通知數(shù)據(jù)庫(kù),您只對(duì)一小部分行感興趣,這樣它就不會(huì)取其他不需要的行了。其語(yǔ)法(或非常類似的東西)已經(jīng)被其他流行的開(kāi)放源代碼數(shù)據(jù)庫(kù)采納,但并不是所有數(shù)據(jù)庫(kù)都提供了相同的語(yǔ)法。 Troels Arvin 收集了一些非常有用的信息,對(duì)不同 RDBMS 所支持的語(yǔ)法進(jìn)行了比較。

如果您想在以 DB2 為后臺(tái)數(shù)據(jù)庫(kù)的 PHP 應(yīng)用程序中實(shí)現(xiàn)分頁(yè)結(jié)果,那么可以(也應(yīng)該)使用下面示例中的語(yǔ)法。這里我們假設(shè)有一個(gè) books 表,表中包含書名和作者,我們現(xiàn)在想要每次在一頁(yè)中顯示 10 個(gè)以上結(jié)果:

清單 8. 使用 SQL Standard "Window Functions" 實(shí)現(xiàn)數(shù)據(jù)分頁(yè)

$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); // the offset is passed in from the user when they click on a link // this cast to integer ensures that no SQL injection can occur $offset = (int)$_GET['offset'];$stmt = $db->prepare("select * from ( select ROW_NUMBER() OVER (ORDER BY author) as rownum, * from books ) as books_windowWHERE rownum > $offset AND rownum <= (10 + $offset)"); if ($stmt->execute()) { while (($row = $stmt->fetch()) !== false) { print_r($row); }}

Cloudscape 說(shuō)明在撰寫本文之際,Cloudscape 在其 SQL 實(shí)現(xiàn)中還不支持 ROW_NUMBER(),所以需要使用可滾動(dòng)游標(biāo)。

現(xiàn)在,如果您要編寫一個(gè)更通用的應(yīng)用程序,并希望實(shí)現(xiàn)分頁(yè)的結(jié)果集,但是不想專門編寫很多的代碼,并且也不想使用更重量級(jí)的抽象層,Troels Arvin 的非常有幫助的 RDBMS 信息建議,您可以使用游標(biāo)作為更輕便(稍微慢一點(diǎn))的方案。碰巧的是,PDO 具有這方面的 API 級(jí)的支持。下面將談到如何使用這種支持來(lái)達(dá)到與上面示例相同的效果:

清單 9. 使用滾動(dòng)游標(biāo)實(shí)現(xiàn)數(shù)據(jù)分頁(yè)

$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); $stmt = $db->prepare("select * from books order by author", array( PDO_ATTR_CURSOR => PDO_CURSOR_SCROLL)); // the offset is passed in from the user when they click on a link // this cast to integer ensures that no SQL injection can occur $offset = (int)$_GET['offset'];if ($stmt->execute()) { // moves the cursor to the requested offset and fetches the first for ($tofetch = 10, $row = $stmt->fetch(PDO_FETCH_ASSOC, PDO_FETCH_ORI_REL, $offset); $row !== false && $tofetch-- > 0; $row = $stmt->fetch(PDO_FETCH_ASSOC)) { print_r($row); } }

需要強(qiáng)調(diào)的是,雖然滾動(dòng)游標(biāo)對(duì)于更冗長(zhǎng)的 window 函數(shù)方案來(lái)說(shuō)是一個(gè)很方便的替代方案,但這種方案要慢很多。如果在一個(gè)傳輸量比較少的環(huán)境中進(jìn)行測(cè)試,您可能發(fā)現(xiàn)不了速度上的差異,但當(dāng)規(guī)模擴(kuò)大時(shí),您就會(huì)開(kāi)始發(fā)現(xiàn)速度降慢帶來(lái)的痛苦。

定位更新

可滾動(dòng)游標(biāo)的另一個(gè)用途是,基于 SQL 中無(wú)法表達(dá)的重大標(biāo)準(zhǔn)驅(qū)動(dòng)更新。如果您有一個(gè) Web 頁(yè)面鏈接的表,并且需要在每晚的批處理過(guò)程中更新那個(gè)表,以反映 Web 頁(yè)面當(dāng)前大小,那么可以編寫如下代碼:

清單 10. 使用滾動(dòng)游標(biāo)作出定位更新

$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); // create a named, scrolling, updateable cursor $stmt = $db->prepare("select url, size from links FOR UPDATE OF size", array( PDO_ATTR_CURSOR => PDO_CURSOR_SCROLL, PDO_ATTR_CURSOR_NAME => 'link_pos'));if ($stmt->execute()) { // a statement for applying our updates. // Notice the WHERE CURRENT OF clause mentions "link_pos", // which is the name of the cursor we're using to select the data $upd = $db->prepare("UPDATE links set size = ? WHERE CURRENT OF link_pos"); // grab each row while (($row = $stmt->fetch()) !== false) { // There are much more efficient ways to do this; // this is a brief example only: grab all the content // from the URL $content = file_get_conents($row['url']); // and measure its length $size = strlen($content) // and pass that as a parameter to our update statement $upd->execute(array($size)); }}

大型對(duì)象

在應(yīng)用程序中的某個(gè)地方,您可能發(fā)現(xiàn)需要在數(shù)據(jù)庫(kù)中存儲(chǔ)"大型(large)"數(shù)據(jù)。大型通常意味著"大約 4kb 或 4kb 以上",盡管在沒(méi)有"大型"數(shù)據(jù)之前 DB2 最大可以處理 32kb 的數(shù)據(jù)。 大型對(duì)象可以是文本的,也可以是二進(jìn)制的。PDO 允許在 bindParam() 或 bindColumn() 調(diào)用中通過(guò)使用 PDO_PARAM_LOB 類型代碼來(lái)使用大型數(shù)據(jù)類型。PDO_PARAM_LOB 告訴 PDO 將數(shù)據(jù)映射為流,所以可以使用 PHP Streams API 來(lái)操縱這樣的數(shù)據(jù)。下面是一個(gè)示例:

程序功能

清單 11. 從數(shù)據(jù)庫(kù)取一副圖像

$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); $stmt = $db->prepare("select contenttype, imagedata from images where id=?"); $stmt->execute(array($_GET['id']));list($type, $lob) = $stmt->fetch(); header("Content-Type: $type");fpassthru($lob);

上面的介紹很簡(jiǎn)明扼要。現(xiàn)在讓我們?cè)囋嚵硪幻?,將上傳的圖像插入到一個(gè)數(shù)據(jù)庫(kù)中:

清單 12. 將圖像插入數(shù)據(jù)庫(kù)中

$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); $stmt = $db->prepare("insert into images (id, contenttype, imagedata) values (?, ?, ?)"); $id = get_new_id(); // some function to allocate a new ID // assume that we are running as part of a file upload form // You can find more information in the PHP documentation $fp = fopen($_FILES['file']['tmp_name'], 'rb');$stmt->bindParam(1, $id); $stmt->bindParam(2, $_FILES['file']['type']); $stmt->bindParam(3, $fp, PDO_PARAM_LOB); $stmt->execute();

這兩個(gè)例子都是宏觀層次的。請(qǐng)記住,被取的大型對(duì)象是一個(gè)流,可以通過(guò)所有常規(guī)的流函數(shù)來(lái)使用它,例如 fgets()、fread()、fgetcsv() 和 stream_get_contents()。

關(guān)于全球化、NLS 和字符集的簡(jiǎn)要說(shuō)明

在越來(lái)越多的 PHP 應(yīng)用程序中,越來(lái)越重要的一點(diǎn)是讓應(yīng)用程序能夠在全球范圍內(nèi)使用。從實(shí)踐角度來(lái)講,這意味著應(yīng)用程序需要能夠正確地處理多種語(yǔ)言(例如英語(yǔ)和日語(yǔ))中的數(shù)據(jù),并且其功能性不變。這是一個(gè)很大的專題,做起來(lái)很有技巧性。實(shí)現(xiàn)全球化要走的第一步是采用一種適合所有數(shù)據(jù)的全球編碼,例如 UTF-8。這是一種 ASCII 兼容的編碼,它可以使用特殊字符序列為整個(gè) unicode 字符集編碼。UTF-8 也是一種多字節(jié)編碼。

與常規(guī) ASCII 字符串相比,多字節(jié)編碼的字符串處理起來(lái)要棘手一點(diǎn),因?yàn)橐粋€(gè)或多個(gè)字符對(duì)應(yīng)于一個(gè)給定的字母 -- 例如,UTF-8 允許最多 6 個(gè)字符的序列映射到字符串中的一個(gè)字母。ASCII 字符在 UTF-8 中仍具有相同的表示,因此,如果只是處理不帶任何特殊音調(diào)的純英文文本,則 UTF-8 看上去就像是 ASCII。這意味著類似的字符串函數(shù)(作用于字節(jié)而不是字符位置),例如 strlen() 和 substr(),可能得不到預(yù)期的效果,這取決于 UTF-8 字符串中的內(nèi)容。幸運(yùn)的是,PHP iconv 擴(kuò)展為這些函數(shù)提供了一些編碼感知的替代函數(shù)。例如,您可以使用 iconv_strlen() 來(lái)得出字符串中的字符數(shù),而不是使用 strlen()。類似地,您可以不用 strpos() 或 substr(),而使用 iconv_strpos() 和 iconv_substr()。

iconv 擴(kuò)展為您提供了在處理多種編碼下的數(shù)據(jù)時(shí)所需的基本工具。應(yīng)用程序應(yīng)該盡量確保所有數(shù)據(jù)都是 UTF-8 編碼的。如果用適當(dāng)?shù)?Content-Type 標(biāo)記 Web 頁(yè)面,那么大多數(shù)瀏覽器將發(fā)送 UTF-8 編碼的數(shù)據(jù),可以確信,一定有一個(gè)編碼類型屬性可應(yīng)用于 HTML FORM 標(biāo)簽。

接下來(lái)的一步是設(shè)置 DB2 實(shí)例,使它在您與之交互時(shí)使用 UTF-8。這很容易辦到,只需在 DB2 的命令行提示符中運(yùn)行以下命令:

清單 14. 設(shè)置 DB2 實(shí)例,使之使用 UTF-8

$ db2set DB2CODEPAGE=1208

完成這樣的更改后,從 DB2 實(shí)例取到的所有文本數(shù)據(jù)都是 UTF-8 編碼的。同樣,DB2 期望您輸入的所有文本也是 UTF-8 編碼的。當(dāng)應(yīng)用程序的每個(gè)部分都使用 UTF-8 時(shí),應(yīng)用程序就可以全球使用了,并且能夠顯示任何語(yǔ)言的文本,只要這種語(yǔ)言的文本可以用 UTF-8 編碼。前面我已經(jīng)暗示過(guò),這只是通往國(guó)際化大道的第一步。還有很多其他的事情需要考慮,例如本地化(采用給定用戶的地區(qū)設(shè)置來(lái)顯示日期、時(shí)間、重量和度量,將通用文本翻譯成用戶本地的語(yǔ)言)、從右到左或雙向(bi-di)文本布局,等等。

值得注意的是,PDO 不對(duì)該數(shù)據(jù)做任何特殊的事情。有些驅(qū)動(dòng)程序允許更改為一個(gè)連接使用的編碼,但是在 PDO 級(jí)沒(méi)有處理這種事情的特殊邏輯。其原因是,PHP 內(nèi)部完全不知道 unicode,所以在這里試圖使 PDO 知道 unicode 是沒(méi)有意義的。如果您對(duì)這方面的專題感興趣,那么您會(huì)欣喜地得知,PHP 的 unicode 支持很快就要出現(xiàn),不過(guò)我也不知道它初次露面的確切日期。

在Unix環(huán)境下PHP5.1以上版本中:

如果你正在使用PHP5.1版本,PDO和PDO SQLITE已經(jīng)包含在了此發(fā)行版中;當(dāng)你運(yùn)行configure時(shí)它將自動(dòng)啟用。推薦你將PDO作為共享擴(kuò)展構(gòu)建,這樣可以使你獲得通過(guò)PECL升級(jí)的好處。推薦的構(gòu)建支持PDO的PHP的configure line應(yīng)該也要啟用zlib。你也應(yīng)該啟用你選擇的數(shù)據(jù)庫(kù)的PDO驅(qū)動(dòng) ;關(guān)于這個(gè)的更多信息請(qǐng)查看database-specific PDO drivers ,但要注意如果你將PDO作為一個(gè)共享擴(kuò)展構(gòu)建,你必須也要將PDO驅(qū)動(dòng)構(gòu)建為共享擴(kuò)展。SQLite擴(kuò)展依賴于PDO,所以如果PDO作為共享擴(kuò)展構(gòu)建,SQLite也應(yīng)當(dāng)這樣構(gòu)建

./configure --with-zlib --enable-pdo=shared --with-pdo-sqlite=shared --with-sqlite=shared

將PDO安裝為一個(gè)共享模塊后,你必須編輯php.ini文件使得在PHP運(yùn)行時(shí)自動(dòng)載入PDO擴(kuò)展。你同樣需要啟用那兒的特定數(shù)據(jù)庫(kù)驅(qū)動(dòng);確保他們列出在 pdo. so 行之后,因?yàn)镻DO必須在特定數(shù)據(jù)庫(kù)驅(qū)動(dòng)載入之前初始化。如果你是以靜態(tài)方式構(gòu)建的PDO和特定數(shù)據(jù)庫(kù)驅(qū)動(dòng)擴(kuò)展,你可以跳過(guò)這一步。

extension=pdo. so

讓PDO作為一個(gè)共享的模塊將使你可以在新版PDO發(fā)布時(shí)運(yùn)行 pecl upgrade pdo 命令升級(jí),而不用強(qiáng)制你重新構(gòu)建整個(gè)PHP。注意如果你是這樣做的,你也需要同時(shí)升級(jí)你的特定數(shù)據(jù)庫(kù)驅(qū)動(dòng)。

在windows環(huán)境下PHP5.1以上版本中:

PDO和主要數(shù)據(jù)庫(kù)的驅(qū)動(dòng)同PHP一起作為擴(kuò)展發(fā)布,要激活它們只需簡(jiǎn)單的編輯php.ini文件:

extension=php_pdo.dll

然后,選擇針對(duì)特定數(shù)據(jù)庫(kù)的DLL文件使用 dl() 在運(yùn)行時(shí)加載,或者在php.ini文件中 php_pdo.dll 行后啟用它們,如:

extension=php_pdo.dll

extension=php_pdo_firebird.dll

extension=php_pdo_informix.dll

extension=php_pdo_mssql.dll

extension=php_pdo_mysql.dll

extension=php_pdo_oci.dll

extension=php_pdo_oci8.dll

extension=php_pdo_odbc.dll

extension=php_pdo_pgsql.dll

extension=php_pdo_sqlite.dll

這些DLL文件應(yīng)當(dāng)存在于系統(tǒng)的 extension_dir 目錄里。

注意 PDO_INFORMIX 只能作為一個(gè)PECL擴(kuò)展使用。

========================================================================================

PHP 5.1 發(fā)布時(shí)將附帶一個(gè)全新的數(shù)據(jù)庫(kù)連接層,即 PHP Data Objects (PDO)。雖然 PHP 一直都擁有很好的數(shù)據(jù)庫(kù)連接,但 PDO 讓 PHP 達(dá)到一個(gè)新的高度。學(xué)習(xí)如何獲得、安裝和使用 PDO,以連接到 IBM? DB2? Universal Database? 和 IBM Cloudscape? 數(shù)據(jù)庫(kù),插入和檢索數(shù)據(jù),并探索更多高級(jí)特性,例如預(yù)處理語(yǔ)句(prepared statements)、綁定參數(shù)(bound parameters)、可滾動(dòng)游標(biāo)(scrollable cursors)、定位更新(positioned updates)以及 LOB。

PHP 5.1 發(fā)布時(shí)將附帶 PDO,但是也可以通過(guò) PECL 這個(gè) PHP 擴(kuò)展庫(kù)(PHP Extension Repository)來(lái)結(jié)合使用 PDO 和 PHP 5.0.3 及以上版本。如果您使用的是 Windows,那么您會(huì)欣喜地發(fā)現(xiàn)安裝過(guò)程要簡(jiǎn)單得多。

我將假設(shè)您已經(jīng)擁有配置 PHP 5 使之使用您選擇的 Web 服務(wù)器的經(jīng)驗(yàn),只有在此假設(shè)下,我才能集中精力關(guān)注更相關(guān)的細(xì)節(jié)。同樣,我還將假設(shè)您使用的是一個(gè) DB2 Universal Database 服務(wù)器或網(wǎng)絡(luò)服務(wù)器模式下的 IBM Cloudscape 數(shù)據(jù)庫(kù),并且接受了用戶為 db2inst1、密碼為 ibmdb2 的默認(rèn)安裝選項(xiàng)。如果您自己編譯驅(qū)動(dòng)程序,那么在進(jìn)行編譯的機(jī)器上,應(yīng)該安裝有 DB2 客戶機(jī),并且存在應(yīng)用程序開(kāi)發(fā) header,否則編譯將遭到失敗。

pdo文獻(xiàn)

一種新型可循環(huán)利用的生物降解高分子材料PPDO 一種新型可循環(huán)利用的生物降解高分子材料PPDO

格式:pdf

大小:2.3MB

頁(yè)數(shù): 11頁(yè)

評(píng)分: 4.7

聚對(duì)二氧環(huán)己酮(PPDO)是一種具有良好生物降解性和生物相容性的脂肪族聚酯醚,其獨(dú)特的醚酯結(jié)構(gòu)又賦予了材料高強(qiáng)度和良好的柔韌性,是一種理想的生物醫(yī)用材料。綜述了近年來(lái)針對(duì)PPDO單體合成、開(kāi)環(huán)聚合、PPDO結(jié)構(gòu)與性能,納米復(fù)合、淀粉共聚等方面的相關(guān)研究成果。隨著單體對(duì)二氧環(huán)己酮(PDO)合成技術(shù)的突破而導(dǎo)致成本的大幅度下降、PDO開(kāi)環(huán)聚合可控性的實(shí)現(xiàn)以及PPDO納米復(fù)合材料的原位合成對(duì)性能的有效改善,必將推進(jìn)該聚合物在一次性使用塑料領(lǐng)域的廣泛應(yīng)用。

立即下載
蘇丹PDOC石油公司總部辦公大樓空調(diào)設(shè)計(jì) 蘇丹PDOC石油公司總部辦公大樓空調(diào)設(shè)計(jì)

格式:pdf

大?。?span id="qgsx96b" class="single-tag-height">2.3MB

頁(yè)數(shù): 4頁(yè)

評(píng)分: 4.5

介紹了該海外工程的空調(diào)冷源及室內(nèi)空調(diào)系統(tǒng)的設(shè)計(jì)。歸納總結(jié)了該工程在應(yīng)用國(guó)際先進(jìn)的計(jì)算軟件、空調(diào)系統(tǒng)形式、節(jié)能措施、自控手段及噪聲控制等方面的設(shè)計(jì)特點(diǎn),并闡述了設(shè)計(jì)中遇到的難點(diǎn)及設(shè)計(jì)體會(huì)。

立即下載

產(chǎn)品名稱(中文)LAP Dorado 激光定位系統(tǒng)

產(chǎn)品名稱(英文)LAP Dorado Laser Positioning Systems

注冊(cè)號(hào)國(guó)食藥監(jiān)械(進(jìn))字2005第2240139號(hào)

產(chǎn)品性能結(jié)構(gòu)及組成結(jié)構(gòu):固定激光燈, 可移動(dòng)激光軌,手控盒。性能:可移動(dòng)激光軌移動(dòng)范圍600mm;激光移動(dòng)定位精度±0.25mm。

產(chǎn)品適用范圍該定位系統(tǒng)與CT掃描設(shè)備安裝在一起,在病人皮膚上投射出用作標(biāo)記的位置參考點(diǎn), 供對(duì)病人腫瘤放射治療時(shí)定位之用。

注冊(cè)代理德國(guó)LAP激光應(yīng)用有限公司上海代表處

售后服務(wù)機(jī)構(gòu)德國(guó)LAP激光應(yīng)用有限公司上海代表處

批準(zhǔn)日期2005.01.17

有效期截止日2009.01.16

備注LAP GmbH Laser Application,

生產(chǎn)廠商名稱(英文)LAP GmbH Laser Application

生產(chǎn)廠地址(中文)Zeppelinstr. 23 D-21337 Luneburg, Germany

生產(chǎn)場(chǎng)所Zeppelinstr. 23 D-21337 Luneburg, Germany

生產(chǎn)國(guó)(中文)德國(guó)

規(guī)格型號(hào)Dorado CT-1-1, Dorado CT-1-3, Dorado CT-1-4、

產(chǎn)品標(biāo)準(zhǔn)YZB/GEM 1738-24-2004 《LAP Dorado 激光定位系統(tǒng)》

單品 產(chǎn)品名稱 產(chǎn)地/廠商 地域 價(jià)格 (元/噸) 漲跌 報(bào)價(jià)日期 DOP DOP 東莞盛和 全國(guó) 12800 0 12-08-07 DOP DOP 浙江慶安 全國(guó) 12500 0 12-08-07 DOP DOP 鎮(zhèn)江聯(lián)成 全國(guó) 12500 0 12-08-07 DOP DOP 山東宏信 全國(guó) 12400 100 12-08-07 DOP DOP 愛(ài)敬寧波 全國(guó) 12600 100 12-08-07 DOP DOP 齊魯增塑劑 全國(guó) 12500 100 12-08-07 DOP DOP 寧波聯(lián)泰 全國(guó) 12500 0 12-08-07 DOP DOP 寧波東來(lái) 全國(guó) 12500 0 12-08-07 DOP DOP 金陵石化 全國(guó) 12500 0 12-08-07 DOP DOP 浙江偉博 全國(guó) 12500 0 12-08-07

單品 產(chǎn)品名稱 產(chǎn)地/廠商 地域 價(jià)格 (元/噸) 漲跌 報(bào)價(jià)日期 DOP DOP 東莞盛和 全國(guó) 12800 -100 12-08-06 DOP DOP 浙江慶安 全國(guó) 12500 0 12-08-06 DOP DOP 鎮(zhèn)江聯(lián)成 全國(guó) 12500 0 12-08-06 DOP DOP 山東宏信 全國(guó) 12300 0 12-08-06 DOP DOP 愛(ài)敬寧波 全國(guó) 12500 0 12-08-06 DOP DOP 齊魯增塑劑 全國(guó) 12400 0 12-08-06 DOP DOP 寧波聯(lián)泰 全國(guó) 12500 0 12-08-06 DOP DOP 寧波東來(lái) 全國(guó) 12500 0 12-08-06 DOP DOP 金陵石化 全國(guó) 12500 0 12-08-06 DOP DOP 浙江偉博 全國(guó) 12500 0 12-08-06

pdo相關(guān)推薦
  • 相關(guān)百科
  • 相關(guān)知識(shí)
  • 相關(guān)專欄

最新詞條

安徽省政采項(xiàng)目管理咨詢有限公司 數(shù)字景楓科技發(fā)展(南京)有限公司 懷化市人民政府電子政務(wù)管理辦公室 河北省高速公路京德臨時(shí)籌建處 中石化華東石油工程有限公司工程技術(shù)分公司 手持無(wú)線POS機(jī) 廣東合正采購(gòu)招標(biāo)有限公司 上海城建信息科技有限公司 甘肅鑫禾國(guó)際招標(biāo)有限公司 燒結(jié)金屬材料 齒輪計(jì)量泵 廣州采陽(yáng)招標(biāo)代理有限公司河源分公司 高鋁碳化硅磚 博洛尼智能科技(青島)有限公司 燒結(jié)剛玉磚 深圳市東海國(guó)際招標(biāo)有限公司 搭建香蕉育苗大棚 SF計(jì)量單位 福建省中億通招標(biāo)咨詢有限公司 泛海三江 威海鼠尾草 廣東國(guó)咨招標(biāo)有限公司 Excel 數(shù)據(jù)處理與分析應(yīng)用大全 甘肅中泰博瑞工程項(xiàng)目管理咨詢有限公司 山東創(chuàng)盈項(xiàng)目管理有限公司 當(dāng)代建筑大師 廣西北纜電纜有限公司 拆邊機(jī) 大山檳榔 上海地鐵維護(hù)保障有限公司通號(hào)分公司 甘肅中維國(guó)際招標(biāo)有限公司 舌花雛菊 湖北鑫宇陽(yáng)光工程咨詢有限公司 GB8163標(biāo)準(zhǔn)無(wú)縫鋼管 中國(guó)石油煉化工程建設(shè)項(xiàng)目部 華潤(rùn)燃?xì)猓ㄉ虾#┯邢薰? 韶關(guān)市優(yōu)采招標(biāo)代理有限公司 莎草目 建設(shè)部關(guān)于開(kāi)展城市規(guī)劃動(dòng)態(tài)監(jiān)測(cè)工作的通知 電梯平層準(zhǔn)確度 廣州利好來(lái)電氣有限公司 蘇州弘創(chuàng)招投標(biāo)代理有限公司