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

  1. Create a fresh Yii application using yiic webapp as described in the official guide and find your protected/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>',
          ),
       ),
  2. Delete everything from rules as we are going to start from scratch.
  3. In your protected/controllers directory, create PostController.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.

  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 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:

How to do it...

The following screenshot shows that the URL http://example.com/archive/test did not run successfully and encountered an error:

How to do it...

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:

See also

  • The Configuring URL rules recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.239