使用 url 创建 yii2 动态页面:www.example.com/pageName
Creating yii2 dynamic pages with url: www.example.com/pageName
在我的系统中,用户需要有他们的个人资料页面。我要求这些页面将显示在 url 中,如下所示:
www.example.com/John-Doe
www.example.com/Mary-Smith
如何在yii2中实现这些URL?这些 John-Doe 和 Mary-Smith 可以是用户用户名或个人资料名称。例如,我在用户 table 中有一个名为 "name" 的字段,它将包含名称 "John Doe"、"Mary Smith"。请注意,我需要带有“-”而不是空格的 SEO 友好 URL。
这样的网址:
www.example.com/profile/view?id=1
不是一个选项。
www.example.com/John-Doe
www.example.com/Mary-Smith
我认为没有使用这些 url 的正常方法,因为首先需要确定控制器(在您的情况下是 ProfileController
)。从这些 urls 这是不可能做到的。
您提供的 url 的第二个问题 - 不保证唯一性。如果另一个名为 John Doe
的用户将在网站上注册怎么办?
例如,查看您在 Stack Overflow 上的个人资料 link:
http://whosebug.com/users/4395794/black-room-boy
不是 http://whosebug.com/black-room-boy
甚至 http://whosebug.com/users/black-room-boy
。
结合使用 id
和 name
是更广泛和更可靠的方法。它们也可以像这样与破折号结合使用:http://whosebug.com/users/4395794-black-room-boy
Yii 2 为此内置了行为,称为 SluggableBehavior。
将它附加到您的模型:
use yii\behaviors\SluggableBehavior;
public function behaviors()
{
return [
[
'class' => SluggableBehavior::className(),
'attribute' => 'name',
// In case of attribute that contains slug has different name
// 'slugAttribute' => 'alias',
],
];
}
对于您的特定 url 格式,您还可以指定 $value
:
'value' => function ($event) {
return str_replace(' ', '-', $this->name);
}
这只是生成自定义 slug 的示例。根据您的 name
属性特征和保存前的验证/过滤进行更正。
实现独特 url 的另一种方法是将 $ensureUnique 属性 设置为 true
。
所以如果 John-Doe
existense John-Doe-1
将生成 slug 等等。
请注意,您还可以通过设置 $uniqueSlugGenerator 可调用来指定您自己的唯一生成器。
我个人不喜欢这种方法。
如果您选择类似于 Stack Overflow 使用的选项,请将其添加到您的 url 规则中:
'profile/<id:\d+>/<slug:[-a-zA-Z]+>' => 'profile/view',
在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.');
}
}
但其实id
已经足够找到用户了。如果您使用正确的 id
但不同的 slug
进行访问,Stack Overflow 会重定向。当您也完全跳过名称时会发生重定向。
例如 http://whosebug.com/users/4395794/black-room-bo
重定向到原始页面 http://whosebug.com/users/4395794/black-room-boy
以避免不利于 SEO 的内容重复。
如果您也想使用它,请像这样修改 findModel()
方法:
protected function findModel($id)
{
if (($model = User::findOne($id) !== null) {
return $model;
} else {
throw new NotFoundHttpException('User was not found.');
}
}
和actionView()
像这样:
public function actionView($id, $slug = null)
{
$model = $this->findModel($id);
if ($slug != $model->slug) {
return $this->redirect(['profile/view', ['id' => $id, 'slug' => $model->slug]]);
}
}
在我的系统中,用户需要有他们的个人资料页面。我要求这些页面将显示在 url 中,如下所示:
www.example.com/John-Doe
www.example.com/Mary-Smith
如何在yii2中实现这些URL?这些 John-Doe 和 Mary-Smith 可以是用户用户名或个人资料名称。例如,我在用户 table 中有一个名为 "name" 的字段,它将包含名称 "John Doe"、"Mary Smith"。请注意,我需要带有“-”而不是空格的 SEO 友好 URL。
这样的网址: www.example.com/profile/view?id=1 不是一个选项。
www.example.com/John-Doe
www.example.com/Mary-Smith
我认为没有使用这些 url 的正常方法,因为首先需要确定控制器(在您的情况下是 ProfileController
)。从这些 urls 这是不可能做到的。
您提供的 url 的第二个问题 - 不保证唯一性。如果另一个名为 John Doe
的用户将在网站上注册怎么办?
例如,查看您在 Stack Overflow 上的个人资料 link:
http://whosebug.com/users/4395794/black-room-boy
不是 http://whosebug.com/black-room-boy
甚至 http://whosebug.com/users/black-room-boy
。
结合使用 id
和 name
是更广泛和更可靠的方法。它们也可以像这样与破折号结合使用:http://whosebug.com/users/4395794-black-room-boy
Yii 2 为此内置了行为,称为 SluggableBehavior。
将它附加到您的模型:
use yii\behaviors\SluggableBehavior;
public function behaviors()
{
return [
[
'class' => SluggableBehavior::className(),
'attribute' => 'name',
// In case of attribute that contains slug has different name
// 'slugAttribute' => 'alias',
],
];
}
对于您的特定 url 格式,您还可以指定 $value
:
'value' => function ($event) {
return str_replace(' ', '-', $this->name);
}
这只是生成自定义 slug 的示例。根据您的 name
属性特征和保存前的验证/过滤进行更正。
实现独特 url 的另一种方法是将 $ensureUnique 属性 设置为 true
。
所以如果 John-Doe
existense John-Doe-1
将生成 slug 等等。
请注意,您还可以通过设置 $uniqueSlugGenerator 可调用来指定您自己的唯一生成器。
我个人不喜欢这种方法。
如果您选择类似于 Stack Overflow 使用的选项,请将其添加到您的 url 规则中:
'profile/<id:\d+>/<slug:[-a-zA-Z]+>' => 'profile/view',
在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.');
}
}
但其实id
已经足够找到用户了。如果您使用正确的 id
但不同的 slug
进行访问,Stack Overflow 会重定向。当您也完全跳过名称时会发生重定向。
例如 http://whosebug.com/users/4395794/black-room-bo
重定向到原始页面 http://whosebug.com/users/4395794/black-room-boy
以避免不利于 SEO 的内容重复。
如果您也想使用它,请像这样修改 findModel()
方法:
protected function findModel($id)
{
if (($model = User::findOne($id) !== null) {
return $model;
} else {
throw new NotFoundHttpException('User was not found.');
}
}
和actionView()
像这样:
public function actionView($id, $slug = null)
{
$model = $this->findModel($id);
if ($slug != $model->slug) {
return $this->redirect(['profile/view', ['id' => $id, 'slug' => $model->slug]]);
}
}