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

时间:2010-07-13 18:50:57

标签: routing symfony1

为了不在网址中显示社交网络成员的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();

一切正常:当我点击他们的名字时,会显示相应的个人资料,网址就是这个类型:

  

frontend_dev.php / miembros /玛利亚+的+米格尔+尔瓦拉多

现在我想在网址中插入名称,这样我就改变了这条路线:

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;
  }
}

现在,当我点击某个成员的名字时,会显示以下网址:

  

frontend_dev.php / miembros /玛利亚-DE-米格尔-尔瓦拉多

但它始终显示我在灯具文件中的第一个成员的个人资料。

我怎样才能让它发挥作用?

Ubuntu 8.04 - Symfony 1.3。

2 个答案:

答案 0 :(得分:1)

slug字段需要是一个真正的列,而不是您创建的虚拟列 访问URL时,doctrine正在寻找单个对象 匹配网址中找到的字段 - 在您的情况下,这意味着没有字段,那就是 为什么你看到你桌子上的第一条记录。查询记录器 应该显示select * from tablename limit 1;

之类的内容

关于你网址的说明:你确定不会有多个网址吗? 有同名人物?如果发生这种碰撞,没有人会这样 能够看到第2,第3等人的页面。我会以/miembros/:id/:slug的形式在网址中包含ID,这样就可以保持人类的可读性并且肯定不会发生冲突。

<强>更新
在第一条评论中,@ Raise建议使用ID的盐渍哈希而不是ID本身。这比我原来包含身份证的想法要好 sfDoctrineGuardPlugin为每个用户生成一个新的salt,存储它,并用于设置/验证密码。您需要在users表中为hash创建一个新字段(不需要存储salt,ID也不会更改),并且您的url将显示为/miembros/:hash/:slug

答案 1 :(得分:1)

您可以使用这些路由选项:options: { model: Usuario, type: object, method: getObjectBySlug },但您需要一个getObjectBySlug()方法,该方法会在给定slug的情况下检索您的对象。现在你有getNombreApellidosSlug()恰恰相反。问题是通常,没有办法知道slu“maria-martinez”是否对应用户“Maria Martinez”,“MaríaMartínez”,“MaRiA MaRtInEz”或“MaríaMartíÑez”,所以这是一个问题。您可以通过“slug”列来解决它。

我的建议是使用Sluggable behaviour of Doctrine来处理slug列。

我在this pet project上使用它来做到这一点。使用它非常简单:

首先,您在the schema中激活它:

actAs:
  Timestampable: ~
  Sluggable:
    fields: [name]
    indexName: name_slug
    canUpdate: true
    unique: true

它将创建并保留一个名为“slug”的列。

然后,在the routing中使用它。在我的情况下是:

list_permalink:
  url: /:slug
  class: sfDoctrineRoute
  options: { model: SkinnyList, type: object, method: getObjectBySlug }
  param: { module: list, action: show }
  requirements: { sf_method: get }

您需要lib/model/doctrine/yourmodelTable.class.php中的方法getObjectBySlug:

  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();