網站製作學習誌

記錄學習製作網站的一切

Portable ZF 專案會遇到的問題

在「建立 Portable 的 ZF 專案」一文中,已經讓我們可以將 Zend Framework 專案佈署到其他機器上而不需要修改 Apache 的 Virtual Host 設定檔;但是這樣卻會造成某些問題,以下我們來一一分析及解決。

防止不必要的目錄被直接瀏覽

假設在佈署 Portable 專案的 Apache 伺服器上,其 httpd.conf 中有以下設定:

1
2
3
4
<Directory "/path/to/document_root">
    Options Indexes 
    # 略...
</Directory>

其中 /path/to/document_root 是我們的網站實體根目錄,而一般 Portable 專案就是放在網站實體根目錄下去執行。

Options Indexes 這個指令就是啟用 Apache 能直接瀏覽目錄,所以知道我們程式結構的人其實能直接看到我們的專案目錄結構!

為什麼會這樣呢?首先我們要分析一下原來的 .htaccess 做了什麼事情:

1
2
3
4
5
6
7
8
9
10
11
12
# 啟用 RewriteEngine
RewriteEngine On
# 檢查 ${REQUEST_FILENAME} 中,大小不為 0 的檔案是否存在,或是
RewriteCond %{REQUEST_FILENAME} -s [OR]
# 檢查 ${REQUEST_FILENAME} 中,指定的符號連結是否存在,或是
RewriteCond %{REQUEST_FILENAME} -l [OR]
# 檢查 ${REQUEST_FILENAME} 中,指定的目錄是否存在
RewriteCond %{REQUEST_FILENAME} -d
# 上面規則有找到資源的話就直接導過去
RewriteRule ^.*$ - [NC,L]
# 沒有符合的連結就全部導向 index.php
RewriteRule ^.*$ index.php [NC,L]

這個 .htaccess 原本是放置在 public 目錄下的;也就是說,在 Zend Framework 原先的設計裡, public 資料夾除了置放原來的 index.php 入口外,還可以用來放置 css 、 javascript 或 image 等資料夾;這些公開資源只要在適當的情況下,都是可以直接被存取的;而其他的在 public 外部的資料夾因為不在 Virtual Host 的公開範圍內,所以就不會被存取到了。

一旦我們將原來的 .htaccess 搬到專案根目錄後,就會使得 application 、 library 、 tests 等資料夾都有被直接瀏覽的危險。

怎麼辦呢?兩個方式可以解決這個問題。第一種方式是把可以直接瀏覽目錄的選項關閉,做法就是在根目錄下的 .htaccess 上方再補上一行:

1
Options -Indexes

這樣就可以了。

第二種方式是將專案根目錄下的 .htaccess 中檢查目錄是否存在的 RewriteCond 拿掉,也就是把:

1
2
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d

改成:

1
RewriteCond %{REQUEST_FILENAME} -l

這麼一來 application 等目錄就不會被 Rewrite Engine 所辨識出來了。

不在網址上加入 public 路徑

改用 Portable 架構後還會遇到一個問題:就是原來在 View Script 中存取 css 或 javascript 時,在路徑上要多加入一個 public ,例如:

1
2
3
$this->baseUrl('/css/style.css')
// 要改為
$this->baseUrl('/public/css/style.css')

解決的方法有兩種:

第一種方式是將放在 public 底下的 css 及 js 等資料夾移到專案根目錄下,然後把原來 public 目錄下的 .htaccess 各複製一份給 css 及 js 資料夾,最後再刪掉 public 目錄。但這樣太麻煩了,而且到最後整個專案根目錄下的目錄結構都會很亂。

因此建議使用第二種方式,透過 RewriteRule 來改寫,也就是在專案根目錄下 .htaccess 的 RewriteEngine On 下一行加入:

1
2
# 遇到 css/xxxx 就導向對應的 public/css/xxxx , js 及 img 以此類推。
RewriteRule ^(css|js|img)/(.*)$ public/$1/$2 [L]

這個解法的問題在於如果 public 底下有新增目錄的話 (例如 download ) ,就得再修改專案根目錄下的 .htaccess ,但已經比第一個方法好維護多了。

如此一來改為 Portable 架構後的 ZF 專案就與原來 ZF 預設架構執行的結果相差無幾了。

Comments