亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝

2019-09-08 23:11:16
字體:
來源:轉載
供稿:網友
編碼對于合格的PHP程序員來說并不是什么難事(也許只是花費時間長短的問題),因此系統分析和設計這一階段就顯得尤為重要。不過本文并不打算討論和需求分析、獲取商業邏輯相關的話題,而是針對系統設計方面進行探討。

面臨難題
編碼對于合格的PHP程序員來說并不是什么難事(也許只是花費時間長短的問題),因此系統分析和設計這一階段就顯得尤為重要。對于一個擔任PHP項目的系統分析員來說,面臨著兩個難題:

  1. PHP語言本身的限制。
    這一點在復雜系統的面向對象設計中尤其顯著。PHP的面向對象特性在現有版本中雖然得到了改善,但是還不甚健全,根本不足以擔任面向對象設計的實現語言;即使眼光長遠一些,在即將釋出的以Zend Engine 2.0支持的全新PHP中,面向對象特性也不會像現在流行的Java或者C++那樣(關于這方面的內容可以參見我在developerWorks中國網站發表的另一篇文章)。但是如果采用完全面向過程(準確說是面向Web頁面)的方式,可以想見整個系統的設計會非常復雜,而由此帶來的編碼復雜和維護困難更加難以應付。
  2. 現有資料的嚴重缺乏。
    這是眾所周知的現象即針對Web項目的系統設計資料不足;而在這些有限資料中,關于PHP的設計資料又非常匱乏。如果本公司或本人也沒有相關的技術積累,系統分析員只能在黑暗中摸索方法(更壞的兩種情況,一是照搬其他項目比如Java或者C++的設計,二是認為項目簡單而不負責任的草草了事)。


認識面對的系統
既然如此,采用何種方法妥善處理PHP系統的分析和設計?最初的構想應該需要分清項目承擔任務的類型:

  1. 涉及大量客戶本身或者客戶所在行業的商業邏輯的項目,包括辦公系統、訂單系統以及其他商業系統。
  2. 簡單網站項目,包括一些需要承擔高訪問量或要求快速響應的項目比如品牌網站或者活動網站以及其他一些網站。
  3. 綜合性網站項目。通常包含多個相對獨立的子系統比如新聞子系統、論壇子系統、產品陳列子系統等等。


PHP的設計初衷在于解決后兩種項目的迫切需求,語言本身對于這些項目進行了良好的改造。而眾多的PHP開發者對這些項目也具有或多或少的經驗,相關書籍中的范例也大都圍繞于此。相對說來第一種系統所有的資料不多,各種出版物對其內容也很少提及。因此在本文中將題所述對第一種類型的項目進行詳細講述(有關MVC模式和類封裝),同時附帶提及第二種項目(有關黑客代碼)以及第三種項目的設計方法。當然,并不是被歸類的這些項目就只能采用本文描述的方式,系統分析員需要權衡各方面因素加以選擇。

方案一:涉及大量商業邏輯項目
如何分離用戶界面和后臺操作?如何避免將商業邏輯混淆于一般的流程控制中?作為一個嚴謹的商用項目,就需要考慮很多類似的問題。對于由PHP擔當的這類項目,貫徹Model-View-Controller(MVC)模式的設計是一個非常好的方法。

理論描述
在這里我不想多加解釋MVC模式本身--簡單的從字面上以及應用上說,通過將系統的設計分為Model模型/邏輯、View視圖/界面、Controller控制/流程三個邏輯部分達到良好的項目效果,以此便利各部分開發者的工作并降低日后的維護成本。(如果您熟悉JSP開發的Model 2模式,可以發現它也是MVC模式的很好體現。)就現實的項目開發而言,現存的很大問題包括網頁設計人員和程序開發人員的工作交錯和沖突以及商業邏輯嵌入頁面造成不可重用也很難維護等等。引入MVC模式一方面可以為系統的總體設計指出明確的方向,對于開發團隊的分工也是良好的指導。

既然依照MVC模式要求對系統的總體結構在邏輯上分成三部分,那么團隊的開發者中也存在著針對各個部分的開發者。

開發者角色相關系統邏輯職責
網頁設計人員View視圖/界面設計所有用戶界面的網頁模板。
控制流程開發人員Controller控制/流程編寫系統流程中的所有PHP頁面。
商業邏輯開發人員Model模型/邏輯開發系統設計中規定的各個類(其中的方法)。


由以上的表格可以看出,傳統的網頁設計和程序開發的人員分工被打破而取而代之的是根據系統邏輯劃定的職責。對于網頁設計人員,職責并沒有改變,準確說由于這樣的劃分避免了以往與程序設計人員的糾紛,他們完成的只是網頁模板,因此只需關注于純粹的網頁代碼(主要是HTML,也許會有其他客戶端的代碼比如WML之類)而根本不需要被服務器端的<? … ?>干擾。程序設計人員則被分為兩部分:其中比較容易把握的是商業邏輯開發人員,他們的任務是根據系統分析員給定的模塊(準確說是類方法)完成之,在他們手中的PHP更像一般的程序設計語言(比如Java)而與Web沒有什么關系;一時較難接受的是控制流程開發人員,他們的任務是在實現系統設計時制定的系統流程的同時,根據客戶端的輸入調用商業邏輯(相應的類方法)以及輸出更新的界面(對設計網頁模板進行處理),在他們手中PHP可以充分發揮Web編程語言的優勢。

代碼組織相關的話題
這樣的觀念有些抽象,沒有實例的演示很難接受。在舉例之前先介紹一下我對這類工程的推薦代碼結構:

一級目錄二級目錄三級目錄備注
/project_name 項目源代碼根目錄
/Templates 網頁模板目錄(View)
/admin管理控制臺目錄/admin下的網頁模板
/Include 商業邏輯目錄(Model)
/Temp  臨時代碼目錄(可選),可供開發者進行一些試驗代碼的測試
/images 圖片目錄,網頁模板采用
/css 樣式單目錄,網頁模板采用
/scripts  客戶端代碼目錄,網頁模板采用
/admin 管理控制臺目錄(可選),包含所有后臺管理的功能代碼
/other_dir對應與源代碼根目錄下的/other_dir,包含管理該類的功能代碼
/other_dir 其他與相應功能相關的目錄,比如與用戶相關的/member目錄或者與從產品相關的/product目錄等等
/config.inc.php 全局配置變量,定義系統中的全局變量
/security.inc.php 安全策略控制(可選)
/error.php 錯誤控制返回頁面(可選),也可以采用靜態頁面如/error.html或者其他頁面名稱


看完之后您是不是被喚起了一點使用Java進行Web開發的記憶?比如WEB-INF目錄下的classes目錄和lib目錄以及web.xml都是開發中的規則--雖然支持PHP的Web服務器不可能像Java應用服務器那樣自動加載這些目錄下的文件,但是規定一個合適的代碼組織模式還是非常有利于開發的便利和后續的維護的。(我開始考慮PHP項目的代碼結構就是由Tomcat的開發手冊中獲得了啟發。)

一個用戶登錄的例子
根據以上的代碼目錄,前文所說的MVC模式的實現可以得到更簡單的解釋。以最常見的用戶登錄功能為例,設想/project_name目錄下有一個/member目錄包含有關于用戶的一切功能,其中包含了login.php頁面接受用戶登錄使用的用戶名稱和密碼,index.php頁面是登錄完成之后的用戶主頁,而/project_name目錄下的error.php是登錄失敗后的錯誤顯示頁面。

  1. 用戶通過系統的其他部分請求進入用戶主頁即/member/index.php頁面,此時該頁面判斷用戶情況:已登錄用戶則直接顯示本頁內容(可以采用檢查session等方法);未登錄用戶則需要登錄(重定向到/member/login.php);出現了未知錯誤(重定向到/error.php)。同時采取相應的反應。
  2. 假如用戶被引導至登錄頁面即/member/login.php頁面,該頁面接受用戶的登錄信息(用戶名稱和密碼),并判斷是否正確登錄:正確登錄則再次重定向到用戶主頁/member/index.php;登錄錯誤則重定向到/error.php。
  3. 假如用戶被引導至錯誤顯示頁面/error.php頁面(無論是從以上哪個頁面前來),都會顯示錯誤信息。


流程圖示如下:

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝



根據以上的文字描述和圖示,再結合MVC模式的實現,可以非常輕松的寫出這幾個頁面的框架代碼:

  1. 先看簡單的頁面/error.php:
    用封裝類來合理的設計PHP項目--談PHP項目中類的封裝
  2. 然后是/member/login.php:
    用封裝類來合理的設計PHP項目--談PHP項目中類的封裝
  3. 最后是/member/index.php:
    用封裝類來合理的設計PHP項目--談PHP項目中類的封裝


(注意:以上代碼只是片斷,而且沒有考慮項目全局,只起演示作用)

關于Controller
首先可以明確的是,以上的三個頁面代碼就是前文所說的Controller控制/流程代碼。很明顯,他們的不包含特定的操作,也沒有一行網頁代碼,有的只是與前面流程圖一致的流程控制代碼(放眼望去,這些頁面的共同特點是充滿了引用網頁模板并輸出、取得對象并執行其某個方法或者重定向)。

再選擇其中的一個頁面/member/login.php詳細的解釋。整個頁面通過判斷是否提交表單分為兩個部分:顯示登錄表單供用戶填寫和處理登錄信息。作為前者直接引用一個處于網頁模板目錄/Templates下對應該頁面的member_login.dwt并在解析后輸出;作為后者先取得一個Member對象(該對象出于商業邏輯目錄/Include下的Member.inc.php中),然后獲得登錄判斷的結果后進行重定向。在這個控制頁面的代碼中,member_login.dwt作為View視圖/界面出現,類Member作為Model模型/邏輯出現,而頁面代碼本身就Controller控制/流程。下面就是加入標示的/member/login.php框架代碼:

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝



(關于模板類以及在MVC模式中的應用,可以參考本站另一篇文章《在PHP中選擇合適的模板》)

關于Model
既然談到了Model,下面就是另一個重要的話題:類封裝在PHP項目中的應用。

請注意用詞"類封裝"--這和"面向對象"或者其他什么"采用對象設計"的方法有著本質的不同。"類封裝"只是講述了將商業邏輯采用類方法的方式封裝成各個不同的類,因而這里的"類"并不是因此采用了面向對象設計出現的"類"--準確的說,這里的"類"其實是對一系列相關功能模塊進行合并的結果。

為什么不直接采用面向對象的方式而是采用這種看起來不倫不類的辦法去設計系統呢?PHP不是具有面向對象特性嗎?不錯,PHP具有這樣的特性,但是非常不完全(可以參考本站另一篇文章《從Zend Engine 2.0的設計藍圖(草稿)看PHP的將來》)。舉例來說,PHP是沒有接口這一概念和實現方法的,同時也就沒有什么多重繼承、方法重載之類的典型面向對象特征。如果非要采用面向對象的設計方法,也許在概要設計階段可以非常輕松,但是詳細設計階段就會比較苦悶,而如果還有幸堅持到編碼階段簡直就是苦不堪言了。另一方面,如果不在系統中引入類的概念,而是采用函數來實現模塊功能,那么可以想象在一個采用這樣"純粹"的中大型系統中會有多少的函數,由此帶來的麻煩非常明顯。

還是回到PHP語言本身。雖然PHP提供不了什么實際的面向對象支持,但是還是提供了對類以及其中的屬性和方法的定義。那么自然而然可以想到的是采用類的方法封裝相關函數模塊,既可以借鑒一些對象設計的優點,又可以避免完全采用函數模塊的一些缺點。

(一些采用函數模塊的系統會采用這樣一種方式:將相關的函數編寫在相同的文件中,這樣在引用時可以引入單獨的文件。比如Member.func.php這個文件中包含了所有與用戶相關的操作,在處理用戶登錄時可以先require這個文件,然后調用諸如member_login()這樣的函數。但是這樣的方式僅僅解決了系統中眾多函數的代碼組織問題,沒有解決名字沖突的問題。下面的舉例中就會看到。)

比如上文的用戶登錄實例中,如果采用函數模塊的方法,代碼也許是這樣:

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝



而采用類封裝的方法,可能就是這樣:

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝



也許您會覺得代碼并沒有什么區別(甚至看起來采用函數模塊的代碼由于不需要取得新的對象而顯得更簡潔一些),而真正的不同是發生在include的文件里面。采用函數模塊的方法將相關的函數集合在一個文件中加以組織(有些系統還不能做到這一點,那么就會造成異?;靵y的局面),而采用類封裝的方法在每一個文件中聲明一個和文件名相同的類(比如在Member.inc.php聲明一個Member的類,這一點和Java的規定相似);而在使用時,都需要先進行include(如果采用函數模塊又沒有進行很好的組織,也許有些人就會很"簡便"的將所有函數include進每一個頁面--PHP可不是Java那樣編譯執行,光是解析這些函數就會花費一段時間),但是關鍵就在于采用類封裝的方法可以清楚的指明調用的位置--某個類(Member)的某個方法(login):從避免名字沖突的角度來說這一點是非常成功的;而對于代碼檢查和維護而言,方便程度更是不言而喻。設想一個頁面需要完成若干功能,因而需要include數個文件:采用函數模塊的方法不能夠輕易的從函數調用中找到函數本身所在的文件(如果函數名稱或者include文件名稱沒有什么統一規則,那么這個工作就非常艱巨了),而采用類封裝的辦法可以根據類名稱和類文件名稱準確定位類方法代碼的位置。(也許您會認為這樣一個小小的好處不足掛齒,但是經歷一個維護工程之后也許就不會再有什么異議。)

以上是采用類封裝方法的原因,決定采用這種方法設計系統只是第一步;完成整個系統的設計還有很多可以借鑒的經驗。

  1. 部分設計可以借鑒面向對象的思路。雖然PHP中沒有接口和抽象類的定義,繼承機制也非常不完全,但至少具備了基本的類定義和簡單的繼承關系。類似"公司-雇員"、"賣家-商品-買家"這類顯而易見的關系可以很容易在系統中通過類和類關系定義。既然PHP可以做到這一點,就按照實際的邏輯關系去定義即可。
  2. 經常會在系統中出現的另一個情況是關于個體和列表的關系--這樣說也許難以理解,想象一個BBS系統中的帖子列表和每個帖子之間,就是這樣的關系。根據設計經驗,這樣的關系大量存在于PHP或者其他Web系統中。對于這類關系,我個人建議可以采用以下Item和Item_List的類封裝方式:
    • Item類定義:Item.inc.php的代碼
    • Item_List類定義:Item_List.inc.php的代碼
  3. 由于PHP對于類的成員變量和方法并沒有語法上的訪問限制(均為公開),因此會帶來對象使用方面的某些混亂?;诖耍ㄗh在開發團隊的代碼規范中加以規定,從代碼應用的級別上控制這一情況:
    首先,可以通過對成員變量和方法的注釋來說明其屬性,由此使用該對象的其他開發人員可以了解自己的使用方法是否觸犯了規定的訪問限制。(如果采用phpdoc等自動文檔生成的工具,開發人員甚至可以在不翻閱類源碼的情況下通過瀏覽類文檔正確使用它。)
    其次,對于成員變量訪問限制的考慮,可以將一些主要的、經常需要被訪問或更改的變量(在注釋中)聲明為公開。這樣的作法可以省卻大量get()和set()方法的代碼--雖然在其他的面向對象語言中這一點被認為非常丑陋,但是記住PHP不是Java,只要這樣的用法合理,就應該大膽使用。
  4. 從上面的示例代碼中您也許已經注意到了注釋的比重--雖然大家都了解注釋的重要性,但是仍然有必要提出。這個示例中采用了Javadoc的樣式,利用現有工具也可以很容易的直接生成文檔(當然您和您的開發團隊也可以定義自己的合適注釋樣式和文檔生成工具)。對于系統分析員來說,您在設計階段完成之后交付給您的開發伙伴的代碼部分很可能就是這些注釋占絕大部分的框架代碼;你們之間交流的工具除了那些沒完沒了的圖表之外就是這些程序員最熟悉的代碼和注釋了。


在PHP系統中進行類的設計雖然不像構建面向對象系統那樣需要各種合理的模式介入(也沒有這樣的"本錢"為之),但還是需要一番思量的。邏輯上的合理性和操作上的可行性都是檢驗的標準。

(說到類設計,又想到了適合PHP開發的IDE問題。據我所知比較專業一些有Zend出品的Zend IDE;另外還有作為JBuilder的Open Tools出現的借助JBuilder的PHP開發工具;不過最常用的還是PHPEd或者UltraEdit之類的編輯器。如果現有的編輯器可以非常聰明的支持PHP的類設計和代碼實現就非常理想了。)

關于View
最后說到的是View方面,雖然這部分內容與網頁設計人員聯系比較緊密,不過PHP項目(以及其他Web項目)的系統分析員也必須關注這一話題??梢钥闯鯩VC模式的應用使得網頁開發人員和程序設計人員的各自工作成果不會像以前那樣互相影響,自然可以提高各自的工作效率(相互關系也許會比以前更加融洽一些)。但是對于系統分析員來說,將用戶界面分離為各個獨立的網頁模板需要進行許多分析工作。

首先是確定整個系統的流程,這一點在系統設計的初期就應該做到。而對于View視圖/界面和Controller控制/流程來說,所有需要的頁面都是圍繞此流程產生。不過通常此時能夠在流程圖上看到的也許只是相關的參數在各個頁面之間傳遞,卻不能了解各個頁面展示的內容--這就是下一步分析用戶界面需要進行的工作。

在分析用戶界面的工作中,第一步可以確定各個頁面核心、對于完成流程必不可少的用戶界面元素(表單和表單域、鏈接等);第二步是確定頁面中需要出現的導航內容;最后還需要依據流程復核。還是以上文的用戶登錄為例。對于/member/login.php這個關鍵的頁面,第一步可以確定的是在用戶提交之前應該顯示一個表單,表單包含兩個文本框供用戶輸入用戶名稱和密碼;而提交之后根據流程在本頁面中不需要有用戶界面,取而代之的是利用Controller控制/流程這一邏輯層進行重定向。而第二步需要制定該頁面中(準確說是在顯示登錄表單時)需要提供的導航鏈接,在這里可以加上到系統的主頁或者其他非注冊用戶頁的起點的鏈接(方便用戶臨時決定取消登錄)以及一個注銷現有用戶的鏈接(針對已登錄用戶)。之后進行復核,此時也許會發現這一設計似乎沒有考慮到在登錄前更好的區別是管理員登錄還是普通用戶登錄,那么就可以在表單中增加一個隱藏域表示選擇登錄的用戶是準備以管理員還是普通用戶的身份進行登錄。

確定完用戶界面的元素,并不意味著可以將這些分析結果交付網頁設計人員進行制作了;還有最關鍵的一步沒有實施--為分析完成的各個頁面制定模板所需的變量名稱。對于以上的用戶登錄實例,如果系統有識別曾經登錄用戶的功能(依據之前訪問時在客戶端設置的相關cookie值)并且把這個用戶名稱顯示在登錄表單的用戶名稱一欄,此時就需要在member_login.dwt設計中說明該表單域將被賦值為一個模板變量(比如{USERNAME})。這一步驟完成之后就可以交付網頁設計人員進行制作了。

需要指出的是,在編碼階段很可能局部的一些系統設計需要進行修改,這其中也許就包括對網頁模板的修改,需要仔細處理。

對于代碼組織的補充說明
還有幾個文件和目錄沒有在上文提及:

  1. config.inc.php -- 如果您熟悉phpMyAdmin或者其他phpWizard.net釋出的項目,就應該非常清楚這個文件的作用:定義本項目范圍內的全局變量(在每個頁面中被include)。我個人認為這是一個非常良好的設計,因此也提倡在項目中應用。另外,為了保證與項目中其他的變量沖突,建議在該文件中定義一個多重數組,而各種全局變量都以該數組的某一個值出現。這樣方便團隊中的其他開發者只需要避免一個變量名的使用,而不是避免所有config.inc.php中出現的變量名。使用這個文件的另一個好處是由于將關鍵的變量(比如與服務器環境相關的變量)集中定義,可以方便的安裝和移植整個項目。
  2. security.inc.php -- 顧名思義這個文件控制并實施整個系統的安全策略。關于安全問題,可以想到的是兩種控制方案:在每個控制流程頁面頂端針對本頁面加以控制以及采用一個控制文件整個控制并被加入每個控制流程頁面。我個人提倡采用后一種方式,原因也很簡單:定義簡單而且維護方便。雖然相比每個頁面單獨定義,也許會損失一點點效率(一些不需要安全控制的頁面也需要include該文件并進行判別),但是獲得的是對系統安全的整體控制以及代碼維護的便利(損失一個if…else…的判別換取這樣的結果還是很值得的)。
  3. /Temp -- 很明顯存在于這個目錄下的都是一個臨時文件,并且這個目錄其實并不會出現在項目正式發行的版本中。如果開發時對一些函數的使用不甚明了或者試驗一段沒有相關經驗的代碼,都可以在此目錄下建立文件;因為該目錄就位于項目代碼之中,可以非常便利的取得項目運行的上下文環境,大大降低了試驗代碼的成本。
  4. /admin -- 通常對系統的后臺管理內容應該放置在一個獨立的目錄中,我個人比較喜歡admin這個簡寫詞(當然也有一些情況系統分析員認為不應該設置一個容易猜測的管理目錄名稱以增加一重對系統安全的保護)。
  5. /css和/scripts -- 都是與網頁設計也就是View視圖/界面有關的文件存放處,分別是樣式單和客戶端腳本。這樣做的好處在任何一本講述網站規劃的書籍中都會有所提及。


方案二:簡單網站項目
系統性能是這類項目追求的首要目標,而與此同時系統的維護和擴展幾乎可以不用多加考慮。(也許這句話聽起來有些絕對,但是根據客戶的需求和項目的性質判斷,盡最大可能以最短時間滿足客戶的需求并使得系統高效運轉就是項目成功的最好檢驗標準。)因此,也許這類項目就是PHP黑客的天堂(曾經我也是一個過分追求PHP使用效率的人)。由于這類項目的特殊性,這里討論的范圍不僅僅局限與系統設計而是從組建項目小組開始直到交付項目的過程。

首先需要關注的是參與項目的人選(雖然也許這是項目經理的職責,但是最熟悉PHP項目特點的系統分析員應該參與)。在PHP開發人員方面,至少應該選擇對PHP各種函數較為熟悉的開發者(這類項目不適合作為現實項目以培訓參與的開發新人),如果公司中還有能夠在源碼級別理解PHP的人員就更加理想(不過通常對于一般的PHP開發公司是不可能的)。而在網頁設計人員方面,最好可以選擇一些略通客戶端(比如JavaScript)以及服務器端(最好是PHP)腳本的人員;因為這類項目的一大特點即是單個網頁代碼量較大且夾雜網頁代碼(通常是HTML)、客戶端腳本(比如JavaScript)和服務器端腳本(比如PHP),加入了解各種腳本語言的網頁設計人員的目的不是為了增加團隊的PHP開發力量,而是避免在修改網頁時影響程序設計人員的工作。

其次就是面向過程,準確說是面向頁面的系統設計。相對第一類項目,客戶的需求在該類項目中表現得非常清晰,而且一般長期進行Web開發的公司對于這類網站項目也應該有一定的設計經驗積累。設計中需要圍繞整個系統的流程,包括每個頁面的輸入參數和輸出內容(包括網頁中出現的除導航鏈接之外的功能性鏈接),以求完全滿足客戶的需求;另一關鍵在于確定系統安全策略,在這類項目中主要是用戶等級的確定和頁面的訪問權限,并給出實現的方式。不過還需要指出的是,這類項目中由編碼階段返回設計階段的情況并不少見,對于局部設計(比如頁面傳入參數或者輸出鏈接)的更改應該加以及時控制。

最后是針對代碼和數據庫的優化。在這類項目中需要適當鼓勵開發人員的黑客態度。推薦的辦法是系統分析員給出每個頁面的偽代碼(框架代碼),而局部的實現則由各個程序開發人員和網頁設計人員進行。

對于PHP代碼方面,通常可以從如下幾方面考慮:

  1. 算法的選擇和功能實現的方式:模塊級別的優化,可以由幾名開發人員共同討論解決;
  2. 函數的使用:代碼級別的優化,需要開發人員對各類函數有清楚的認識,至少養成多多參考函數手冊的習慣;
  3. 數據庫的查詢和更改即SQL語句的使用:如果公司中有相關數據庫系統的管理人員,可以就一些優化問題征詢他們的建議;
  4. 其他應該避免的問題:比如拷貝代碼、等不良代碼情況。


而根據我的經驗,通常會在這類項目中撰寫的黑客代碼如下:

  1. 循環語句的使用特別是在查找時的應用:此時注意while和for的區別(想必大家在大學課堂中都做過這類的程序),這也是良好的編程習慣;
  2. SQL語句的優化:首先是盡量避免多余的數據庫交互,這是提高效率非常重要的一點;其次是不要害怕長達幾行的語句而寧愿使用所謂簡單的語句;再次是認真考慮查詢語句返回的字段,減少不必要的數據。
  3. 表單提交值的獲取,比如復選框和文本域。精巧的表單域名稱設計可以減少一定的代碼量,而處理提交值時也需要注意處理的方式。


黑客代碼在這類項目中值得鼓勵,不過最好在每段代碼旁附上盡可能詳細的注釋。

由于該類項目的特殊性,完成項目的關鍵不僅僅在于系統設計階段,因此給出項目開始、系統設計、編碼以及測試、交付這一過程的簡單描述:

  1. 挑選合適人員組成項目小組,可以考慮銷售人員和客戶代表的加入。
  2. 系統分析員可以簡單的從客戶的需求以及以往項目經驗的結合中總結出系統所需的每個網頁并對其功能作出描述,同時確定初步的安全策略。這一步驟中可以加入銷售人員和客戶代表的加入。(此時網頁設計人員正在準備提供給客戶的一系列網站形象頁面。)
  3. 詳細設計中需要為每個頁面確定位置和名稱,更加關鍵的是確定輸入參數和輸出內容以及不同級別用戶對于網頁的確切訪問權限。同時進行數據庫設計。該階段完成后至少應該提供系統的流程圖(包括訪問權限標識)以及數據庫設計資料。
  4. 網頁設計人員和程序開發人員拿到相關資料各自進行工作。對于前者,根據客戶認可的一套形象設計每個頁面;對于后者,開始進行"興奮的"(因為此時要求的是高效簡介的代碼--黑客代碼)編碼工作。此階段工作中遇到的困難均需要反饋到系統分析員處,可能返回以上的第3步甚至第2步進行設計修改。
  5. 程序編寫和網頁設計結束后需要有一段整合的時間,也是程序開發人員對代碼進行自我測試的階段。同時在這一階段可以進行的是代碼(包括網頁代碼和程序代碼)和數據庫的優化工作。此階段結束后應該可以提供一個完整的系統。
  6. 真正的測試階段通常都比較倉促,這方面的技術和經驗公司也應該有一定積累(如果有條件希望采用一些軟件工具進行穩定性和抗壓能力的測試)。最后是提供一個可Web訪問的地址供客戶測試。此階段完成后可以提供正式交付客戶的系統。


方案三:綜合性網站項目
已經有一些大型網站使用PHP作為主要的開發語言。對于這類項目,單純從PHP技術方面值得提出的話題不多,簡而言之還是根據網站各部分的實際應用情況(訪問強度、操作行為等)選擇以上提出的兩種項目設計方法或者綜合使用。除此之外,根據我個人的經驗,項目團隊的組織和協調工作以及項目各期完成后的維護工作等等是較之單純的技術更加關鍵的因素。

對于這類項目,可以提出的建議是,適當采納一些開源軟件對于快速、優質的完成項目很有好處。項目的某些部分可以直接引入開源軟件項目的設計甚至是代碼,不過前提是系統設計人員對這些引入的項目需要非常了解,同時需要做好這些孤立的開源項目和整個項目之間的接合(比如安全策略的考慮和全局變量的引用等)。

舉例來說,根據客戶要求某個綜合網站需要以下的功能:

  1. 復雜的新聞發布;
  2. 需要不多管理功能的在線論壇;
  3. 簡單的產品陳列;
  4. 需要用戶管理。


(很明顯這是一個企業網站的雛形。)

其中的1、2項很明顯可以借用一些成熟的開源軟件項目,而3項由于客戶需求簡單自主開發比較符合成本。由此看來4項則是整個系統中最重要的部分--需要做好與1、2項使用的開源軟件項目的用戶管理集成工作(3項由于自主開發的原因集成工作非常簡單)。(某些技術積累較好的公司甚至對于以上提及的集成部分都有簡單的解決方案,那么這樣一個網站項目的完成所需成本非常微小。)

幾個特殊的功能點
另外還有一些通常項目中都會出現但是必須妥善處理的功能點:

1. 數據列表分頁。
關于這個功能,互聯網上的中文和英文資料都有許多。具體的技術和實施細節不需要多說,這里只需要指出的是:

A. 建議封裝成某一個工具類的方法或者其他可復用的形式--這樣的好處不言自明,任何人都不希望系統中只要存在數據列表分頁的時候都會出現一堆幾乎相同的代碼。

B. 如果針對一些效率要求較高的項目(例如上文提到的"簡單網站項目"類型),應該直接使用PHP自帶的針對特定數據庫系統的操作函數以及與該數據庫系統相關的結果集截取技術(SQL語句),比如MySQL中的'LIMIT start, offset'之類;其他一些需要系統設計工整合理的項目(例如上文提到的"設計大量商業邏輯項目"),如果采用了通用的數據庫接口,出于兼容多種數據庫系統的考慮,可以采用此接口完成結果集的篩選,以損失的效率換取系統更好的可維護性和可擴展性。也就是說,對于采用特定數據庫操作函數還是第三方通用數據庫接口來實現數據列表分頁,需要考慮系統的性能和擴展兩方面因素。

2. 錯誤控制。
這一點在上文之中也有提及。除了建立屬于工具類的錯誤類之外,最好可以建立專門的錯誤顯示頁面。該頁面既可以是靜態的HTML頁面(表達一些對用戶的歉意和出錯之后的處理指導)或者動態的PHP頁面(可以包含具體的出錯原因和地點以及其他更詳細的信息,前提是在系統安全策略允許提供這些信息)。而錯誤類的任務就是接受正常的程序中拋出的錯誤,進行必要處理之后將信息一起重定向在錯誤顯示頁面上。

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝

同時,建立出錯頁面對于開發階段也有一定好處,可以彌補現有PHP缺少類似try{…} catch{…} 塊的違例控制的缺點,將調試中的錯誤或者輸出通過錯誤類拋出并顯示出來。

3.上載與下載。
對于PHP來說,上載的實現并不會像其他流行的Web開發語言那樣需要第三方程序的支持,內建的機制可以非常簡單的處理。不過這里提及的是一些復雜的上載功能實現??疾煲韵乱粋€處理附加文件的流程:

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝

該功能使得用戶在撰寫新的消息時可以附加其他文件,而且在消息沒有提交之前可以隨意的對已經附加的文件進行刪除或者繼續增加。這種需求會體現在許多辦公相關的系統中,作為有經驗的系統分析員應該在系統設計階段制定完成針對該類功能的實施計劃。比如在圖中所示的流程中,其實是通過一個或者多個表單的互相提交完成(具體設計不再贅述,提供相關的PHP文件參考;另外的一個直觀的例子就是多數免費郵件系統的添加附件功能,如果有興趣可以考察一下)。

至于下載,將文件置于服務器Web可訪問目錄下、提供訪問者真實文件路徑是最簡單的解決辦法;不過一些系統中對文件的下載基于某些安全策略需要進行身份方面的判別方可予以下載,這樣的方式就會帶來隱患。通常采用的方式也許是將文件放置在Web可訪問目錄以外的服務器文件系統中或者存儲進數據庫系統--都需要一個簡單的程序取得文件內容并直接返回給發出請求的用戶(這其中涉及到一些HTTP輸出頭的問題請注意,提供一個PHP文件代替具體敘述)。在系統設計時針對不同的需求可以采用相應的辦法。

4. 客戶會話session的保持
PHP的現有版本已經內置了對session的支持,通常項目中都使用這樣的方式;一些特殊需要的項目(比如分布系統)也許會采用復雜一些的處理方式。

在客戶端,通常采用的是設置cookie以識別特定的客戶,另一個可以應付不支持cookie的客戶端的方法是采用URL重寫加入足夠標示特定客戶的字符串。從這方面來說,采用PHP內置的session支持最為理想,因為它可以自動的進行客戶端的FALLBACK:如果客戶端支持cookie,那么就順其自然;如果cookie不被支持,就采用URL重寫方式--一切都不需要開發者干預。如果采用其他session處理方式,或者自己編寫適應需要的session庫,需要注意的就是怎樣處理客戶端存儲數據的問題--cookie還是URL重寫還是兩者兼顧。

在服務器端,簡單說來只需要針對以字符串標示的每個特定客戶存儲相關的數據即可--可以采用的方式多種多樣,通常的方式是文件和數據庫。PHP內置的session支持中,默認的支持方式是在系統的臨時目錄或者制定的目錄下為每個客戶建立一個文件存儲其數據;當然也可以修改設置使其支持數據庫的方式或者其他方式。如果自己編寫session庫,根據系統的需要選擇一種合適的存儲方式即可。值得指出的是,對于分布系統,如何共享服務器端的session信息是需要極大關注的。

另外,在設置session變量的時候,PHP內置的session庫支持對象作為變量值(實際上所有的變量值,不論是一般的變量還是數組或是對象,都在經過串行化之后被存儲),也就是說,以下代碼是可用的:

用封裝類來合理的設計PHP項目--談PHP項目中類的封裝



這一點對于上文提到的一些商用系統是有益的:首先,可以使用關于用戶的對象作為一個session變量值存儲一套信息,而不是割裂的多個session變量;其次,如果具有類似購物車的功能,可以以非常符合整個系統設計的方式(即前文所述商用系統的設計方式,強調類封裝)將該購物車對象放入session中。

5. ……其他和特定項目有關的功能點……
如果能在系統設計階段就預見并解決這些功能點固然很好,即使有少量未發現的功能點遺留到了編碼階段也并不可怕--通常這樣的遺漏并不會影響整個系統的架構,只是需要返回設計階段加入相應的內容和文檔即可。畢竟對于相關項目經驗不太豐富的系統分析員來說,做到設計階段對這類功能點了然于胸是不太現實的。

關于其他
對于PHP的爭論從前很多,不過自從Java在Web方面的優勢越來越進入人們的視野之后,這樣的爭論倒偃旗息鼓了--看來大家都達成了共識--PHP對于嚴謹的商用系統還是無能為力。不過基于此就一味否定PHP在商用系統中的應用也不大客觀,畢竟PHP還具有低成本的優勢(這里的成本包括開發成本、使用成本和維護成本)。本文的目的除了講述一些PHP系統設計的方法之外,也希望吸引一些開發者或者企業采用PHP構建合適的商用系統。

另外,本文僅僅是我自己的一些經驗,如果您看到這里時候已經有了自己的一些想法,我非常樂意與您分享--能夠推動如PHP這樣無商業支持的開源軟件的發展,畢竟是一件非常令人興奮的事情。(從這方面來說,我甚至想撰寫關于PHP開發的文檔資料和示范項目,就如同Sun Microsystems為J2EE發布的Blueprint和Java Pet Store--可惜暫時受到時間、精力以及個人能力的限制--也許春節假期是一個好時機:)

參考資料

  • 本文中提及的文章和代碼
    • 代碼:用戶登錄實例(包括控制頁面index.php,login.php;網頁模板member_index.dwt,member_login.dwt;邏輯類Member.inc.php)相關附件;
    • 代碼:類封裝實例(Item類定義Item.inc.php;Item_List類定義Item_List.inc.php)相關附件;
    • 代碼:上載實例(控制頁面add.php,attach.php)相關附件;
    • 代碼:下載實例(控制頁面download.php)相關附件;
    • 代碼:實例代碼組織中的兩個全局文件(config.inc.php,security.inc.php)相關附件;
    • 文章:關于PHP的未來;
    • 文章:模板在PHP中的使用。
  • 其他參考資料
    • PHP官方網站--http://www.php.net
      包含軟件和文檔以及使用情況等(本文成文時的最近動向是PHP 4.1.0釋出,在某些方面有較大改進)。
    • 為PHP提供商業支持的Zend公司--http://www.zend.com
      包含PHP相關的工具和文字資料(可以尋找到一些與本文主題相關的話題)。
    • 著名的開放源碼項目網站SoureForge--http://www.sourceforge.net
      開放源碼項目的聚集地,并提供基于Web的各種便利工具(可以尋找到成千上萬PHP撰寫的項目)。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97热精品视频官网| 日韩在线免费高清视频| 国产精品久久久久久久av大片| 中文字幕精品在线视频| 91精品久久久久久久久久久| 91国产中文字幕| 精品无人区乱码1区2区3区在线| 亚洲国产精品成人精品| 久久69精品久久久久久国产越南| 国产一区二区香蕉| 亚洲激情视频在线播放| 亚洲精品v欧美精品v日韩精品| 亚洲视频在线视频| 91在线视频九色| 热久久免费视频精品| 久久久视频在线| 这里只有精品久久| 日韩av男人的天堂| 亚洲成色777777在线观看影院| 国产精品久久久久一区二区| 深夜福利日韩在线看| 麻豆成人在线看| 国产精品一区二区三区成人| 91久久在线播放| 91在线免费看网站| 一区二区欧美激情| 国产精品av网站| 中文字幕日韩综合av| 亚洲激情第一页| 国产精品久久久久久久久久久新郎| 欧美成人三级视频网站| 成人h片在线播放免费网站| 久久久精品一区二区三区| 中国日韩欧美久久久久久久久| 91久久国产精品| 亚洲欧美另类中文字幕| 狠狠色香婷婷久久亚洲精品| 日韩欧美大尺度| 亚洲aⅴ男人的天堂在线观看| 亚洲美女动态图120秒| 亚洲欧洲在线视频| 日韩女在线观看| 日韩极品精品视频免费观看| 亚洲午夜女主播在线直播| 欧美日韩精品在线观看| 91国偷自产一区二区三区的观看方式| 日韩欧美在线字幕| 国产成人福利夜色影视| 国产精品久久久精品| www.亚洲人.com| 亚洲乱码国产乱码精品精| 日韩精品视频在线观看网址| 久久久久久网址| 久久久黄色av| 欧美综合国产精品久久丁香| 国产一区二区三区在线播放免费观看| 91精品国产乱码久久久久久蜜臀| 91高清在线免费观看| 91av福利视频| 久久久亚洲影院你懂的| 成人天堂噜噜噜| 日本精品久久久久久久| 日韩中文在线视频| 亚洲免费精彩视频| 91干在线观看| 欧美性69xxxx肥| 97欧美精品一区二区三区| 成人动漫网站在线观看| 国产一区二区三区在线视频| 亚洲欧美日韩综合| 51视频国产精品一区二区| 久久精品亚洲热| 毛片精品免费在线观看| 欧美日韩成人精品| 亚洲欧美激情视频| 福利微拍一区二区| 久久免费福利视频| 青青草原成人在线视频| 成人国产精品久久久久久亚洲| 欧美亚洲国产另类| 欧美极品在线播放| 久久av在线播放| 在线播放日韩精品| 欧美丰满少妇xxxxx| 亚洲a区在线视频| 国产91色在线| 久久黄色av网站| 久久久久久一区二区三区| 欧洲精品在线视频| 久久精品国产免费观看| 欧美高清videos高潮hd| 91香蕉电影院| 亚洲成人激情视频| 欧美—级高清免费播放| 国产日韩在线亚洲字幕中文| 青青草国产精品一区二区| 日韩成人av在线播放| 亚洲国产精品悠悠久久琪琪| 狠狠久久五月精品中文字幕| 91av视频在线播放| 国产精品一区二区三区在线播放| 少妇久久久久久| 亚洲午夜女主播在线直播| 欧美天天综合色影久久精品| 久久成人精品电影| 热99在线视频| 国产精品88a∨| 欧美成人精品h版在线观看| 在线视频免费一区二区| 日韩精品在线观看网站| 久久久久久久影视| 欧美成人午夜免费视在线看片| 77777少妇光屁股久久一区| 精品福利在线观看| 欧美视频国产精品| 国产z一区二区三区| 国产精品第1页| 精品无码久久久久久国产| 欧美精品在线观看| 韩剧1988免费观看全集| 亚洲综合第一页| 日本精品在线视频| 久久成年人免费电影| 91精品久久久久久久久不口人| 亚洲精品之草原avav久久| 岛国av午夜精品| 国产精品久久久久久久天堂| 欧美日韩国产一中文字不卡| …久久精品99久久香蕉国产| 亚洲国产精品电影在线观看| 欧美国产高跟鞋裸体秀xxxhd| 国产成人在线播放| 国产精品久久久久久av下载红粉| 亚洲欧美国产精品久久久久久久| 精品福利视频导航| 在线观看国产精品91| 一区二区三区黄色| 日韩欧美中文字幕在线播放| 日韩欧美在线看| 岛国av一区二区| 亚洲欧美一区二区三区在线| 欧美日韩国产色| 国产精品久久久久久久久久| 久久亚洲电影天堂| 一色桃子一区二区| 日本一区二区在线播放| 亚洲free性xxxx护士白浆| 成人精品久久av网站| 国产精品永久免费| 亚洲国产欧美一区二区三区久久| 欧美日韩国产成人在线| 亚洲精品综合久久中文字幕| 欧美成人免费全部| 国产免费一区视频观看免费| 国产精品免费一区豆花| 色综合导航网站| 亚洲精品一区二区网址| 668精品在线视频| 久久久av一区| 欧美激情欧美激情在线五月| 中文日韩电影网站| 欧美在线视频网站| 亚洲无限av看| 成人免费在线视频网站|