由於 PHP 正在成熟,因此是快速即編即用的腳本編制人員與了解 UML 的面向對象的開發人員“思想達成一致”的時候了。
很少有編程語言能夠像 PHP 這樣迅速地得到普及。現在廣泛宣傳的那個關於自己動手做 (DIY) 的腳本編制語言改變 IT 業的故事表明,成功不一定總是來自於系統計劃和市場研究。但是現在的實際問題是這種成功如何能夠為龐大的 IT 業所接受。Oracle 以及其他幾個大的參與者正在關注 PHP 铮铮事實表明,這種語言已經成熟。
直到現在,成功也只是剛剛“出現”。數量不斷增長的愛好者已經聚集在 PHP 周圍,就象聚集在一個天才神童身邊一樣。但是既然這個孩子正在長出胡子,並開始以平等的地位與成人交談,那麼早期的擁護者會適應這種變化嗎?
PHP 與大部分主要的開放源代碼項目一樣,是正在成為主流技術的過程中的一種基本現象。PHP 會使那些使它獲得名譽的人們失望嗎?它會達到龐大的 IT 業的期望嗎?
兩種編程文化的故事
PHP 的成功吸引了不同背景人士的注意。早期的 Rasmus 的擁護者(如果您能諒解那些在開放源代碼圈內不常出現的略以救世者自居的語氣)習慣於快速的即編即用的腳本編制方法,他們現在必須對付那些了解 UML、面向對象 (OO) 編程的開發人員,這些開發人員決心使 PHP 與其他現代開發工具並駕齊驅。雙方都很了解 Web 開發,都擁有強大的文化。忽略任何一方都是不明智的。
早期的 PHP 類型了解 Web 開發的哪些方面,它擅長做什麼,不擅長做什麼?它了解很多關於設計的問題。它的風格有時可能會有問題,但可以看出它擁有 HTML 和 CSS 功能,不必說更為流行的多信息互聯網應用程序 (RIA) 技術了。它總是那麼年輕,卻經常出現在 PHP 論壇中。術語“面向對象”對於它可能具有負面的涵義。它的代碼很扼要,注重表現而不注重可維護性。
由於采用類型松散的變量和為其 HTML 代碼填充 <?php?> 語句,因此 UML 類型將更缺乏吸引力。它將要考慮應用程序體系結構、類級代碼重用、團隊合作以及源代碼管理。它知道,即使復雜度適中的網站首先也是一個應用程序,而設計不良的應用程序會導致工期延誤、惹惱客戶甚至丟掉工作。
乍一看來,後者似乎更適應於需求越來越多的環境,在這種環境中,Web 開發將會越來越多地受到營銷策略和經濟因素的驅動。但是我們是否應該把前者看作瀕臨滅絕的物種?或許不應該這樣。如果我們承認 Web 是與台式機系統差別很大的一種媒介 — 更不要說大型機了(還有人記得 3270 嗎?),在大型 機環境中產生了占統治地位的開發方法 — 則我們可能會得出結論,畢竟可以從這種成功卻相對雜亂的方法中學到很好並且有效的東西。
讓我們來回顧實際的問題,以便在其可能發生之前加以克服,並回顧一些實際的工作方法。
彌補文化差距
現在 PHP5 即將把面向對象技術帶入到 PHP 世界中。Zend 引擎修改 (ZE2) 正在將對象引入到該語言的核心。不僅新的語言構造鼓勵對象編程風格,而且語言的實施也正在適應其他的面向對象環境。例如,不再以缺省方式將對象進行來回的復制,而是通過引用來進行處理。引入了新的關鍵字(如 final 或 static),它們只與對象概念相關,是對 Java 風格的保留;其他特性(如委托)鼓勵使用對象設計模式。(期待在幾個月的時間後能夠聽到大家談論“原有的 PHP4”。) 這種深刻的變化來自於向當前占優勢的編程模型進行無情的革命性轉移。無論您喜不喜歡,對象方法都將會流行,因為它已證明自己在提供復雜應用程序方面最有效,無論它們是不是 Web 應用程序。這使得我們別無選擇,只能尋找富於想象力的方法來協調兩種文化,以便具有設計思想的人與了解體系結構的人能夠取長補短。
為此,必須開發(或從其他平台中變換出)各種方法,以便在將其包含在清晰的界限內的同時獲得語言的多功能性。這樣,編程創造力的“孤島”就可以存在於強健的體系結構中。
一個明顯的事實是,盡管 PHP CMS 或應用程序框架的數量呈爆炸性增長,卻沒有關於它們的一致意見。經常出現的報怨是,無論您的項目是什麼,現有系統都不能完成任務。人們大都開始於對若干系統的評估,而最後經常是從頭開發自己的框架。這是為什麼?
在台式機系統中,似乎已經由操作系統徹底解決了 GUI 設計問題,與此相反,Web 是個原始視覺設計舉足輕重的平台。Web 站點承載商業公司的形像和個性,可能會日益影響其收入。視覺創造力與品牌共同發揮作用,因此必須促進它們的發展。
同時,必須能夠將靈活的邏輯編入到應用程序中,以便盡可能改善用戶體驗,應牢記,用戶在 Web 上要比在台式機系統中可能表現的更“菜”。
當設計人員不斷對程序員所設計的系統感到失望時,這是個問題,而當開發人員不得不將應用代碼強行加入到不完備的門戶框架中時,這同樣是個問題。最常見的結局就是無法令人滿意的折中 — 有些呆板的外觀、為了將應用的復雜性限制在某個可管理級別而犧牲了很多可用性。(這種現象並不只限於 PHP 應用程序。)
為了徹底克服這些限制,設計人員和面向對象開發人員必須找到一種不阻礙對方工作的協作方法。最好的方法可能是從了解對方團隊如何工作開始。
從技巧到產業
此刻先不要考慮協作問題,讓我們觀察各自的實際操作。讓我們按照 PHP 的歷史順序開始,首先訪問一個“增強 html”使用者的商店。
進行交易的工具非常類似於“純 html”使用者的工具:一些 html 編輯器,具有各種級別舒適特性和項目管理特性,並在某種程度上與 PHP、ASP、JavaScript 以及較次要工具相集成。
讓我們花點時間仔細觀察一下代碼。我們首先會注意到,使用這些不同種類的工具生成的網站非常漂亮。我們在這裡不僅指技術,也指天賦。由於擺脫了抽象編程因素的限制,Web 設計人員通過擺弄積極、微妙的情感效果(類似於機敏的裝飾人員在真實商店中所營造的效果)營造了令您網站的客戶感到安適的視覺環境。
當我們從經過訓練的面向對象編程者的角度來看這些代碼時,事情卻突然變得很糟。代碼看上去就象它本身一樣:它是一次性的、用完即忘的工作,沒有為將來的發展或者為簡易的維護作出任何准備。經常這樣,的確如此。
那麼,這有什麼不好嗎?它以後是否會成為一個難題,導致放棄部分或整個網站並從頭開始重建呢?或許不是。畢竟,真實商店的裝修經常定期拆除並重建。因此,就這些櫥窗式的網站而言,牛仔風格的 PHP 編程已經夠用了。這種語言富含各種有助於實現旨在吸引訪問者注意的視覺效果的技巧。這裡顯然與對象方法無關。
一旦需要某些應用邏輯時,這種觀點就發生顯著的變化。您是否需要若干表單來收集有關您網站的常客的少量的營銷信息?如果您希望這種信息能夠很中肯,則最好添加校驗代碼。如果這樣做,您應該確保可以過濾惡意腳本或 SQL 指令侵入式攻擊。順便說一下,既然您正在閱讀 OTN 文章,因此您一定熟悉數據庫 (DB) 問題。您將要收集的這些信息將會存放在某些數據庫表中,而您的 PHP 代碼中的 SELECT 語句將反映這種數據庫結構。從現在開始,這個網站已經固定在您的業務基礎架構中 — 它正在成為成熟的應用程序。
我們暫時不要管其所有的硬編碼鏈接、危險的類型轉換以及安全漏洞,接著訪問最新的 PHP 面向對象應用程序裝配線。對於我們那些具有藝術家風范的 Web 設計人員而言,這種地方可能並不熟悉,甚至可能並不友好。在這裡不太看重技巧。Web 開發已經產業化了。要想為這裡所接受,您必須熟悉類、繼承、數據抽象以及大量的代碼封裝工具。
團隊協作需要規則。必須遵循編程慣例;必須將源文件提交版本管理和源代碼管理。文件根據嚴格的模塊化層次進行組織。摒棄了那些有危險的編碼技巧 — 尤其是那些耍小聰明的技巧。代碼不僅必須易讀,而且必須有良好的注釋。
這樣可能令人厭煩,但卻很有效。現在我們正在創建 Web 應用程序:內聯網、商業 Web 站點、電子市場、各種應用程序,其中具有缺陷的設計都可能會導致停業。簡言之,我們正在克服復雜性。
PHP 面向對象裝配線的管理者並沒有選擇 PHP,因為他們熱愛這種語言。他們之所以這樣做,是因為它不但能像那些專有的其他語言一樣有效地完成工作,而且還是免費的,並且沒有任何附加條件。
我們要走向何處?
那麼我們將如何利用由那些經過 C++ 和 Java 培訓的人們所提供的行業級方法,以完成對早期使用者所使用的多功能語言的專業技術的潛在補充?
PHP5 將會動搖很多習慣,因此這個問題可能為時尚早。有些人將被迫采用一定程度的面向對象方法,而另一些人最終會了解面向對象的所有內容並成為它的信仰者。某些小環境可能會象過去那樣良好運行並繼續興盛發展。
讓我們來實踐一下
現在讓我們深入到基礎的技術級別,了解如何養成簡單的習慣,以及尋找簡單而有效的解決方案將會如何幫助我們准備好應對即將來臨的變化。大量非常簡單的慣例有助於促進編程,並使應用程序准備好進行擴展。
命名慣例(C++ 編程人員的習性)是最容易的方式。如果您已經大量使用了代碼庫(例如 PEAR),則將其慣例作為自己的慣例可能是個好主意;否則應制定您自己的內部規則。簡化的匈牙利批注(根據其匈牙利發明者 Charles Symonyi 而命名)可在松散類型所允許的范圍內廣泛應用。您還可以使用下劃線作為類成員的前綴。另一個有用的習慣是,向那些並不用於從類外部進行調用的方法(屬於一個類的函數)附加一個特殊的前綴(例如 impl_)。
無論您采用什麼命名慣例,都要盡可能使您的代碼明確清楚。這樣,經過訓練的人員就可能在滿屏的 PHP 中發現編程錯誤,只因為它看上去就有問題,就象肖像上的一個污點。
命名慣例的另一個重要方面是避免名稱沖突,使得在大范圍中重用代碼成為可能。經驗告訴我們,程序員在命名編程對象方面並不總是非常富有想像力。很有可能,存在很多的 Page 類,而且也不是沒有可能當您要重用兩個 Page 類時卻發現,它們只是名稱相同而用途卻迥異。真不夠走運的。從長遠看來,重命名將會帶來維護問題。您最好一開始就避免這個問題。生成 GUID 將會矯枉過正、難看(例如 _16B280C5_EE70_11D1_9066_00C04FD9189D_Page!)並且有悖於 PHP 的精神。
一種簡單並可以防止沖突的方法是,通過將類的幾個不同方面關聯到其名稱中(例如 GalleryPage),確保內部類的唯一性;而後,為了消除與您控制范圍之外的類發生沖突的各種可能,您可以按 Java 的方式將您擁有的域名的保留版本作為它的前綴 (com_mydomain_GalleryPage)。
要養成的另一個習慣不需要您花費什麼,並且當某個應用程序范圍的意外變化不可避免時,它可以節省您的工作,這就是將最常用的基本語句封裝在一個單獨的渠道中。例如,除了調試代碼,在整個應用程序中只應該有一個“響應”語句,它應該在某個函數(或單獨的類方法)中。如果某個新環境中需要對輸出進行預處理或重定向,則您知道應該將所需的幾行代碼寫在哪裡,而不必面對那種搜索和編輯大量文件的令人沮喪的情況。
錯誤處理不必像 C++ 中那樣嚴格 — 在 C++ 中,一個懸空指針 (dangling pointer) 或者緩沖區溢出可能極具破壞性。當沒有危及數據完整性時,試著大方地放下架子告訴訪問者,盡管某些功能不太完善,但她可以再試試。一個經常被忽視的好幫手是標准的 set_error_handler() 函數。這是另一個 — 這次是基本事件 — 封裝到一個集中位置(其中所有代碼都專門用於處理這些基本事件)的例子。如果您希望保留所有發生錯誤的事件日志,以便找出重復發生的問題,則應該在這裡完成這項工作。
在我們結束低級編程討論之前,還有另外一個救命招術。在 PHP5 中,缺省情況下,分配或傳遞對象引用(引用是對象的句柄,而不是對象本身或對象的副本)。只要我們還需要使用 PHP4,就必須認真注意對象的傳遞方式。某些微妙之處可能使您心神不寧。例如,以下語句導致 $obj2 成為 $obj1 的副本;這並不奇怪。
$obj2=$obj1;
函數將使用副本並返回副本,除非另有指定 — 我們只得接受這種情況。以下示例導致很多了難以跟蹤的錯誤:
class ObjectKeeper {
var $_obj; // Whatever object is
function & get_object() {
return $this->_obj;
}
}
//引用可以良好地返回。現在陷阱出現了:
$keeper = new ObjectKeeper();
$obj1 = $keeper->get_object();
$obj1->modify();
$obj2 = $keeper->get_object(); // Ask new reference to same object
if ($obj2->is_modified()) {
echo 'OK'; // 這將永遠不會打印
}
正確的語句應該是:
$obj1=&$keeper->get_object(); // 注意,是“=&”而非“=”
如果沒有 =&,則返回的引用所指向的對象的副本被分配給 $obj1,而無論您對您認為正確的引用進行什麼操作,也不會影響原始對象的狀態。換言之,您的更新將會丟失。
在協調 Web 設計人員與程序員的文化方面,模板可能會大有幫助。它們通常包括布局中所配備的一切(主要是 HTML 代碼),而在生成頁面時,模板引擎填入所有可變的內容。大部分模板引擎帶有高速緩存機制,確保相關的耗費資源的處理只發生在數據源更新要求進行這些處理的時候。
接下來的步驟
論壇:Oracle 上的 PHP
PHP 漫游者指南
開放源代碼開發人員中心
Oracle + PHP 疑難解答指南
PHP 腳本編制:隨心所欲的代碼逐漸流行
Oracle + PHP 使用入門
在 Linux 上安裝 Oracle、PHP 和 Apache
模板引擎允許在相當大的程度上將布局和圖形分在一端,將商務邏輯分在另一端。最流行的模板引擎可能是 Smarty,它也恰好被集成在很多開放源代碼的 CMS 和框架項目中。
最後,必須注意當邏輯超出基本的搜索取代式的替換時,模板引擎傾向於提供編程方言。將來的方法很可能依靠 XSLT 技術,而 PHP5 中的擴展 XML 支持將會因此而改變很多。
最後卻是相當重要的一個實踐方面:從眾所周知的庫中重用一流的代碼。我們的研究將只限於 PEAR,因為它現在是標准 PHP 發行版本中的一部分。
PEAR 可能目前更接近於真正標准的 PHP 軟件組件。嚴格選擇提供者以及嚴格的質量標准確保了組件與商業級組件一樣優秀。版本控制慣例為您提供精確控制,以確定組件的哪個版本適合於您的應用程序。PEAR 提供從表單處理到數據庫抽象層 (PEAR::DB) 等一系列豐富的功能,並包括 Web 服務或 WebDAV 支持等高級特性。
不用說,通過熟悉 PEAR 以及類似的 PHP 代碼庫,您可以節省很多天緊張的研發工作。
PHP5 呼之欲出
PHP 已經使自己成為最大的開放源代碼成功的故事之一,與 Linux 和 Apache 齊頭並立。盡管尚有不理想之處,但它已經在 IT 界牢牢站穩了腳跟,並且其龐大的基層用戶群仍然很喜歡它。
PHP5 可能會促進負擔沉重的 Web 應用程序的開發,與數據庫進行交互作用的業務邏輯層越來越多地接受 PHP 代碼。同時,靈活的編程方法將會越來越多地使用 XML 技術,使 Web 設計人員更容易與開發人員和軟件設計人員進行無摩擦的協作。
我們期待看到新一代非常具有吸引力並且非常好用的基於 PHP 的 Web 應用程序。