Php 使用url创建Yi2动态页面:www.example.com/pageName
在我的系统中,用户需要有他们的个人资料页面。我要求将这些页面显示在url中,如下所示:Php 使用url创建Yi2动态页面:www.example.com/pageName,php,url,routing,seo,yii2,Php,Url,Routing,Seo,Yii2,在我的系统中,用户需要有他们的个人资料页面。我要求将这些页面显示在url中,如下所示: www.example.com/John-Doe www.example.com/Mary-Smith 如何在yii2中实现这些url?这些John Doe和Mary Smith可以是用户用户名或配置文件名。例如,我在用户表中有一个名为“name”的字段,它将包含名称“johndoe”、“marysmith”。请注意,我需要搜索引擎友好的网址与“-”而不是空格 URL如下所示: www.example.c
www.example.com/John-Doe
www.example.com/Mary-Smith
如何在yii2中实现这些url?这些John Doe和Mary Smith可以是用户用户名或配置文件名。例如,我在用户表中有一个名为“name”的字段,它将包含名称“johndoe”、“marysmith”。请注意,我需要搜索引擎友好的网址与“-”而不是空格
URL如下所示:
www.example.com/profile/view?id=1
我们没有选择
www.example.com/John-Doe
www.example.com/Mary-Smith
我认为没有正常的方法使用这些URL,因为首先需要确定控制器(在您的情况下是ProfileController
)。从这些网址是不可能做到的
您提供的URL的第二个问题-不保证唯一性。如果另一个名为John Doe的用户将在网站上注册怎么办
例如,查看堆栈溢出处的配置文件链接:
http://stackoverflow.com/users/4395794/black-room-boy
它不是http://stackoverflow.com/black-room-boy
甚至不是http://stackoverflow.com/users/black-room-boy
将id
和name
相结合是更广泛、更稳健的方法。它们也可以像这样与破折号组合:http://stackoverflow.com/users/4395794-black-room-boy
yii2为此有内置的行为,它被称为
将其附加到您的模型:
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的一个示例。保存前,请根据您的名称
属性功能和验证/筛选进行更正
实现唯一url的另一种方法是将属性设置为true
因此,如果John-Doe
existenseJohn-Doe-1
slug将生成,依此类推
请注意,您还可以通过设置callable来指定自己的唯一生成器
我个人不喜欢这种方法
如果选择与Stack Overflow使用的选项类似的选项,请将其添加到url规则中:
'profile/<id:\d+>/<slug:[-a-zA-Z]+>' => 'profile/view',
但实际上,id
足以找到用户。如果使用正确的id
但不同的slug
进行访问,堆栈溢出会重定向。当您完全跳过名称时,也会发生重定向
例如http://stackoverflow.com/users/4395794/black-room-bo
重定向到原始页面http://stackoverflow.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]]);
}
}
非常感谢你!但若我想通过他的id+名称或者仅仅是id来查找用户,但我不想在URL中显示id,我只想显示名称,那个该怎么办呢。这可能与slug或自定义urlManager规则有关吗?类似于“John-Doe-1”(增量)或“John-Doe-255”/“255 John-Doe”这样的slug也是可能的。(id)。在SluggableBehavior中指定$ensureUnique和$uniqueSlugGenerator(在与ids组合的情况下)。然后修改findModel以按slug查找,并修改操作以接收$slug作为get参数。是否要修改代码示例(概要文件控制器)中的findModel和viewAction行?是。当使用findOne()查找模型时,如果多个用户的名字完全相同,那么像“John Doe”这样的URL不能保证结果模型包含所需的用户。回答得好!是否有任何方法可以将静态页面(如“隐私策略”)映射到SiteController的content()方法,并将2或任何数字作为参数传递?我的想法是使用该id从db获取内容。
public function actionView($id, $slug = null)
{
$model = $this->findModel($id);
if ($slug != $model->slug) {
return $this->redirect(['profile/view', ['id' => $id, 'slug' => $model->slug]]);
}
}