Komplett URL-hantering för en webbapplikation involverar två aspekter. För det första, när en användar-request kommer in i form av en URL, behöver applikationen avkoda den till begripliga parametrar. För det andra behöver applikationen erbjuda ett sätt att skapa URL:er på ett sådant vis att de är begripliga för applikationen. En Yii-applikation åstadkommer detta med hjälp av CUrlManager.
Även om URL:er kan hårdkodas i kontrollervyer, är det ofta mer flexibelt att skapa dem dynamiskt:
$url=$this->createUrl($route,$params);
där $this
refererar till kontrollerinstansen; $route
anger
route för önskad request; $params
är en
lista med GET
-parametrar som skall läggas till URL:en.
Som standard är URL:er som skapats med hjälp av
createUrl av det så kallade get
-formatet. Till
exempel, givet $route='post/read'
och $params=array('id'=>100)
, skulle vi
erhålla följande URL:
/index.php?r=post/read&id=100
där parametrarna återfinns i frågesträngen sammanslagna till en lista av
Namn=Värde
-par separerade av och-tecken (&), och där r
-parametern
specificerar request-route. Detta
URL-format är inte speciellt användarvänligt eftersom det erfordrar ett antal
ordfrämmande tecken.
Ovanstående URL kan fås att se renare ut samt mer självförklarande genom
användning av det så kallade path
-formatet, vilket eliminerar frågesträngen
och dessutom placerar GET-parametrarna i den del av URL:en som innehåller path-info:
/index.php/post/read/id/100
För att byta URL:format konfigurerar vi applikationskomponenten urlManager så att createUrl automatiskt kan byta till det nya formatet och så att applikationen korrekt kan begripa de nya URL:erna:
array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
),
),
);
Lägg märke till att vi inte behöver klass för komponenten urlManager, den är fördeklarerad som CUrlManager i CWebApplication.
Tips: URL:en som genereras av metoden createUrl är en relativ sådan. För att få en absolut URL kan vi infoga ett prefix med hjälp av
Yii::app()->hostInfo
, alternativt anropa createAbsoluteUrl.
När path
används dom URL-format kan vi specificera vissa URL-regler för att
göra våra URL:er ännu mer användarvänliga. Vi kan till exempel generera en så
kort URL som /post/100
, i stället för det betydligt längre
/index.php/post/read/id/100
. URL-regler används av CUrlManager både för att
skapa URL:er och för URL-parsning.
För att ange URL-regler behöver vi konfigurera propertyn rules i applikationskomponenten urlManager:
array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'pattern1'=>'route1',
'pattern2'=>'route2',
'pattern3'=>'route3',
),
),
),
);
Reglerna specificeras i form av en array av mönster-routepar, vart och ett motsvarande en enstaka regel. Mönstret i en regel utgörs av en sträng som används till att matcha pathinfo-delen av URL:erna. Routedelen av en regel skall referera till en giltig kontrollerroute.
Info: med start fr o m version 1.0.6, kan en regel anpassas ytterligare med hjälp av dess
urlSuffix
- ochcaseSensitive
-alternativ. Med start från version 1.0.8, kan en regel också hadefaultParams
som representerar en lista med namn-värdepar att sammanfogas med$_GET
. För att anpassa en regel med dessa alternativ, specificera routedelen av regeln i form av en array, i stil med följande:'pattern1'=>array('route1', 'urlSuffix'=>'.xml', 'caseSensitive'=>false)
En regel kan associeras med några GET-parametrar. Dessa GET-parametrar uppträder i regelns mönster som speciella symboler på följande format:
<ParamName:ParamPattern>
där ParamName
specificerar namnet på en GET-parameter och det frivilliga
ParamPattern
specificerar det reguljära uttrycket som skall användas för att
matcha GET-parameterns värde. Om ParamPattern
utelämnas, innebär detta att
parametern skall matcha alla tecken med undantag för snedstreck /
.
När en URL skapas kommer dessa parametersymboler att ersättas med motsvarande
parametervärden; vid parsning av en URL, kommer de motsvarande GET-parametrarna
att erhålla värden från resultatet av parsningen.
Några exempel följer nu för att belysa hur URL-regler fungerar. Regeluppsättningen antas innehålla tre regler:
array(
'posts'=>'post/list',
'post/<id:\d+>'=>'post/read',
'post/<year:\d{4}>/<title>'=>'post/read',
)
Anropet $this->createUrl('post/list')
genererar /index.php/posts
. Den
första regeln appliceras.
Anropet $this->createUrl('post/read',array('id'=>100))
genererar
/index.php/post/100
. Den andra regeln appliceras.
Anropet $this->createUrl('post/read',array('year'=>2008,'title'=>'a sample
post'))
genererar /index.php/post/2008/a%20sample%20post
. Den tredje
regeln appliceras.
Anropet $this->createUrl('post/read')
genererar /index.php/post/read
.
Ingen av reglerna appliceras.
Sammanfattningsvis, när createUrl används för att generera en URL, används route- och GET-parametrarnas som lämnas till funktionen till att avgöra vilken URL-regel som skall appliceras. Om varje parameter associerad med en regel kan hittas bland GET-parametrarna som lämnats till createUrl, och om regelns route också matchar routeparametern, kommer regeln att användas för att generera URL:en.
Om GET-parametrarna som lämnas till createUrl är fler
än de som behövs i en regel, hamnar de överflödiga parametrarna i en query-
sträng. Till exempel, ur anropet $this->createUrl('post/read',array('id'=>100,'year'=>2008))
,
erhålls /index.php/post/100?year=2008
. För att få dessa tillkommande parametrar att
hamna i pathinfo-delen, kompletterar vi regeln med /*
. Med regeln
post/<id:\d+>/*
erhåller vi URL:en /index.php/post/100/year/2008
.
Som nämnts är det andra ändamålet med URL-regler parsning av request-URL:er.
Detta är naturligtvis den omvända processen mot URL-generering. Till exempel,
när en användare skickar en request /index.php/post/100
, kommer den andra
regeln i ovanstående exempel att appliceras, vilket löses upp till en route
post/read
och GET-parametern array('id'=>100)
(kan nås via $_GET
).
Märk: Användning av URL-regler försämrar applikationen prestanda. Detta beror på att vid parsning av request-URL:en, kommer CUrlManager att försöka matcha den mot varje regel tills någon kan appliceras. Ju fler regler, desto större prestandaförlust. Av denna anledning skall en webbapplikation med intensiv trafik minimera sin användning av URL-regler.
Med start fr o m version 1.0.5, kan vi referera till namngivna parametrar i routedelen av en regel. Detta medger att regeln appliceras på multipla route baserat på matchningskriterium. Det kan även hjälpa till att reducera antalet regler i en applikation och därmed förbättra totalprestanda.
Följande exempelregler illustrerar hur route parametriseras med hjälp av namngivna parametrar:
array(
'<_c:(post|comment)>/<id:\d+>/<_a:(create|update|delete)>' => '<_c>/<_a>',
'<_c:(post|comment)>/<id:\d+>' => '<_c>/read',
'<_c:(post|comment)>s' => '<_c>/list',
)
Ovan används två namngivna parametrar i routedeln av reglerna:
_c
och _a
. Den förra matchar ett kontroller-ID till att vara antingen
post
eller comment
, medan den senare matchar ett åtgärds-ID till att vara
create
, update
eller delete
. Parametrarna kan namnges annorlunda så länge
de inte kommer i konflikt med GET-parametrar som kan finnas i URL:er.
Med användning av ovanstående regler kommer URL:en /index.php/post/123/create
att tolkas som routen post/create
med GET-parametern id=123
.
Och givet routen comment/list
och GET-parametern page=2
, kan vi generera
URL:en /index.php/comments?page=2
.
index.php
Det finns en sak till att göra för att ytterligare rensa upp URL:er, att
eliminera startskriptet index.php
från URL:en. Detta kräver att vi
konfigurerar webbservern såväl som applikationskomponenten
urlManager.
Webbservern behöver konfigureras så att URL:en utan startskriptdelen fortfarande
kommer att hanteras av startskriptet. För Apache HTTP-server,
kan detta åstadkommas genom att slå på URL rewriting engine och
specificera några rewriting-regler. Vi t ex kan skapa filen
/wwwroot/blog/.htaccess
med nedanstående innehåll.
Märk att samma innehåll även kan placeras i Apaches konfigurationsfil
inuti elementet Directory
för /wwwroot/blog
.
Options +FollowSymLinks IndexIgnore */* RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php
Därefter konfigurerar vi propertyn showScriptName
i komponenten urlManager till false
.
Med anropet $this->createUrl('post/read',array('id'=>100))
, erhålls nu URL:en
/post/100
. Och nog så viktigt, denna URL kan kännas igen korrekt av
webbapplikationen.
Vi kan även lägga till något suffix till URL:er. Till exempel, kan vi erhålla
/post/100.html
i stället för /post/100
. Detta liknar mer en URL till en
statisk webbsida. För att göra så, konfigurera komponenten
urlManager genom att sätta dess property
urlSuffix till önskad suffixsträng.
Signup or Login in order to comment.