Yii 1.1: How to hide `index` action from URL

10 followers

Here is my experiment inspired by my own question and others from the forum.

I am not talking about [Url: hide index.php] or [How to hide index.php on nginx], however, i am also talking about 'hide' something.

take yii default scaffolding web app as example: assuming that you already did the trick as above to hide index.php from your uri, you might notice that the following two URLs are still working.

/webroot/site/index
/webroot/index.php/site/index

someone in the forum suggested add the following code in /protected/components/Controller.php

public function init(){
    if (strpos(Yii::app()->request->requestUri, '/index.php') !== false){
        throw new CHttpException(404,'The requested page does not exist.');
    }
}

I am not sure if I like the idea of throwing an error, so I took another approach [redirect], so modified the code as:

public function init(){
    if (Yii::app()->urlManager->showScriptName == false){
        if (strpos(Yii::app()->request->requestUri, '/index.php') !== false){
            $_uri = str_replace("/index.php", "", Yii::app()->request->requestUri);
            $_uri = str_replace("//", "", $_uri);
            $this->redirect($_uri);
        }
    }
}

then you will always see url like this which 'truelly' hide index.php

/webroot/site/index

good enough? just wait a minute, someone mentioned in the forumn he/she does not really like to see 'index' in this url even! he/she expects this:

/webroot/site

hmmmm, would redirect do the trick? let's put some code in /protected/controller/SiteController.php:

protected function beforeAction($action)
{
    $_uri = false;
    if (Yii::app()->urlManager->showScriptName == false){
        if (strpos(Yii::app()->request->requestUri, '/index.php') !== false){
            $_uri = str_replace("/index.php", "", Yii::app()->request->requestUri);
        }
        if (Yii::app()->controller->action->id == 'index'){
            if (!$_uri) {
                if (strpos(Yii::app()->request->requestUri, "/index") !== false){
                    $_uri = str_replace("/index", "", Yii::app()->request->requestUri);
                }
            } else {
                if (strpos($_uri, "/index") !== false){
                    $_uri = str_replace("/index", "", $_uri);
                }
            }
        }
    }
 
    if ($_uri !== false){
        $this->redirect($_uri);
    }
    return parent::beforeAction($action);
}

give a try, works? yeah ,,,

*note:

I'm not sure if this is 'the' solution, but sure it will work for those 'picky' developers or users for a clean url.

You may ask why don't you have the above code in Contoller Class [/protected/components/Controller.php], so this trick works for all Controllers? I tried, did work. I guess the redirection lost its way to hit SiteController. Someone may help me on this.

and feel free to modify this wiki.

Total 2 comments

#8742 report it
rootbear at 2012/06/22 02:23pm
thx

thanks @jeroen84

the trick i dumped here is more about replace 'urgly' with 'cleaner' url rather than hiding 'index.php' or default action, i should title it how to remove duplicate urls.

with .htaccess rule of hidding index.php, however, /index.php/controller/action would be still working. with this trick, user will always see /controller/action only.

#8727 report it
yJeroen at 2012/06/22 02:28am
feedback

Hiding index.php should be done using htaccess: http://www.yiiframework.com/doc/guide/1.1/en/topics.url#hiding-x-23x

Hiding the default action, actionIndex() in most cases, is interesting. Though remember, that index isnt always the default action. :)

Leave a comment

Please to leave your comment.

Write new article
  • Written by: rootbear
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +3 / -2
  • Viewed: 12,374 times
  • Created on: Jun 20, 2012
  • Last updated: never
  • Tags: index