Using regular expressions in URL rules
One of the hidden features of the Yii URL router is that you can use regular expressions that are pretty powerful when it comes to strings handling.
Getting ready
- Create a fresh Yii application using
yiic webapp
as described in the official guide and find yourprotected/config/main.php
file. It should contain the following:// application components 'components'=>array( … // uncomment the following to enable URLs in path-format /* 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( '<controller:\w+>/<id:\d+>'=>'<controller>/view', '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>', '<controller:\w+>/<action:\w+>'=>'<controller>/<action>', ), ),
- Delete everything from
rules
as we are going to start from scratch. - In your
protected/controllers
directory, createPostController.php
with the following code inside it:class PostController extends CController { public function actionView($alias) { echo "Showing post with alias $alias."; } public function actionIndex($order = 'DESC') { echo "Showing posts ordered $order."; } public function actionHello($name) { echo "Hello, $name!"; } }
This is our application controller that we are going to access using our custom URLs.
- Configure your application server to use clean URLs. If you are using Apache with
mod_rewrite
andAllowOverride
turned on, then you should add the following lines to the.htaccess
file under yourwebroot
folder: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
How to do it...
We want our PostController
action to accept parameters according to some specified rules and give the 404 not found HTTP response for all parameters that do not match. In addition, post/index
should have an alias URL, archive
.
Let's use regular expressions in the configuration file to achieve this:
'post/<alias:[-a-z]+>' => 'post/view', '(posts|archive)' => 'post/index', '(posts|archive)/<order:(DESC|ASC)>' => 'post/index', 'sayhello/<name>' => 'post/hello',
The following URLs will be successful:
http://example.com/post/test-post
http://example.com/posts
http://example.com/archive
http://example.com/posts/ASC
http://example.com/sayhello/Александр
The following URLs will fail:
http://example.com/archive/test
http://example.com/post/another_post
The following screenshot shows that the URL http://example.com/post/test-post
has run successfully:
The following screenshot shows that the URL http://example.com/archive/test
did not run successfully and encountered an error:
How it works...
You can use regular expressions in both parameter definition and the rest of the rule. Let's read our rules one by one.
'post/<alias:[-a-z]+>' => 'post/view',
The alias
parameter should contain one or more English letters or a dash. No other symbols are allowed.
'(posts|archive)' => 'post/index',
Both posts
and archive
lead to post/index
.
'(posts|archive)/<order:(DESC|ASC)>' => 'post/index',
Both posts
and archive
lead to post/index
. The order
parameter can only accept two values: DESC
and ASC
.
'sayhello/<name>' => 'post/hello',
You should specify the name
part but there are no restrictions on what characters are allowed.
Note that regardless of the rule used, the developer should never assume that input data is safe.
There's more...
To learn more about regular expressions, you can use the following sources:
- http://www.php.net/manual/en/reference.pcre.pattern.syntax.php
- Mastering Regular Expressions, Jeffrey Friedl available at http://regex.info/
See also
- The Configuring URL rules recipe