2008年02月29日
[PHP-ZF] 目錄結構的安排
Zend Framework 目錄結構的安排 (Directory Layout) 也是一個很讓初學者困擾的問題,而且不論是官方或是社群都推薦了很多方法,更讓剛接觸 Zend Framework 的朋友難以適從。
本文將探討 Zend Framework 目錄結構的特點以及幾個常見的目錄結構,讓各位開發者能夠對它們有所認知。
為什麼要有目錄結構
目錄結構主要目的如下:
-
將程式及相關文件分門別類,以便於管理。
-
便於設定相關存取權限。
-
讓開發者很快能找到要修改的檔案。
因此選定一個好的目錄結構,將會為你的專案開發帶來高效率且易維護等好處。
專案目錄要放在哪裡
有些目錄結構需要有修改 Apache httpd.conf 的權限,有些則不需要;也因此專案目錄的存放位置也變得很重要,因為這會牽扯到安全性的問題。
一般來說,需要修改 httpd.conf 權限的目錄結構類型,我們可以放在檔案系統的任何地方,並確定它能讓 Apache 正確存取與執行。而不需要修改 httpd.conf 的類型,通常是為了因應專案的可攜性或是開發者缺少系統管理權;這時專案目錄就要放在 Apache 預設提供可以存取的位置,例如 /home/username/htdocs 。
常見的目錄結構
以下我們來看看幾個常見的目錄結構。
類型一:官方手冊的版本
官方手冊的「 7.1. Zend_Controller Quick Start 」一節裡提供了一個參考用的 Directory Layout ,我稍微做了一些修改,如下:
application/
controllers/
IndexController.php
ErrorController.php
models/
views/
scripts/
index/
index.phtml
error/
error.phtml
helpers/
filters/
library/
Zend/
(other libraries)/
html/
scripts/
images/
styles/
.htaccess (導向 index.php)
index.php
說明
這是一個需要修改 httpd.conf 的目錄結構,也僅適用於單一功能的應用程式 (也就是單一模組) 。在安裝時我們必須修改 httpd.conf ,將專案的 Document Root 指向 html 這個目錄。 html 目錄除了做為 Document Root 外,其目地就是存放可公開的檔案,像是圖片、 JavaScript 或樣式表等等。而 application 目錄即為預設的模組,存放著 MVC 等三種類型的檔案 (即 controllers 、 models 及 views 等三個目錄) 。至於 library 目錄就比較隨意,我們只要確定它的執行權限,並且讓 PHP 能夠找到裡面所需要的類別即可。
在預設模組中, controllers 目錄裡的 IndexController.php 與 ErrorController.php 都是一定要的,另外 views/scripts/index/index.phtml 和 views/scripts/error/error.phtml 也是如此;而原因可以參考 Front Controller 的基本應用技一文,這裡不再詳述。
這裡要特別說明 application/views 這個目錄,其中還區分成 scripts 、 helpers 及 filters 三個目錄。 scripts 主要放的就是 templates ,底下可以用小寫的 controller name 做為資料夾名稱以做為區別;而 helpers 和 filters 其實在實際應用上比較少用,所以通常我會把它們從結構中拿掉。
註:為了節省篇幅,在呈現目錄結構時,預設模組的相關必要檔案我會略掉,但實際應用時請記得加回去。
另外 .htaccess (導向 index.php) 的實際內容如下:
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
php_flag magic_quotes_gpc off
php_flag register_globals off
在 .htaccess 的第一行中,由於 Zend Framework 支援自訂網址的功能,所以我們啟用了 RewriteEngine ,也就是設定為 on 。接著第二行我們加入一個 RewriteRule ,讓 index.php 處理所有非公開資源的 request 。
註:不過 Zend Framework 也支援沒有 mod_rewrite 的環境,我們只要在 Front Controller 中將 baseUrl 設定好就沒問題了,這點有機會再探討。
剩下兩行是 PHP 的設定,這邊就不再加以說明。
這種目錄結構最大的特色是將 index.php 放在 html 目錄下, 這樣的好處在於能提高對 application 目錄的安全掌控度,因為 application 目錄並不會直接曝露給外部的瀏覽者。但是這樣的結構也有一個很大的缺點,那就是可攜性很差!換句話說如果在測試環境所使用的網址是 http://localhost/myproject/ ,而正式上線的環境卻是 http://www.myproject.com/ ,那麼就要修改 httpd.conf 讓 html 目錄對應到正確的網址,這樣才有辦法讓程式正確執行。
類型二: Rob Allen 的版本
在 Rob 的 Getting Started with the Zend Framework 一文中,他採用了和官方不同的目錄結構:
application/
.htaccess (deny from all)
controllers/
models/
views/
filters/
helpers/
scripts/
library/
Zend/
(other libraries)/
.htaccess (deny from all)
public/
.htaccess (RewriteEngine off)
images/
scripts/
styles/
.htaccess (導向 index.php)
index.php
說明
這種目錄結構也是屬於單一功能 (模組) 的類型,它的特色是不必在 httpd.conf 中指定 Document Root 。這種目錄結構將 application 、 library 、 public (即第一種版本的 html) 以及 index.php 放在同一層的專案根目錄下,再利用 .htaccess 去控制每個目錄結構的存取權。
.htaccess (導向 index.php) 內容和官方版相同,請參考上面的說明。比較特別的是 application/.htacess 的內容為 deny from all ,這是要避免用戶直接從網址瀏覽 application 內的檔案;而 public/.htaccess 的內容則是 RewriteEngine off ,亦即關閉原本 .htaccess (導向 index.php) 對此目錄的影響,讓用戶可以直接瀏覽 public 內的檔案 (就是圖片、 JavaScript 及樣式表等等) 。
index.php 則是從 public 目錄中往外移至專案根目錄,這樣就可以讓用戶直接存取 (因為一般我們會在 Apache 設定 index.php 為預設執行頁) 。
這種目錄結構剛好和官方版本相反,它非常俱有可攜性,也是一般開發 Zend Framework 專案常用的目錄結構型態。不過它也有很大的缺點,那就是當 mod_rewrite 被關閉或是 .htaccess 不被解析時,這種目錄會將 application 及 library 兩個目錄曝露出來,在安全性上就大打折扣;不過通常這樣的 httpd.conf 設定比較少見,也因此一般開發 Zend Framework 專案時,大多都會採用這種目錄結構。
類型三: Gavin Vess 的 Conventional Modular 版本
前面兩種版本都是單一功能 (模組) ,不過如果專案需要前後台或多種功能時,通常就會使用模組機制。Zend Framework 支援了模組機制,因此在目錄結構上也需要做一些改變。
有一篇 Gavin Vess 所寫的 Choosing Your Application's Directory Layout 也討論到了有關 Zend Framework 在模組上的目錄結構安排。文章中有個 Conventional Modular 版本,我也做稍做了修改,如下:
application/
config/ (非必要)
default/
config/ (非必要)
controllers/
models/
views/
(module 1)/
controllers/
models/
views/
(module 2)/
controllers/
models/
views/
htdocs/
images/
scripts/
styles/
.htaccess (導向 index.php)
index.php
library/
Zend/
(other libraries)/
tmp/
sessions/
cache/
view_compiles/
說明
很明顯地,這個版本是從官方版本演化而來的;它的主要特色是將原來 application 中的 MVC 三個目錄拿掉了,取而代之的是 default 、 module1 、 module2 等 MVC 模組。
前面兩個版本都是以 application 為預設模組,因此我們不必在程式裡特別設定。但是在多模組的狀況下,我們需要指定 application 下的某個模組為預設模組;這部份的程式碼可以參考我在 「Front Controller 的基本應用技」一文中所提到的「進階的 Front Controller 用法」。
其他的目錄也都能望名生義,這裡不再解說。
類型四:我的版本
最後介紹我自己所採用的版本。基本上它可以算是模組化的 Rob 版本,只是我為了專案開發需求,又再加入一些特別的目錄結構。
app/
.htaccess (deny from all)
base/
cron/
etc/
lib/
tmp/
mod/
default/
caches/
controllers/
models/
views/
(module 1)/
caches/
controllers/
models/
views/
(module 2)/
caches/
controllers/
models/
views/
pub/
.htaccess (RewriteEngine off)
img/
js/
css/
.htaccess (導向 index.php)
index.php
說明
首先我將 application 及 public 的名稱分別縮短為 app 及 pub ,其它目錄名稱也改為較短的名稱。而所有的 .htaccess 則和 Rob 版的相同,因此也會有同樣的限制。
另外我把放置 Zend Framwork 及其他 library 所在的 lib 目錄移入 app 目錄中以方便管理, Gavin Vess 的 config 我也改成了 etc ,這點算是仿照 Gavin Vess 的 Classical (Unix/Linux-like) 版本。
其他幾個特點如下:
-
加入了 base 目錄,這是用來存放專案共用程式的地方。
-
加入了 cron 目錄,這是用來存放排程程式的地方。
-
加入了 tmp 目錄,視需要使用。
-
每個模組裡加入了 caches 資料夾,用來存放各模組所產生的快取資料。
註:以上的特色是在累積了多個 Zend Framework 專案經驗後所得出的結論,但或許各位所開發的專案屬性會和我的不同,因此這些特色僅供參考。
結論
Zend Framework 目錄結構的安排其實有很大的學問,在規劃得當的情況下,它能為我們帶來事半功倍的開發效率。本文簡單地為大家分析了幾種常見的目錄結構,也說明了它們的一些優缺點。各位朋友不妨多參考其他版本的目錄結構,並在瞭解專案的屬性後,選擇一個適合專案的目錄結構。
希望這篇文章能為各位在學習 Zend Framework 時帶來一些幫助,同時也希望對 Framework 有深入研究的朋友也能不吝指正我的謬誤。
前輩您好對於目錄結構中的 models 用途不是很瞭解
雖然有文章在說是用來放置與資料庫連結的模組
或放置一些常用的函數
還可以有其他用途嗎?
之前是採用載入子樣版去做模組開發
但每個子樣版都會有程式處理的部分
因此在程式與樣版上都要分別載入
在開發上不是很直覺
如果要將樣版與程式結合的模組
在架構上要怎麼實行會比較好?
期待前輩給於指點

今天第一次接觸zend framework;
有個基礎的問題想請問一下,
我在網站的根目錄底下有置放
index.php 及 .htaccess 兩隻檔案
.htaccess內容為:
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
php_flag magic_quotes_gpc off
php_flag register_globals off
只要我有置放.htaccess讀取網站時就會出現:
Internal Server Error
但我移除,則可正常執行網站,
請問一下我是不是要在php.ini裡把網站的路徑改掉
才不會出現這樣找不到網頁的錯誤
我的環境為
windows+apache+php+mysql
請給我一道曙光...
麻煩你嚕!謝謝。

不好意思...我不是來亂的!
很巧我剛在爬zend framework有找到答案了
php.ini中extension=php_pdo.dll需開啟
httped.conf中的LoadModule rewrite_module modules/mod_rewrite.so需開啟
可能是我第一次用framework所以這兩樣我沒啟用
我啟用之後根目錄下有.htaccess也可成功執行..
不好意思!
