一,前言:
ASP,JSP,PHP是WEB開發的三大技術,三種技術優缺點也早就有人分析過了。無非也就是ASP簡單易用且有microsoft做靠山,JSP功能強大是因為有java支援,PHP則開源跨平台。在國內,ASP應用範圍最廣,JSP發展勢頭最猛,PHP則處於劣勢。這可能與公司的支援以及技術的培訓有關。
由於公司項目的需要,我這才接觸PHP,用過一段時間後兩點體會最深刻,一是學習容易,上手極快,內建函數很多,適合快速開發;二是學習資料匱乏,普及不廣,很多時候都要去看英文文檔。
對於中小型WEB應用來說,PHP有很強的競爭力,LINUX+APACHE+MYSQL+PHP(LAMP)的組合幾乎可以勝任絕大多數網站的解決方案,對於大型應用來講,對於系統架構要求更高,需要有成熟的架構支援,JSP的struts是個不錯的架構,國內介紹它的資料也非常多,應用逐漸廣泛起來,對應的PHP也有php.MVC,但是我搜遍了網路也沒有發現一篇中文文檔,這才讓我動了翻譯使用者指南念頭,也算是拋磚引玉,希望PHP能夠在國內蓬勃發展起來。
php.MVC是PHP Web應用程式的一個開源架構,它實現了模型-視圖-控制器(MVC)設計模式??Web應用程式的工業標準,鼓勵基於Model2架構的應用程式設計。這種開發模式允許網頁或其他顯示內容從內部應用程式代碼中分離出來,讓設計者和程式員更容易地集中於他們各自的專業領域。這個架構提供了一個單獨進入點的控制器。這個控制器接受HTTP請求,並根據設定檔分配給相應的動作處理。
模型包含了應用程式的商務邏輯,控制器負責處理請求,並轉向到相應的顯示組件??將HTML和PHP標籤的結合起來的模板檔案。處理結果返回給用戶端瀏覽器,或者通過另外的協議比如SMTP。
php.MVC是用PHP來實現Jakarta Struts架構,目前它支援Struts的許多特性,包括申明應用程式的配置參數通過XML解析器。比如在XML設定檔中指定各種商務邏輯組件與對應的顯示組件之間的映射。
php.MVC的網站地址http://www.phpmvc.net
二,php.MVC系列教程之安裝配置
php.MVC必須安裝在PHP v 4.1.0及以上版本的Web伺服器上
Windows(Apache 2.0.51+php-4.3.9-Win32)
1.從http://www.apache.org下載相應的Apache版本。
2.從http://www.php.net下載相應的PHP版本。
3.從http://www.phpmvc.net下載相應的php.MVC版本。
4.建立目錄c:\www作為Web伺服器目錄,c:\webapp作為Web根目錄,
你也可以定義自己的目錄,以下作相應的修改即可。
5.將Apache安裝到c:\www,開啟瀏覽器,在地址欄輸入http://localhost測試是否安裝成功
注意:如果你的系統上已經安裝有其他Web伺服器(如IIS 5),且佔用了80連接埠,請先停止該伺服器。
6.把PHP壓縮包解壓到c:\www。
7.將c:\www\php-4.3.9-Win32目錄下php.ini-dist拷貝到系統目錄如c:\winnt中並更名為php.ini,
將php4ts.dll拷貝到系統目錄如c:\winnt\system32中,開啟c:\www\Apache Group\Apache2\conf目錄下http.conf檔案,
在ScriptAlias /cgi-bin/ "c:/www/Apache Group/Apache2/cgi-bin/"下加入
ScriptAlias /php/ "c:/www/php-4.3.9-Win32/"
AddType application/x-httpd-php .php
Action application/x-httpd-php "/php/php.exe"
並將DocumentRoot "c:\www\Apache Group\Apache2\htdocs"改為DocumentRoot "c:/webapp"
8.把php.MVC壓縮包解壓到c:\webapp
9.開啟c:\webapp\phpmvc目錄下Main.php檔案,修改如下內容
// Set php.MVC library root directory
$appServerRootDir = 'c:\webapp\phpmvc'; // no trailing slash
// Set the application path
$moduleRootDir = 'c:\webapp\phpmvc'; // no trailing slash
// Set the OS Type [Optional] [UNIX|WINDOWS|MAC] if we have
// trouble detecting the server OS type. Eg: path errors.
$osType = 'WINDOWS';
確認c:\webapp\phpmvc\WEB-INF目錄下phpmvc-config.data有可寫入權限。
開啟瀏覽器,在地址欄輸入http://localhost/phpmvc/Main.php?do=stdLogon測試是否安裝成功。
10.要查閱更為詳細的安裝文檔,請看http://www.phpmvc.net/docs/installIdx.php?doc=all。
三、php.MVC系列教程之架構介紹:
一、介紹
php.MVC是一個開放原始碼的Web應用程式框架,實現了模型-視圖-控制器(MVC)設計模式,鼓勵基於Model2架構的應用程式設計。這種開發模式允許網頁或其他顯示內容從內部應用程式代碼中分離出來,讓網頁設計者和程式員更容易地集中於他們各自的專業領域。
這個架構提供了一個單獨進入點的控制器。這個控制器接受HTTP請求,並根據設定檔分配給相應的動作處理。模型則包含了應用程式的商務邏輯。當請求處理完成,控制器調用相應的顯示組件??通常用模板檔案來實現。處理結果返回給用戶端瀏覽器,或者通過另外的協議比如SMTP。
php.MVC是用PHP來實現Jakarta Struts架構,目前它支援Struts的許多特性,包括通過XML解析器實現XML與對象的映射,從而設定應用程式的配置參數。比如在XML設定檔中指定各種商務邏輯組件與對應的顯示組件之間的映射。
圖1所示的邏輯圖描述了架構的高層結構。
可以看出架構套件括三個主要的組件:前端控制器、主控制器和動作分配器。
二、優/缺點
優點:
1. php.MVC是一個開源項目能讓你完全接觸原始碼,使開發人員能更深入的瞭解其內部實現機制。
2. 使用php.MVC可以促進模組化開發,促使開發人員和設計者的角色分離,提高代碼的重用性和可維護性。
3. php.MVC架構的學習可以借鑒Jakarta Struts的一些知識和經驗,如果你有開發Struts的經驗,那麼就可以快速地用php.MVC來進行開發。
4. MVC模式是Java開發Web應用程式的一個設計標準,使用php.MVC架構還有助於Web開發人員理解MVC設計模式。
缺點:
1. php.MVC功能仍在不段變化和完善中,你需要隨時關注最新版本。
2. 使用php.MVC需要進行額外的學習過程。
3. 應用php.MVC可以得到清晰的程式結構,但也會增加系統複雜度。
4. 應用php.MVC可以讓程式更加有條理,但也會降低程式執行速度。
因此你需要根據項目大小、周期、成本,開發人員素質等眾多條件來決定是否應用php.MVC架構。
四、php.MVC系列教程之處理流程:
php.MVC架構由許多類組裝而成,但是我們不必瞭解所有類的詳細工作過程也可以使用這個架構,圖2顯示了我們使用該架構需要瞭解的一些核心組件。
從圖2我們可以看到一個典型的Web瀏覽器的HTTP請求如何與我們應用程式架構的核心類進行互動,然後如何得到HTTP響應返回到Web瀏覽器。
現在,讓我們以一個執行個體來瞭解架構的處理流程。比如要查看公司銷售報告,先在瀏覽器地址欄輸入
http://www.myhost.com/mycompany/Main.php?do=salesReport 用戶端便發送給php.MVC應用程式一個請求。應用程式架構的控制器處理這個請求,分析查詢字串,取出請求路徑關鍵字。在這個執行個體中,路徑為salesReport。後面我們將看到如何通過XML設定檔來配置必需的應用行為,綁定表單驗證,商務邏輯處理和顯示組件。
如果我們想嚴格控制只有通過驗證的人才能訪問這個報表,則使用者必須先輸入基本的驗證資訊,通常是使用者名稱和密碼。為了限制只有通過了驗證的使用者才能訪問該報表,這裡用了一個被稱作ActionForm的類,我們需要繼承架構的ActionForm來定義自己的表單驗證類,比如SalesActionForm,如下所示:
class SalesActionForm extends ActionForm { ... }.
在SalesActionForm類裡我們要檢查使用者是否可信任的以決定下一步動作。如果使用者沒有通過驗證,我們將重新導向到初始頁面要求重新輸入;如果他通過了驗證,控制器會通過Action類來調用業務處理類。
我們通過繼承架構Action類來進行自訂,比如SalesAction,如下所示:
class SalesAction extends Action { ... }.
在XML設定檔中我們要定義請求與Action類的對應關係,這樣控制器找到相應的Action類,這裡調用SalesAction。在SalesAction類裡我們能訪問業務處理類和資料來源。本例中我們從資料庫中取得銷售資料,製成報表格式。例如:我們建立一些對象,後面在銷售報告模板中可以使用這些對象,如下所示:
// Sales report items - per zone (individual object instances):
$item1 = new Item('Northern Zone Sales' , $salesNorth);
$item2 = new Item('Southern Zone Sales' , $salesSouth);
...
當我們完成了銷售報告,就要通過控制器指定顯示組件顯示出來。這是通過一個在XML設定檔中已經配置好的被稱作Forward的對象的來完成,如下所示:
return $mapping->findForwardConfig('salesReportSuccess');
Forward對象包含了銷售報告模板的路徑,比如salesReport.tpl,這也是在設定檔中定義。
然後控制器將請求轉向到ActionDispatcher,由它定向到指定的顯示組件,在本例中是salesReport.tpl,在模板中通過訪問先前定義對象和變數從而得到在SalesAction裡準備好的資料。
下面顯示我們如何用phpTAL模板系統訪問報表資料並產生顯示視圖,對象$item1我們用類變數$item1->value
...
最後將處理結果通過HTTP發送到用戶端瀏覽器,從而也就完成了整個處理過程。
五、 php.MVC系列教程之目錄檔案
圖3顯示了如何布置一個php.MVC應用程式和其核心類庫
php.MVC類庫
從我們可以看到php.MVC類庫被安裝在伺服器的DEV目錄下,這個目錄用來放置一些通用類庫。為了安全起見,該目錄不允許Web使用者訪問,因此最好不要將該目錄建立在Web根目錄。如果由於某種原因需要將php.MVC類庫安裝在Web 根目錄,那你必須用.htaccess檔案來控制其訪問對象。
下面顯示的是Apache的.htaccess檔案
# options the .htaccess files in directories can override.
# Edit apache/conf/httpd.conf to AllowOverride in .htaccess
# AllowOverride AuthConfig
# Stop the directory list from being shown
Options -Indexes
# Controls who can get stuff from this server.
Order Deny,Allow
Deny from all
Allow from localhost
這將指示Apache伺服器
拒絕所有人訪問包含有該.htaccess的目錄及其子目錄,在本例中是php.MVC類庫的/WEB-INF目錄下包含的檔案及子目錄。
允許從伺服器主機可以訪問,這允許使用Web 服務器的開發人員能夠瀏覽該類庫下的測試目錄以及執行單元測試。
php.MVC檔案不必做任何修改即可正常使用,為了能夠訪問到類庫檔案,我們需要在Web應用程式的Main.php檔案中設定php.MVC類庫根目錄,如下所示:
$appServerRootDir = 'D:/Dev/PHP/phpmvc-base'; // no trailing slash
php.MVC Web應用程式
從圖3我們可以看出一個Web應用程式目錄SalesReport被放置在Web根目錄WWW下。
在SalesReports下的一級目錄下我們可以看到幾個目錄和Main.php檔案,art目錄用來存放應用映像,style目錄用來存放樣式表,這兩個目錄可以通過Web訪問,並且可以根據實際需要重新命名,我們能夠在模板檔案中訪問這些資源,如下所示:
接下來是WEB-INF目錄,該目錄存放應用類和資源。它不能通過Web訪問,這是通過.htaccess檔案來實現的。開發人員可以在該目錄下自由建立目錄及子目錄,但需要在WEB-INF目錄下的ModulePaths.php中聲明。在WEB-INF目錄下,class目錄用來存放應用類和資源檔,tpl目錄用來存放顯示資源,比如網頁模板。
在WEB-INF目錄下還有.htaccess,ModulePaths.php, phpmvc-config.xml, phpmvc-config_1_1.dtd, phpmvc-config.data and prepend.php files。其中.htaccess檔案已經在前面討論過了。
ModulePaths.php檔案用來定義指定應用類及資源的路徑,我們可以象下面一樣定義:
$appDirs = array();
$appDirs[] = ''; // starting with the sub-application home directory
$appDirs[] = 'WEB-INF';
$appDirs[] = 'WEB-INF/classes';
$appDirs[] = 'WEB-INF/tpl';
phpmvc-config.xml檔案是php.MVC應用程式的中心組件,可以通過XML來定義應用程式的行為和屬性,在後面將有更為詳細的介紹。
phpmvc-config_1_1.dtd檔案是phpmvc-config.xml的文件類型定義檔案,DTD檔案指定了在phpmvc-config.xml檔案中可以包含的節點,它是應用程式行為和屬性的最終參照。大部分XML編輯器都可以用DTD檔案來驗證phpmvc-config.xml檔案的有效性。
phpmvc-config.data檔案包含了應用程式的一些配置資料,這些配置資料是根據phpmvc-config.xml檔案的最新資訊動態產生的。假如你的應用程式得不到期望結果時,可以在phpmvc-config.xml中增加空格鍵以修改它,重新運行應用程式時配置資料就會被重建。
prepend.php檔案常用來包含應用檔案,前面,我們已經包含了應用類和模板檔案,我們可以用它來包含其他類和資源檔,如下:
include_once 'Locale.php';
include_once 'PropertyMessageResources.php';
Main.php就是php.MVC應用程式的那個單一進入點,它被放置在應用程式根目錄。所有的請求都需要通過它來完成。
從上面我們可以看出,Main.php檔案中必須定義php.MVC類庫的路徑
$appServerRootDir = 'D:/Dev/PHP/phpmvc-base'; // no trailing slash
接下來我們將指定應用程式路徑
$moduleRootDir = 'C:/WWW/SalesReports'; // no trailing slash
我們也可以設定應用程式的ActionDispatcher路徑。每個php.MVC應用程式通常都要自訂一個
ActionDispatcher來處理指定的請求,我們需要定義ActionDispatcher變數,如下所示:
$actionDispatcher = 'ReportActionDispatcher';
$osType變數用於指定php.MVC所在主機的作業系統類型,通常架構能夠自動檢測出來並以此來設定應用路徑,但是如果你的應用程式運行出現路徑錯誤,請手工設定該變數。如下所示:
$osType = 'UNIX';
正常情況下,包含在Main.php中的其它參數可以不做修改。
六、 php.MVC系列教程之對象關係
在上方是Action類,通常用來處理通過ActionForm類完成了初始化驗證的請求。我們再次看到了繼承Action定義的基類AbstractBaseAction,SalesReportAction類繼承AbstractBaseAction用來處理請求,在SalesReportAction類中我們能調用商務邏輯類ReportBusinessClass,訪問資料庫和其他資源。
在下方是ActionDispatcher類,負責為Action請求準備顯示資源如網頁模板。通常,我們需要繼承架構ActionDispatcher類來定義自己的Dispatcher,比如樣本中的ReportActionDispatcher。
在後面我們將有更為詳細的介紹
XML應用程式配置系統
phpmvc-config.xml檔案是php.MVC應用程式主要的配置組件,每個php.MVC應用程式都有自己的phpmvc-config.xml檔案,通常位於WEB-INF目錄下。一旦這個檔案被修改,Controller就會調用XML解析器解析該檔案,將XML節點轉化為設定物件,這些設定物件緩衝在phpmvc-config.data檔案中,通常它也是放在與phpmvc-config.xml相同的目錄。在後面的請求中,Controller將會調入緩衝的phpmvc-config.data檔案,儲存處理時間。
在圖5我們看到了設定檔與應用程式組件是如何聯絡起來的,我們為action節點定義了一個path屬性為salesReport,這個標識就是Action的訪問路徑如:http://www.myhost.com/mycompany/Main.php?do=salesReport.
在action節點中name屬性為salesReportForm,這就告訴Controller我們要用一個名為salesReportForm的form-bean來處理表單驗證,我們能看到名為salesReportForm的form-bean在action-mappings節點上面的form-bean內定義了,其中validate屬性為true表示控制器會調用form-bean的validate(...)方法。
在action節點和與其聯絡的form-bean節點中,都有type屬性。我們用這個屬性定義form-bean和action各自對應的類。比如action節點就定義了Action類為SalesReportAction,form-bean節點的ActionForm類為SalesReportForm。
接下來我們還需要在action節點中定義forward節點群組來指定架構顯示組件的URI,其中name屬性為forward節點定義一個標識,path屬性定義了與這個action相關聯的資源或模板。樣本中第一個forward節點定義為salesReportSuccess,資源路徑為salesReport.tpl,第二個定義為salesReportFailure,資源路徑為salesReportIndex.tpl,在我們的類裡我們能用這些forward節點指定顯示資源的位置。在這個執行個體中,假如報表成功產生,我們用salesReportSuccess對象和它所定義的salesReport.tpl來處理請求,如果報表產生失敗,我們用salesReportFailure對象和salesReportIndex.tpl來處理,一般是返回到初始頁。
phpmvc-config.xml檔案可以用一般的文字編輯器就可以修改,或者用專用XML編輯器。專用XML編輯器可以使用phpmvc-config_1_1.dtd來驗證該設定檔的有效性,DTD檔案定義在XML檔案可是使用的元素,屬性以及數值。關於這方面的知識可以查閱XML的相關資料。
下面是樣本phpmvc-config.xml檔案:
Sales report->value will appear here | ...
現在讓我們來分析一個典型的php.MVC Web應用程式的結構。
圖4顯示了從開發人員的角度來看php.MVC樣本程式中主要類和資源,以及它們之間的關係。
在左上方是ActionForm類,我們通過繼承它來處理HTML表單驗證和與之相關的功能。樣本中通過繼承ActionForm定義了一個基類AbstractBaseForm,它包含一些通用的邏輯,可以為更多的應用程式ActionForm類所引用,比如SalesReportForm類就具體實現了AbstractBaseForm類。
七、 php.MVC系統教程之設定檔
前面我們講解了php.MVC的結構以及流程,接下來,我們將重點介紹以下的核心組件:
XML設定檔是php.MVC應用程式的“配電盤”,為HTTP請求綁定組件。 Controller由一些架構類組成,負責為HTTP請求找到正確的Form和Action類以及顯示資源,在 phpmvc-config.xml檔案中定義。 ActionForm類通常用來處理Web表單驗證。 Action類可以訪問業務處理類,能讓我們把精力放在應用程式業務流上。 ActionDispatcher類操縱顯示資源的處理。
XML Configurations and Bindings: phpmvc-config.xml
|
八、 php.MVC系列教程之控制器
控制器(Controller)由一些類組成,根據預先定義的配置選項處理使用者請求。一個典型的使用者請求如下:
http://www.myhost.com/mycompany/Main.php?do=salesReport.
php.MVC 控制器由兩部分組成:前端控制器和控制器。當請求到來時,前端控制器負責安裝應用程式,控制器則根據phpmvc-config.xml的配置屬性處理請求。
使用者請求被Main.php檔案接收,這裡,將設定一些初始化參數。前端控制器將執行以下任務:
定義應用程式路徑:這將指定php.MVC類庫以及Web應用程式的路徑,如下:
$appServerRootDir = 'C:/WWW/phpmvc-base';
$moduleRootDir = 'C:/WWW/mycompany'; 定義應用程式的ActionDispatcher:我們通常需要擴充架構ActionDispatcher來定義自己的Dispatcher類:
$actionDispatcher = 'MyActionDispatcher'; 初始化應用程式類路徑:為了將類和資源裝入,前端控制器將匯入預先定義的全域路徑以及應用程式路徑。我們可以在/WEB-INF/ModulePaths.php中設定路徑,如下:
$appDirs = array();
...
$appDirs = 'WEB-INF/report_tpl';
$appDirs = 'WEB-INF/report_classes'; 包含應用程式類:前端控制器將匯入它所需要的類檔案,我們也可以用/WEB-INF/prepend.php檔案來有選擇性地匯入一些特殊的應用程式類檔案。如下:
include_once './WEB-INF/mytools/MyTools.php'; 配置應用程式:前端控制器將為應用程式設定配置資訊,比如我們先前定義的ActionDispatcher。 初始化控制器:前端控制器現在將建立一個應用伺服器執行個體(ActionServer)。 匯入配置資訊:前端控制器現在將匯入應用程式配置資訊,假如phpmvc-config.xml從最後一次請求後被修改了,phpmvc-config.xml檔案將被重新處理並將資料緩衝到/WEB-INF/phpmvc-config.data中。 初始化HTTP請求:前端控制器現在將設定HTTP請求並添加請求屬性。 調用應用程式控制器:前端控制器現在已經完成了準備工作,將會把處理權交給控制器。
控制器接收從前端控制器傳來的請求,根據配置屬性執行一系列操作。
處理action路徑:控制器將根據請求路徑識別出關鍵字,選擇一個action映射。比如請求路徑為:
http://www.myhost.com/mycompany/Main.php?do=salesReport, action路徑就為salesReport。
處理現場:根據需要為目前使用者選擇一個Locale 處理內容格式:根據需要設定內容格式,預設為text/html。 處理不緩衝:根據需要設定不緩衝頭資訊,預設為:
"Pragma", "No-cache"
"Cache-Control", "no-cache"
"Expires", 1 處理預先處理任務:可以在自訂的ActionServer子類中覆蓋這個方法,執行一些指定的預先處理任務。 處理Action映射:控制器將根據請求識別action映射,根據phpmvc-config.xml的相應節點產生action映射對象(ActionConfig),比如:。 處理角色:檢查能執行這個action的所有必須的認證。 處理ActionForm:控制器將根據action映射找到相關聯的ActionForm,form-bean就是由action的name屬性指定,比如:
。 處理Populate:根據請求參數設定ActionForm執行個體的屬性。 驗證ActionForm:根據action的validate屬性值如:,決定是否調用ActionForm的validate()方法。如果validate()返回False(驗證失敗),控制器將用action中input屬性所指定的顯示資源(模板)顯示錯誤,比如:
...
validate = "true"
input = reportsIndex.tpl>
假如validate()返回True(驗證通過),則將繼續處理。處理Forward:控制器檢查forward映射的URI是否正常,如果是,繼續處理。 處理Include:控制器檢查include映射的URI是否正常,如果是,繼續處理。 處理Action建立:控制器將建立或擷取Action執行個體來處理這個請求,這是用action的type屬性來定義的,比如:
type = "SalesReportAction"
... 處理Action執行:控制器現在將調用Action類的execute()方法,比如SalesReportAction->execute(...)。在該方法內,我們將調用業務處理邏輯類。 處理Action鏈:控制器將檢查是否還有另外一個Action需要處理,在應用程式設定檔中,我們通過ActionChain能定義一系列Action,為了定義ActionChain,需要為action節點的forward元素添加一個nextActionPath屬性,比如:
type = "SalesReportAction"
...
name = "salesReportSuccess"
path = "salesReport.tpl"
nextActionPath = "salesReport2"/>
... forward元素的path屬性是必須項,假如這個特殊的Action沒有輸出,我們可以設定path = ""。 處理Action Forward:控制器將轉寄或重新導向到指定的資源,一個forward請求在當前處理器中被處理。RequestProcessor只是把控制權交給ActionDispatcher,那裡包含了指定的URI模板。比如:
name="forward_path
path="forwardRequest"
redirect="false"/> 重新導向請求實際是發送給用戶端瀏覽器一個標題響應,然後重新導向到一個新的URL。在發送重新導向標題資訊時當前的處理將立即終止。
name="redirect_path
path="/MyApp/Main.php?do=newRequest"
redirect="true"/>
name="redirect_path
path="http://www.myhost.com/MyApp/Main.php?do=newRequest"
redirect="true"/>
假如沒有其他的Action需要處理,控制器處理結束。