www.example.com/John-Doe www.example.com/Mary-Smith
I think there is no normal way to use these URLs, because you need to define a controller first (in your case, it is ProfileController ). Of these URLs, this cannot be done.
The second problem with the addresses you specify is that uniqueness is not guaranteed. What should I do if another user with the name John Doe is registered on the site?
See an example of your profile link in Stack Overflow:
http://stackoverflow.com/users/4395794/black-room-boy
This is not http://stackoverflow.com/black-room-boy and not even http://stackoverflow.com/users/black-room-boy .
Combining id and name is a more common and reliable approach. They can also be combined with a dash as follows: http://stackoverflow.com/users/4395794-black-room-boy
Yii 2 has a built-in behavior for this, it is called SluggableBehavior .
Attach it to your model:
use yii\behaviors\SluggableBehavior; public function behaviors() { return [ [ 'class' => SluggableBehavior::className(), 'attribute' => 'name',
For your specific URL format, you can also specify $value :
'value' => function ($event) { return str_replace(' ', '-', $this->name); }
This is just an example of creating a custom pool. Correct it according to your name attribute attributes and check / filter before saving.
Another way to achieve a unique URL is to set the $ ensureUnique property to true .
So, in the case of John-Doe existense, John-Doe-1 will generate slug, etc.
Note that you can also specify your own unique generator by setting $ uniqueSlugGenerator .
Personally, I do not like this approach.
If you choose an option similar to the one used by Stack Overflow, add it to your URL rules:
'profile/<id:\d+>/<slug:[-a-zA-Z]+>' => 'profile/view',
In ProfileController :
public function actionView($id, $slug) { $model = $this->findModel($id, $slug); ... } protected function findModel($id, $slug) { if (($model = User::findOne(['id' => $id, 'name' => $slug]) !== null) { return $model; } else { throw new NotFoundHttpException('User was not found.'); } }
But actually id enough to find the user. The stack overflow is redirected if you use the correct id but another slug . Redirecting occurs when you also completely miss the name.
For example, http://stackoverflow.com/users/4395794/black-room-bo redirected to the original page http://stackoverflow.com/users/4395794/black-room-boy to avoid duplication of content that is not desirable for SEO.
If you want to use this as well, change the findModel() method as follows:
protected function findModel($id) { if (($model = User::findOne($id) !== null) { return $model; } else { throw new NotFoundHttpException('User was not found.'); } }
And actionView() as follows:
public function actionView($id, $slug = null) { $model = $this->findModel($id); if ($slug != $model->slug) { return $this->redirect(['profile/view', ['id' => $id, 'slug' => $model->slug]]); } }