您的位置:首页 > 运维架构 > Apache

Note on <Zend Framework - A Beginner's Guide> - 01:Apache的URL重寫,ZF項目結構

2012-08-08 16:09 357 查看


第一章所講的內容正是前面的文章中所做的--安裝Zend Framework。所以現在從第二章開始。

Chapter 2: Working with Models, Views, Controllers, and Routes

按照書中建議,在路徑docroot\square\application\下創建modules文件夾,再在其中創建default文件夾。然後將docroot\square\application\下的views,models和controllers文件夾都移動到default裏面去。然後打開\square\application\configs\application.ini,在[production]中添加

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules = ""


在瀏覽器中通過http://localhost/square/public/訪問是成功的:



但是通過http://localhost/square/public/default/Index/index則得到錯誤:



當訪問http://localhost/square/public/時,因為這個路徑下有一個index.php文件(而實際上它是程序的入口),所以Apache可以正常執行這個文件并傳輸結果給我們,可是當請求的URL為http://localhost/square/public/default/Index/index時,這個URL首先將要被分析並且重寫,把public後面的內容都轉換成URL參數,然後將這個請求導向至square/public/index.php文件(分析并重寫的工作我懷疑是由square/application/Bootstrap.php來完成的)。現在的問題就是,重寫的工作不能被完成,結果Apache就真的去尋找路徑square/public/default/Index/index,而這個路徑并不存在。這個錯誤解決良久,所以現在羅列解決過程的細節,來做備案。

解決URL重寫問題:

首先,在這篇文章中找到討論此書此案例的內容:zend framework: Creating the Default Module

它關於原因的解釋如下:

If you see a "File not found" error after implementing the modular directory layout and accessing the
URL http://square.localhost/default/index/index, check that the new virtual host supports .htaccess overrides.
You can enable this by adding the following lines to your virtual host configuration,
remembering to change the directory path to your virtual host's document root.


即是說,要想使用ZF的尋路功能,需要開啟Apache的URL重寫功能,而這個功能在square/public/.htaccess中通過RewriteEngine On設定,但是問題是square/public/路徑目前并沒有此權限來重寫此設定。所以按文中所說,需要設定此虛擬主機的重寫設定,但是問題是,我在我的項目中并沒有打算開虛擬主機這個設定。而且因為我之前使用目錄異名做了另外一個指向C盤下的子域名,所以我不希望讓事情再複雜。所以麻煩來了,我首先嘗試的是將整個web
doc root路徑的設定修改,因為square/在其下。下面是httpd.conf原本的樣子:

DocumentRoot "D:/idsweb/htdocs"

<Directory "D:/idsweb/htdocs">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>


我將它修改為:

DocumentRoot "D:/idsweb/htdocs"

<Directory "D:/idsweb/htdocs">
Options All
AllowOverride All
Order allow,deny
Allow from all
</Directory>


重啟Apache。遇到的錯誤如下:



而且,同時,public變成一個不可見的目錄:



至此,確實是一籌莫展了,看來這本書的FAQ寫得不是很到位…………

不過我突然想到,可以參考下Apache的error.log,看看有些什麽提示:

[Thu Aug 09 11:40:47 2012] [alert] [client 127.0.0.1]
D:/idsweb/htdocs/square/public/.htaccess: Invalid command 'RewriteEngine',
perhaps misspelled or defined by a module not included in the server configuration
[Thu Aug 09 11:41:00 2012] [alert] [client 127.0.0.1]
D:/idsweb/htdocs/square/public/.htaccess: Invalid command 'RewriteEngine',
perhaps misspelled or defined by a module not included in the server configuration, referer: http://localhost/


去到Google搜索下這個問題,得到一個解決辦法,就是去掉httpd.conf中的LoadModule rewrite_module modules/mod_rewrite.so前面的註釋。然後重啟Apache。謝天謝地,這次終於成功了:



在這個過程中我看了下關於<directory>中的Order參數的意義:Order allow,deny

好了,現在回到書本,第一件事是修改默認模塊的默認控制的默認動作的佈局模板,也就是修改文件:/application/modules/default/views/scripts/index/index.phtml,這個沒什麼好說的。

創建一個master layout:

先去到application/下面創建一個layouts文件夾。創建一個master.phtml文件并複製書中內容。按書中設置這個佈局,將下面的代碼加入到application.ini中的[production]中

resources.layout.layoutPath = APPLICATION_PATH "/layouts"
resources.layout.layout = master


在瀏覽器中看看效果,結果就是這個master.phtml的內容被作為輸出的HTML頁面的“外殼”,視圖佈局的模板內容則被其包住。



在master.phtml中,對css和圖片的引用使用的是相對路徑:<img src="/images/logo.gif" />,這個路徑顯然是相對于假設以/public/為根目錄,當然實際上這也確實是index.php的目錄,可是我不明白爲什麽會找不到這兩個文件。修改了head中的base為“/square/public/”也無濟於事,從Chrome的觀察器來看,它始終將其路徑解釋為:http://localhost/css/master.css,所以只能試一下以根目錄為localhost了。



定制路徑:

現在要達到一個目的,就是/home將網站定向到default模塊的index控制器的index動作,這樣做的好處是做一個類似快捷路徑,在域名後面跟一個簡單的/subdomain,就可以導向某個控制器的視圖的佈局。

好,現在看設定,在application.ini中的[production]中加入:

resources.router.routes.home.route = /home
resources.router.routes.home.defaults.module = default
resources.router.routes.home.defaults.controller = index
resources.router.routes.home.defaults.action = index


而且,application.ini中的這個設定是可以在view中通過PHP訪問到的。

傳遞靜態頁面:

那麼首先我們需要一個專門用來搞這個的控制器,姑且稱之為StaticContentController,我們假設靜態頁面的格式為/content/xx,xx是一個參數,它其實是靜態頁面的名稱。這個參數將會被自動轉換成一個URL參數,於是可以在PHP中獲取它。首先要做的是在application.ini中加入:

resources.router.routes.static-content.route = /content/:page
resources.router.routes.static-content.defaults.module = default
resources.router.routes.static-content.defaults.controller = static-content
resources.router.routes.static-content.defaults.action = display


這個設定,令跟在URL後面的參數的名字為page,於是在PHP控制器里,可以通過訪問page來得到頁面名稱。現在來創建這個控制器,首先創建文件/application/modules/default/controllers/StaticContentController.php:

<?php
class StaticContentController extends Zend_Controller_Action
{
public function init()
{
}
// display static views
public function displayAction()
{
$page = $this->getRequest()->getParam('page');
if (

file_exists(
$this->view->getScriptPath(null) . "/" .
$this->getRequest()->getControllerName() . "/$page." . $this->viewSuffix
)
)
{
$this->render($page);
}
else
{
throw new Zend_Controller_Action_Exception('Page not found', 404);
}
}
}


給這個控制器創建兩個視圖:

/application/modules/default/views/scripts/static-content/services.phtml

/application/modules/default/views/scripts/static-content/about-us.phtml

現在,介紹下ZF里這些不同目的的文件夾和文件的命名規則:

控制器(controller)和動作(action)使用的名字都是“camel-casing”,即是每個英文單詞的第一個字母大寫,其餘小寫,比如ControllerNameController。controller的是嚴格的這種規則,而action的名字中第一個單詞的首字母則是小寫,如actionNameAction

另外,default模塊(module)以外模塊的controller必須在名字前加上前綴,前綴的格式是:“moduler名_”。

視圖(view)文件的名稱則是與與之相對的action名相同(不帶後面的Action),如果名字由多個單詞構成,單詞之間加“-”,同時都是小寫;它被保存在的文件夾的名字則與對應的controller的名字相對,不過它在單詞之間加一個“-”或者“.”,同時也要都是小寫。

現在來試試在瀏覽器中訪問:



完全不知道怎麼回事。看來我需要找一個方法來進行debug,如果嘗試在StaticContentController.php中使用echo來輸出變量,是不成功的。

調試Zend Framework程序:

我只好利用PHP輸出文字到一個靜態文本的功能了,在public/下創建一個console.log文件。然後在StaticContentController.php中使用:

利用這個方法在controller中發現$page的值是一個空字符。

Static content not displayed with Zend FW

Invalid controller using custom routes

The Standard Router

ORM VS SQL

ORM

Object-relational mapping
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: