YII framework user friendly URL

2019-08-31 00:45发布

My yii PHP project has UserController and it has an action called actionView. I can access user view page using following URL

mysite.com/user/view/id/1

I want to change that one to

mysite.com/username

How Can I do it.

I know that i can simply create rule to be more user friendly to get url such as

mysite.com/user/username

But url scheme with database resource name as direct param (mysite.com/username) is whole different story.

标签: php yii
1条回答
我只想做你的唯一
2楼-- · 2019-08-31 01:08

Url rule:

array(
    '<username:\w+>'=>'user/view',
)

Note that in such scheme, you must also create rules for all your controllers and place above rule at the end, so better prefix it with user:

array(
    'user/<username:\w+>'=>'user/view',
)

Resulting url will be example.com/user/username

In action:

public function actionView($username) ...

Update: To make rule which reacts on any input variable create custom url rule class, here is some example, modify to your needs:

class PageUrlRule extends CBaseUrlRule
{

        public function createUrl($manager, $route, $params, $ampersand)
        {
                // Ignore this rule for creating urls
                return false;
        }

        public function parseUrl($manager, $request, $pathInfo, $rawPathInfo)
        {
                // Ignore / url or any controller name - which could conflict with username
                if($pathInfo == '/')
                {
                        return true;
                }
                // Search for username or any resource in db
                // This is for mongo so it should be tuned to your db,
                // just check if username exists
                $criteria = new EMongoCriteria();
                $criteria->url->$lang = $url;
                $criteria->select(['_id']);
                $criteria->limit(1);
                $model = PageItem::model();
                $cursor = $model->findAll($criteria);
                // Create route, instead of $url id can be used
                $route = sprintf('content/page/view/url/%s', urlencode($url));
                // If found return route or false if not found
                return $cursor->count() ? $route : false;
        }

}

Then place this rule in beginning of urlmanager config

'rules' => [
    [
        'class' => 'application.modules.content.components.PageUrlRule'
    ],
    // Other rules here

Important: If user has username same as your controller, it will match username and controller will be inaccessible. You must forbid registering users with same names as controllers.

查看更多
登录 后发表回答