拖了兩天,今晚終於有時間寫下篇了。可是,對著電腦,卻有點不知道從何說起。或許,就照著ZEND FRAMEWORK來說吧。當然,我會把握要點,記得這篇文章是以zend framework為例來闡述我對物件導向方式程式設計的認識,而不是一篇zend framework的入門手冊,並且,這也不會是一個物件導向的入門教程,而是我對物件導向的理解。
02 一、統一入口文件
03 在許多人眼裡,php仍然不能算是「完全」物件導向的,理由就是物件導向應該是所有程式要全部留化,而PHP還可以算有一個入口文件。但這種學術上的爭論,和我們其實是沒什麼關係的。我們只需要知道,作為一個完全物件導向的應用,除了index.php之外,所有程式都應該是以類別的方式寫的。
04 在zend framework中,使用了rewrite技術,rewrite不僅利用偽靜態功能吸引搜尋引擎收錄,還可以禁止index以為的PHP檔案直接運作從而避免安全隱患。在joomla中,rewrite是可以在後台中選擇的,即使是面向過程的項目,discuz和phpwind也都提供了rewrite的選項,而在zend framework中,說起來可能會讓很多zf的初學者嘔血,其實用或不用rewrite,根本不需要設定的,只不過是連結的URL位址不同罷了。很奇怪的,似乎所有資料上都沒有提及這一點,其實,我們完全可以在IIS下和絕大多數支援PHP的虛擬主機上使用zend framework而不必擔心rewrite的問題。
05 當然了,我個人對rewrite技術還是非常擁護的,對我而言,這項技術至少有三個好處:1、用偽靜態方式增加搜尋引擎蒐錄;2、保護重要文件及危險文件不被運行和下載;3、用PHP產生圖片檔時,其URL位址和真實的圖片地址格式完全相同。
06 所以,一個好的物件導向程序,應該要統一入口文件,並用rewrite功能限制不合規範的其它php文件的使用。
07 二、MVC模式
08 MVC是一種非常經典的程式設計方式。我在本文的上篇就已經提過,如果純粹追求執行效率,每個程式頁面一個文件,才是最有效率的。但是人力有其極限,所以終究需要把文件切割開來,並依照一定規律將文件歸類。如果你做PHP夠久,應該看過各種五花八門的切割和文件歸類方式,而其中,昇華為模式並為主流所接受的,只有MVC。
09 如果說程式和頁面分開,也就是view視圖獨立,已經為大家所公認,那麼控制器和模型是不是要分開,很多人還是有不同意見的。一開始我也覺得,小專案裡不需要這麼講究,但不久後就發現模型的好處了。模型在功能上很大程度與過程導向專案中的函數庫相似,函數庫的好處,我在本文上篇一開始久已經說過,這些理由同樣適合與模型,功能總是應該被細分為函數的,MODEL只不過是對這些函數進行統一歸類而已。模型與函數庫的最主要區別,在於我們通常為每個資料表建立一個模型,這樣,每個模型中的方法不至於過多,方法的命名也可以統一。例如函數庫中,刪除文章命名為delArticle(),刪除圖片命名為delPicture(),刪除使用者命名為delUser(),而用模型一分開,統一都叫del()是不是整潔多了?
10 所以,無論項目大小,只要用到資料庫,那麼使用MODEL總是值得的。
11 一個值得商榷的問題是,從理論上說,model只負責資料處理,不負責輸出顯示的,而我之前的幾個項目中,也規規矩矩的把輸出放到了zend framework的視圖助手中。但最近,我剛剛在model中直接建立了生成列表和目錄樹的方法,和視圖助手相比,多少省了點時間,而且也沒發現有什麼壞處,所以,在沒有發現問題之前,我會繼續在model中做一些小量的輸出:產生string,並傳回給controller中的相關呼叫指令。現在想想,或許是我理解錯誤,也許資料中提到的MODEL不負責輸出,只是要求不用echo等方式直接顯示頁面,生成string,或許本來就是允許的。
12 三、phpunit測試架構
13 在過程導向的程式設計中,很多人在需要時寫函數,然後在需要呼叫函數處直接呼叫函數進行測試。也許很多人跟我一樣,某一天突然發現自己無法忍受各種以外因素的感染,而新建了一個test.php來進行這些測試,而後,測試逐漸增加,test.php就改成了test資料夾,裡面存放所有函數的測試,這就是phpunit的雛形了。在整個程式設計過程中,測試佔據了我們大量時間,而phpunit保存了這些測試,節省了我們在日後修改類別和方法時的大量測試時間。
14 四、類別的抽象與繼承
15 在我的程式碼中,一直在繼承,而很少抽象化。抽象和介面對我們編寫程式做了強制性的定義要求,所以,對於合作者不多的程式設計師來說,似乎沒有太大的意義。但是,也正是因為程式設計過程中的自由散漫,往往會在事後然我們或是我們的下一任程式設計師嚐到苦果。之前在開篇中我就提過,寫這個帖子,是我對之前經驗的反思過程,所以,在這裡,我要說的是,之前我寫的代碼,是極少有抽象和接口的,而在在以後的工作中,我將補上這一點,從而統一我對屬性和方法的命名。
16 五、設計模式
17 迄今為止,人們一共總結了23種設計模式,其中我用到比較多的有註冊模式、工廠模式和單件模式。設計模式是對前人物件導向程式設計方法的總結,幸運的是,當我用zend framework框架程式設計時,很多時候都並不需要太多了解它們的技術細節就能直接利用,例如註冊類zend_register用到了註冊模式,zend_form則大量採用了裝飾模式,而反射API之類的技術,也都得到了合理的應用。當然,反過來說,zend framework的學習難度也因此增加,我們學習一門技術,往往不滿足於知其然,而想知道所以然,而這些模式,顯然不是一本手冊所能涵蓋的,ZEND FRAMEWORK之所以難於掌握,與我們對於設計模式等相關知識了解不深,有很大的關係。
18 六、框架
19 許多人對zend framework身懷恐懼,寧可去學習一些小型的輕量級框架,也不願意接觸zend framework,理由是,它太龐大了。事實上,我自己也為學習和應用zend framework而吃了不少苦,浪費了大量時間。最後,我終於幡然醒悟,框架改變了我們原先的程式設計思維,我們應該向手冊和入門指南中說的那樣去用框架,而不是堅持我們的習慣,改變框架來適應我們,否則必然事倍功半,得不償失。例如,我最近寫了一個網站,它的功能有這樣幾個:
20 1、顯示論壇中投稿區中的所有文章分類清單和文章內容;
21 2、顯示作者的所有投稿文章。 ;
22 3、自動產生google的sitemap。
23 功能確實是相當少的,但連設計頁在內,基於zend framework完成這個網站,我總共只用了兩天時間(而且還不是兩個全天)。所以說,雖然號稱重量級框架,zend framework對小型專案的開發確實是適合的。如果你覺得zend framework太大,你完全可以不使用那麼多多功能類別函式庫,掌握了哪些,就用哪些。 zend framework的問題在於它的功能太多,不可能透過一個專案完全掌握,所以千萬記得要循序漸進才行。
24 當然,其實我們也可以完全不用框架,而自己以MVC方式為主體編寫物件導向程序,所以,我無法理解的,反而是那些輕量級框架的存在意義。如果一個框架只是一個MVC模式的架構器,那麼,就像對smarty的困惑一樣,我們為什麼不自己直接來寫呢?
25 例如可以寫:
26 index.php
27
?28 30 $controller=$ _GET['controller']; 31 require_once 'controller/'.$controller.'.php'; 32 33 $controller=$ _GET['controller']; ller.'.php'; 35 36 controller.php 37 38 view plaincopy to clipboard?39
40 require_once 'some_model.php';
string=$model->getString; 43 require_once 'templates/templte.phtml'; 44 45 require_once 'some_model.php'; 46 >getString; 48 require_once 'templates/templte.phtml' ; 49 50 some_model.php 51 查看純文字到剪貼簿列印? 52 53 類別 Some_Model 擴充 PDO{55 $string='hello世界!
56 返回 $string;
59 60 類 Some_Model 擴充了 PDO{ 61 $string='你好世界! '; 63 與 $string; 64 67 template.phtml 68 69 檢視剪貼簿列印的純文字? 70 71 ...... 72 74 75