在上一篇 Yii Framework開發(fā)簡(jiǎn)明教程(4) Hangman 猜單詞游戲?qū)嵗匀チ藥讉€(gè)方面的問(wèn)題,一是配置文件 main.php 的 URLManager,二是 Controller 的基類 CComponent ,三是定義 View 使用的 CHtml 幫助類。本篇戰(zhàn)開介紹 URLManager,URL 管理。
return array(
...
'components'=>array(
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'game/guess/<g:\w>'=>'game/guess',
),
),
),
);
Web 應(yīng)用程序完整的 URL 管理包括兩個(gè)方面。首先, 當(dāng)用戶請(qǐng)求約定的 URL,應(yīng)用程序需要解析它變成可以理解的參數(shù)。第二,應(yīng)用程序需求提供一種創(chuàng)造 URL 的方法,以便創(chuàng)建的 URL 應(yīng)用程序可以理解的。對(duì)于 Yii 應(yīng)用程序,這些通過(guò) CUrlManager 輔助完成。
當(dāng)用 path 格式 URL,我們可以指定某些 URL 規(guī)則使我們的網(wǎng)址更用戶友好性。例如,我們可以產(chǎn)生一個(gè)短短的 URL/post/100 ,而不是冗長(zhǎng)/index.php/post/read/id/100。網(wǎng)址創(chuàng)建和解析都是通過(guò) CUrlManager 指定網(wǎng)址規(guī)則。
要指定的 URL 規(guī)則,我們必須設(shè)定 urlManager 應(yīng)用元件的屬性 rules:
array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'pattern1'=>'route1',
'pattern2'=>'route2',
'pattern3'=>'route3',
),
),
),
);
這些規(guī)則以一系列的路線格式對(duì)數(shù)組指定,每對(duì)對(duì)應(yīng)于一個(gè)單一的規(guī)則。路線(route)的格式必須是有效的正則表達(dá)式,沒有分隔符和修飾語(yǔ)。它是用于匹配網(wǎng)址的路徑信息部分。還有 route 應(yīng)指向一個(gè)有效的路線控制器。
規(guī)則可以綁定少量的 GET 參數(shù)。參數(shù)的一般格式如下:
<ParamName:ParamPattern>
ParamName 表示 GET 參數(shù)名字,可選項(xiàng) ParamPattern 表示將用于匹配 GET 參數(shù)值的正則表達(dá)式。當(dāng)生成一個(gè)網(wǎng)址(URL)時(shí),這些參數(shù)令牌將被相應(yīng)的參數(shù)值替換;當(dāng)解析一個(gè)網(wǎng)址時(shí),相應(yīng)的 GET 參數(shù)將通過(guò)解析結(jié)果來(lái)生成。
我們使用一些例子來(lái)解釋網(wǎng)址工作規(guī)則。我們假設(shè)我們的規(guī)則包括如下三個(gè):
array(
'posts'=>'post/list',
'post/<id:\d+>'=>'post/read',
'post/<year:\d{4}>/<title>'=>'post/read',
)
總之,當(dāng)使用 createUrl 生成網(wǎng)址,路線和傳遞給該方法的 GET 參數(shù)被用來(lái)決定哪些網(wǎng)址規(guī)則適用。如果關(guān)聯(lián)規(guī)則中的每個(gè)參數(shù)可以在 GET 參數(shù)找到的,將被傳遞給 createUrl ,如果路線的規(guī)則也匹配路線參數(shù),規(guī)則將用來(lái)生成網(wǎng)址。
如果 GET 參數(shù)傳遞到 createUrl 是以上所要求的一項(xiàng)規(guī)則,其他參數(shù)將出現(xiàn)在查詢字符串。例如,如果我們調(diào)用$this->createUrl('post/read',array('id'=>100,'year'=>2008)) ,我們將獲得/index.php/post/100?year=2008。為了使這些額外參數(shù)出現(xiàn)在路徑信息的一部分,我們應(yīng)該給規(guī)則附加/。 因此,該規(guī)則 post/<id:\d+>/ ,我們可以獲取網(wǎng)址/index.php/post/100/year/2008 。
正如我們提到的,URL 規(guī)則的其他用途是解析請(qǐng)求網(wǎng)址。當(dāng)然,這是 URL 生成的一個(gè)逆過(guò)程。例如, 當(dāng)用戶請(qǐng)求/index.php/post/100 ,上面例子的第二個(gè)規(guī)則將適用來(lái)解析路線 post/read 和 GET 參數(shù) array('id'=>100) (可通過(guò)$_GET獲得) 。
createurl 方法所產(chǎn)生的是一個(gè)相對(duì)地址。為了得到一個(gè)絕對(duì)的 url ,我們可以用前綴 yii">
注:使用的 URL 規(guī)則將降低應(yīng)用的性能。這是因?yàn)楫?dāng)解析請(qǐng)求的 URL ,[ CUrlManager ]嘗試使用每個(gè)規(guī)則來(lái)匹配它,直到某個(gè)規(guī)則可以適用。因此,高流量網(wǎng)站應(yīng)用應(yīng)盡量減少其使用的 URL 規(guī)則。
來(lái)看下 Hangman 中使用的規(guī)則
‘game/guess/<g:\w>’=>’game/guess’,
也就是將所有類似 /game/guess/xx 全部映射到 game/guess 也就是 GameController 的 actionGuess 方法,傳入 GET 參數(shù)以 g=’x’ 的方式。參照每個(gè)字母的鏈接
CHtml::linkButton(chr($i),array('submit'=>array('guess','g'=>chr($i))));
點(diǎn)擊的字母鏈接為 /game/guess/?g=x 或 /game/guess/x 根據(jù) main.php 定義的 urlManager 的匹配規(guī)則 Yii 框架調(diào)用 GameController 的 actionGuess 方法,傳入 GET 參數(shù)。這樣在 actionGuess 就可以通過(guò)$_GET[‘g’]來(lái)訪問(wèn)這個(gè)參數(shù)的值。
// check to see if the letter is guessed correctly
if(isset($_GET['g'][0]) && ($result=$this->guess($_GET['g'][0]))!==null)
$this->render($result ? 'win' : 'lose');
else // the letter is guessed correctly, but not win yet
{
$guessed=$this->getPageState('guessed',array());
$guessed[$_GET['g'][0]]=true;
$this->setPageState('guessed',$guessed,array());
$this->render('guess');
}
使用 urlManager 也允許自定義規(guī)則,或者隱藏 index.php ,具體可以參考 Yii 開發(fā)文檔