Tuesday, July 3, 2012

Using regular expressions in URL rules in YII

One of the "hidden" features of Yii URL router is that you can use regular expressions that are
pretty powerful when it comes to strings handling.
Getting ready
1. Create a fresh Yii application using yiic webapp as described in the official guide
and find your protected/config/main.php. 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>',
),
),
2. Delete everything from rules as we are going to start from scratch.
3. In your protected/controllers, create PostController.php with the
following code inside:
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 we are going to access using our custom URLs.
4. Configure your application server to use clean URLs. If you are using Apache with
mod_rewrite and AllowOverride turned on, then you should add the following
lines to the .htaccess file under your webroot 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 actions to accept parameters according to some rules and
give "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 to achieve it:
'post/<alias:[-a-z]+>' => 'post/view',
'(posts|archive)' => 'post/index',
'(posts|archive)/<order:(DESC|ASC)>' => 'post/index',
'sayhello/<name>' => 'post/hello',
Now, you can try the following URLs:
// success
http://example.com/post/test-post
// fail
http://example.com/post/another_post
// success
http://example.com/posts
// success
http://example.com/archive
// fail
http://example.com/archive/test
// success
http://example.com/posts/ASC
// success
The following screenshot shows that the URL http://example.com/post/test-post
has run successfully:
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',
Alias parameter should contain one or more English letter or a dash. No other symbols
are allowed.
'(posts|archive)' => 'post/index',
Both posts and archive are leading to post/index.
'(posts|archive)/<order:(DESC|ASC)>' => 'post/index',
Both posts and archive are leading to post/index. 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.

No comments:

Post a Comment