在上一篇Yii Framework 開發簡明教程(4) Hangman 猜單詞游戲實例略去了幾個方面的問題,一是配置文件main.php 的 URLManager,二是Controller的基類CComponent ,三是定義View使用的CHtml幫助類。本篇戰開介紹URLManager,URL管理。
return array( ... 'components'=>array( 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'game/guess/<g:\w>'=>'game/guess', ), ), ), );
Web應用程序完整的URL管理包括兩個方面。首先, 當用戶請求約定的URL,應用程序需要解析 它變成可以理解的參數。第二 ,應用程序需求提供一種創造URL的方法,以便創建的URL應用程序可以理解的。對於Yii應用程序,這些通過CUrlManager輔助完 成。
當用path格式URL,我們可以指定某些URL規則使我們的網址更用戶友好性。例如,我們可以產生一個短短的 URL/post/100 ,而不是冗長/index.php/post/read/id/100。網址創建和解析都是通過CUrlManager指定網址規則。
要指 定的URL規則,我們必須設定urlManager 應用元件的屬性rules:
array( ...... 'components'=>array( ...... 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'pattern1'=>'route1', 'pattern2'=>'route2', 'pattern3'=>'route3', ), ), ), );
這些規則以一系列的路線格式對數組指定,每對對應於一個單一的規則。路線(route)的格式必須是有效的正則表 達式,沒有分隔符和修飾語。它是用於匹配網址的路徑信息部分。還有route應指向一個有效的路線控制器。
規則可以綁 定少量的GET參數。參數的一般格式如下:
<ParamName:ParamPattern>
ParamName表示GET參數名字,可選 項ParamPattern表示將用於匹配GET參數值的正則表達式。當生成一個網址(URL)時,這些參數令牌將被相應的參數值替換;當 解析一個網址時,相應的GET參數將通過解析結果來生成。
我們使用一些例子來解釋網址工作規則。我們假設我們的規則 包括如下三個:
array( 'posts'=>'post/list', 'post/<id:\d+>'=>'post/read', 'post/<year:\d{4}>/<title>'=>'post/read', )
調用$this->createUrl('post/list')生成/index.php/posts。第一個規則適用。 調用$this->createUrl('post/read',array('id'=>100))生成/index.php/post/100。 第二個規則適用。 調用$this->createUrl('post/read',array ('year'=>2008,'title'=>'a sample post'))生成/index.php/post/2008/a%20sample%20post 。第三個規則適用。 調用$this->createUrl('post/read')產生/index.php/post/read。請注意,沒有規則適用。
總之,當使用createUrl生成網址,路線和傳遞給該方法的GET參數被用來決定哪些網址規則適用。如果關聯規則中的每 個參數可以在GET參數找到的,將被傳遞給createUrl ,如果路線的規則也匹配路線參數,規則將用來生成網址。
如果GET參數傳遞到createUrl是以上所要求的一項規則,其他參數將出現在查詢字符串。例如,如果我們調用$this- >createUrl('post/read',array('id'=>100,'year'=>2008)) ,我們將獲 得/index.php/post/100?year=2008。為了使這些額外參數出現在路徑信息的一部分,我們應該給規則附加/*。 因此,該規則 post/<id:\d+>/* ,我們可以獲取網址/index.php/post/100/year/2008 。
正如我們提到的,URL規則的其他用途是解析請求網址。當然,這是URL生成的一個逆過程。例如, 當用戶請 求/index.php/post/100 ,上面例子的第二個規則將適用來解析路線post/read和GET參數array('id'=>100) (可通 過$_GET獲得) 。
createurl方法所產生的是一個相對地址。為了得到一個絕對的url ,我們可以用前綴 yii">
注:使用的URL規則將降低應用的性能。這是因為當解析請求的URL ,[ CUrlManager ]嘗試使用每個規則 來匹配它,直到某個規則可以適用。因此,高流量網站應用應盡量減少其使用的URL規則。
來看下Hangman中使用的規則 ‘game/guess/<g:\w>’=>’game/guess’,
也就是將所有類似 /game/guess/xx 全部映射到game/guess 也就是GameController 的 actionGuess 方法,傳入GET參數以 g=’x’ 的方式。參照每個字母的鏈接
CHtml::linkButton(chr($i),array('submit'=>array ('guess','g'=>chr($i))));
點擊的字母鏈接為 /game/guess/?g=x 或 /game/guess/x 根據main.php 定義的 urlManager的匹配規則Yii框架調用GameController 的 actionGuess 方法,傳入GET參數。這樣在actionGuess 就可以通過 $_GET['g']來訪問這個參數的值。
// 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 也允許自定義規則,或者隱藏 index.php ,具體可以參考Yii開發文檔: http://www.yiiframework.com/doc/guide/1.1/zh_cn/topics.url