《PHP設(shè)計(jì)模式介紹》第十四章 動(dòng)態(tài)記錄模式(4)_PHP教程
推薦:《PHP設(shè)計(jì)模式介紹》第十三章 適配器模式接口的改變,是一個(gè)需要程序員們必須(雖然很不情愿)接受和處理的普遍問(wèn)題。程序提供者們修改他們的代碼;系統(tǒng)庫(kù)被修正;各種程序語(yǔ)言以及相關(guān)庫(kù)的發(fā)展和進(jìn)化。我孩子的無(wú)數(shù)玩具中有一個(gè)簡(jiǎn)要地描
然而,因?yàn)闀?shū)簽類的構(gòu)造函數(shù)調(diào)用了靜態(tài)方法DB:conn()來(lái)獲取數(shù)據(jù)庫(kù)連接,要注入模擬連接到其中就很困難了。這兒有一些可能的實(shí)現(xiàn)方法:增加一個(gè)方法來(lái)改變$this->conn,增加一個(gè)可選參數(shù)到每一個(gè)方法中,或是增加一個(gè)參數(shù)到構(gòu)造函數(shù)中。讓我們選用最后一種方法:給Bookmark的構(gòu)造函數(shù)增加一個(gè)可選的參數(shù)。
| class Bookmark { // ... public function __construct($id=false, $conn=false) { $this->conn = ($conn) ? $conn : DB::conn(); // ... } } |
現(xiàn)在,新的Bookmark依然能正常工作,但新的Bookmark(1, $connection)用參數(shù)中的$connection對(duì)象代替正常的ADOConnection對(duì)象。
當(dāng)這段代碼完成后,你就能方便的將正常的數(shù)據(jù)庫(kù)連接對(duì)象用模擬的連接對(duì)象進(jìn)行替換,并且能進(jìn)行數(shù)據(jù)庫(kù)錯(cuò)誤的檢測(cè)。
| class ActiveRecordTestCase extends UnitTestCase { // ... function testDbFailure() { $conn = new MockADOConnection($this); $conn->expectOnce(‘execute’, array(‘*’,’*’)); $conn->setReturnValue(‘execute’,false); $conn->expectOnce(‘errorMsg’); $conn->setReturnValue(‘errorMsg’, ‘The database has exploded!!!!’); $link = new Bookmark(1,$conn); $this->assertErrorPattern(‘/exploded/i’); $conn->tally(); } |
動(dòng)態(tài)記錄實(shí)例ID
在前面的例子中,大多數(shù)屬性都是公共的,然而,書(shū)簽ID是受保護(hù)的,以其值被免意外更改(如果其值被意外更改,當(dāng)你想更新書(shū)簽數(shù)據(jù)的時(shí)候問(wèn)題就出現(xiàn)了)。因?yàn)?ID是受保護(hù)的,因此增加一個(gè)輔助方法來(lái)獲取其值。
| class Bookmark { protected $id; //... public function getId() { return $this->id; } } |
怎樣來(lái)測(cè)試它呢?
| class ActiveRecordTestCase extends UnitTestCase { // ... function testGetId() { $this->add(‘http://php.net’, ‘PHP’, ‘PHP Language Homepage’, ‘php’); // second bookmark, id=2 $link = $this->add(‘http://phparch.com’, ‘php|architect’, ‘php|arch site’, ‘php’); $this->assertEqual(2, $link->getId()); } } |
如上,add()方法生并成保存數(shù)據(jù),并通過(guò)getid()方法獲取生成數(shù)據(jù)的ID值并驗(yàn)證其是相匹配的。
但是,如果你想用別的條件來(lái)驗(yàn)證所生成的數(shù)據(jù)而不僅僅是用書(shū)簽的ID,或是你如何確保從數(shù)據(jù)庫(kù)中返回的ID是正確的?用select語(yǔ)句根據(jù)給定的屬性條件取得數(shù)據(jù),并驗(yàn)證返回行的ID值是一個(gè)好的技術(shù)方法。
| class ActiveRecordTestCase extends UnitTestCase { // ... function testGetId() { $this->add(‘http://php.net’, ‘PHP’, ‘PHP Language Homepage’, ‘php’); // second bookmark, id=2 $link = $this->add(‘http://phparch.com’, ‘php|architect’, ‘php|arch site’, ‘php’); $this->assertEqual(2, $link->getId()); $alt_test = $this->conn->getOne( “select id from bookmark where url = ‘http://phparch.com’”); $this->assertEqual(2, $alt_test); //alternatively $this->assertEqual($link->getId(), $alt_test); } } |
注意到這個(gè)試驗(yàn)類似于你用手工執(zhí)行一個(gè)SQL查詢來(lái)驗(yàn)證數(shù)據(jù)是否正確插入到書(shū)簽表中。通過(guò)本次實(shí)驗(yàn)所實(shí)現(xiàn)代碼,還能用于你后續(xù)實(shí)驗(yàn)中來(lái)驗(yàn)證數(shù)據(jù)的正確性,而不是僅僅簡(jiǎn)單的去執(zhí)行它。
記錄搜索
現(xiàn)在,我們已能實(shí)現(xiàn)保存書(shū)簽對(duì)象到數(shù)據(jù)庫(kù),并且能根據(jù)書(shū)簽ID從數(shù)據(jù)庫(kù)中獲取相應(yīng)數(shù)據(jù)來(lái)重建書(shū)簽對(duì)象。但是當(dāng)ID值并不知道(通常情況也是這樣)時(shí)會(huì)發(fā)生什么?或是你想通過(guò)如部分名稱或是URL等相關(guān)值來(lái)搜索數(shù)據(jù)庫(kù),則更常見(jiàn)的解決方法是增加一個(gè)”finder”方法。
例如,你也許想使用findByUrl()方法查找與給定參數(shù)相類似的書(shū)簽,下面的實(shí)驗(yàn)則能實(shí)現(xiàn)上述的要求。
| class ActiveRecordTestCase extends UnitTestCase { // ... function testFindByUrl() { $this->add(‘http://blog.casey-sweat.us/’, ‘My Blog’, ‘Where I write about stuff’, ‘php’); $this->add(‘http://php.net’, ‘PHP’, ‘PHP Language Homepage’, ‘php’); $this->add(‘http://phparch.com’, ‘php|architect’, ‘php|arch site’, ‘php’); $result = Bookmark::findByUrl(‘php’); $this->assertIsA($result, ‘array’); $this->assertEqual(2, count($result)); $this->assertEqual(2, $result[0]->getId()); $this->assertEqual(‘php|architect’, $result[1]->name); } } |
該實(shí)驗(yàn)生成一些數(shù)據(jù),查找URL中包含有“PHP”字樣的行,并校檢返回的書(shū)簽對(duì)象數(shù)組中的字符。FindByUrl()之所以是一個(gè)靜態(tài)方法,是因?yàn)槟阌锌赡茉跊](méi)的書(shū)簽對(duì)象實(shí)例化的情況下進(jìn)行該操作。(當(dāng)然你也能將“查找“方法放到每一個(gè)對(duì)象中,但目前 “查找”方法仍然是書(shū)簽類中的一個(gè)方法。)
分享:《PHP設(shè)計(jì)模式介紹》第十二章 裝飾器模式若你從事過(guò)面向?qū)ο蟮膒hp開(kāi)發(fā),即使很短的時(shí)間或者僅僅通過(guò)本書(shū)了解了一些,你會(huì)知道,你可以 通過(guò)繼承改變或者增加一個(gè)類的功能,這是所有面向?qū)ο笳Z(yǔ)言的一個(gè)基本特性。如果已經(jīng)存在的一個(gè)php
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁(yè)面代碼執(zhí)行時(shí)間
- PHP中獎(jiǎng)概率的抽獎(jiǎng)算法程序代碼
- apache設(shè)置靜態(tài)文件緩存方法介紹
- php對(duì)圖像的各種處理函數(shù)代碼小結(jié)
- PHP 關(guān)于訪問(wèn)控制的和運(yùn)算符優(yōu)先級(jí)介紹
- 關(guān)于PHP語(yǔ)言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國(guó)語(yǔ)言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
PHP教程Rss訂閱編程教程搜索
PHP教程推薦
- 使用php+apc實(shí)現(xiàn)上傳進(jìn)度條且在IE7下不顯示的問(wèn)題解決方法
- 解析PHP漢字驗(yàn)證碼的實(shí)現(xiàn)
- PHP讀取RSS feed源代碼(帶注釋,可讀取多個(gè)源)
- 用什么軟件打開(kāi)php文件
- 如何設(shè)置mysql允許外網(wǎng)訪問(wèn)
- 用PHP5的DirectoryIterators遞歸掃描目錄
- AJAX在PHP中的簡(jiǎn)單使用
- PHP5中Cookie與 Session使用詳解
- 用PHP與XML聯(lián)手進(jìn)行網(wǎng)站開(kāi)發(fā)
- 淺談PHP企業(yè)級(jí)應(yīng)用之WebService
- 相關(guān)鏈接:
復(fù)制本頁(yè)鏈接| 搜索《PHP設(shè)計(jì)模式介紹》第十四章 動(dòng)態(tài)記錄模式(4)
- 教程說(shuō)明:
PHP教程-《PHP設(shè)計(jì)模式介紹》第十四章 動(dòng)態(tài)記錄模式(4)
。