Routing Symfony:关于路由和段塞的问题
为了不在URL中显示我的社交网络成员的ID,我创建了以下路由:Routing Symfony:关于路由和段塞的问题,routing,symfony1,Routing,Symfony1,为了不在URL中显示我的社交网络成员的ID,我创建了以下路由: perfil_miembro: url: /miembros/:nombre_apellidos class: sfDoctrineRoute options: { model: Usuario, type: object} param: { module: miembros, action: show} 并在show action中添加了这一行: $this->usuario = $this->get
perfil_miembro:
url: /miembros/:nombre_apellidos
class: sfDoctrineRoute
options: { model: Usuario, type: object}
param: { module: miembros, action: show}
并在show action中添加了这一行:
$this->usuario = $this->getRoute()->getObject();
它工作正常:当我点击他们的名字时,会显示相应的配置文件,URL是这种类型:
前端开发php/miembros/Maria+de+Miguel+Alvarado
现在,我想在URL中插入名称,因此我已通过以下方式更改了路由:
perfil_miembro:
url: /miembros/:nombre_apellidos_slug
class: sfDoctrineRoute
options: { model: Usuario, type: object}
param: { module: miembros, action: show}
我创建了以下方法:
public function getNombreApellidosSlug()
{
return Tirengarfio::slugify($this->getNombreApellidos());
}
class Tirengarfio
{
static public function slugify($text)
{
// replace all non letters or digits by -
$text = preg_replace('/\W+/', '-', $text);
// trim and lowercase
$text = strtolower(trim($text, '-'));
return $text;
}
}
现在,当我单击某个成员的名称时,此URL将显示:
frontend_dev.php/miembros/maria-de-miguel-alvarado
但它总是显示fixtures文件中第一个成员的配置文件
我怎样才能让它工作
Ubuntu 8.04-1.3。slug字段必须是一个真实的列,而不是您创建的虚拟列。
当url被访问时,条令正在寻找单个对象 匹配在url中找到的字段-在您的情况下,这意味着没有字段,这是错误的 为什么您会看到表中的第一条记录。查询记录器 应该显示类似于
select*from tablename limit 1的内容代码>
关于您的url的注意事项:您确定不会有多个url吗
同名的人?如果发生这样的碰撞,没有人会受伤
能够看到第二、第三等个人页面。我会将ID以/miembros/:ID/:slug
的形式包含在url中,这样它就保持了可读性,并且肯定不会发生冲突
更新
在第一条评论中,@Raise建议使用ID的盐散列,而不是ID本身。这比我最初包含ID的想法要好。
sfDoctrineGuardPlugin为每个用户生成一个新的salt,并存储它,用于设置/验证密码。您需要在users表中为哈希设置一个新字段(salt不需要存储,ID不会更改),您的url看起来像/miembros/:hash/:slug
您可以使用以下路由选项:选项:{model:Usuario,type:object,method:getObjectBySlug}
,但是您需要一个getObjectBySlug()
方法来检索给定slug的对象。现在您有了getNombreApellidosSlug()
,正好相反。问题是,通常无法知道slug“maria martinez”是否对应于用户“maria martinez”、“maria martinez”、“maria martinez”或“maria martinez”,因此这是一个问题。你可以通过一个“slug”列来解决这个问题
我的建议是使用,这会照顾到段塞柱
我用它来做这件事。使用它非常简单:
首先,在以下位置激活它:
它将创建并保存一个名为“slug”的列
然后,把它用在。就我而言:
list_permalink:
url: /:slug
class: sfDoctrineRoute
options: { model: SkinnyList, type: object, method: getObjectBySlug }
param: { module: list, action: show }
requirements: { sf_method: get }
您需要一个getObjectBySlug方法:
在操作中,可以通过执行以下操作检索对象:
$this->list = $this->getRoute()->getObject();
+1建议“uniquify”URL以避免冲突,尽管我认为id和salt的一些散列会更好-避免将id暴露给网站。Doctrine真的构建了这样的查询,并返回数据库中的第一行吗?如果这是真的,那就令人担忧了。@raisethehash是个好主意。关于查询构建,我是一个推进用户,但根据症状,这是我能想象的唯一方式。我同意计数可能是为了查看may记录与查询的匹配程度,但这不是必须的。感谢Maerlyn,你写了“我会在url中包含ID”,但这不是一个好的做法,正如你在这里看到的(搜索permalinks)@Raise(希望你能读到)推进和条令路径都调用$variables=$this->getRealVariables()
,因此,他们可以简单地忽略不映射到DB列的url变量。请参阅SFPROPERROUTE的第46行和sfDoctrineRoute的第68行(当然是1.4版)@Maerlyn我不完全理解这一部分:您需要在用户表中为哈希设置一个新字段(不需要存储salt,ID不会更改),。你能再帮我一点忙吗?
public function getObjectBySlug($options = array())
{
if (!isset($options['slug']))
{
throw new InvalidArgumentException('The slug is required in the options');
}
$q = $this->createQuery('td')->where('td.slug = ?', $options['slug']) ;
return $q->fetchOne();
}
$this->list = $this->getRoute()->getObject();