Routing Symfony:关于路由和段塞的问题

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

为了不在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->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();