映射 slug 与数据库条目

Mapping slug with database entry

在一个 symfony 项目中,我有一个像这样的 url 模式

/resource/{id}

我可以将其转换为一个 slugfied url 作为

/resource/{slug} 

使用 symfony webiste.

中给出的文档

但是,我不知道如何将此 {slug} 映射到数据库中的记录。除了在实体 class 中创建一个 slug 变量并将一个变量存储在数据库中然后使用该 属性 检索记录之外,是否有任何标准方法可以做到这一点?

更新

我不知道 symfony 如何从数据库中检索数据。我的查看操作如下

 /**
 * Finds and displays a Resource entity.
 *
 * @Route("/{slug}", name="resource_show")
 * @Method("GET")
 */
public function showAction(Resource $resource)
{
    $deleteForm = $this->createDeleteForm($resource);
    return $this->render('resource/show.html.twig', array(
        'resource' => $resource,
        'delete_form' => $deleteForm->createView(),
    ));
}

ResourceEntity 中进行适当修改后,我刚刚将控制器中的 id 替换为 slug。现在 symfony 使用 slug 自动从数据库中检索信息并将其传递给 showAction 方法..

你说的是对的, 您应该从字符串(例如:Post 标题)生成一个唯一的 Slug,将其存储在数据库中,然后通过 Slug

找到实体

示例:

$obj = $repository->findOneBySlug('test-post');

如果您想简化创建 Slug 的过程并使用经过良好测试的库,您可以使用 Sluggable behavior extension for Doctrine.

你所要做的就是使用 Synmfony ParameterConvereter。

这是它的样子:

假设您有一个 User 实体。注意 slug 字段。

/**
 * Class User
 *
 * @package AppBundle\Entity
 *
 * @ORM\Entity
 * @Gedmo\Loggable
 */
class User extends BaseUser implements Translatable
{
    /**
     * @var $id
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     * @ORM\Column(type="guid")
     *
     */
    protected $id;

    /**
     * @var
     * @Gedmo\Translatable
     * @Gedmo\Versioned
     * @ORM\Column(type="string"))
     */
    protected $username;
    /**
     * @var
     *
     * @ORM\Column(type="string"))
     */
    protected $firstName;

    /**
     * @var
     *
     * @ORM\Column(type="string"))
     */
    protected $lastName;

    /**
     * @Gedmo\Slug(fields={"firstName"}, style="camel", updatable=false, separator="-")
     * @ORM\Column(length=128, unique=true)
     */
    private $slug;

    /**
     * @Gedmo\Locale
     * Used locale to override Translation listener`s locale
     * this is not a mapped field of entity metadata, just a simple property
     */
    private $locale;

// ...

因此在路由中,您将使用用户的名字而不是 ID。

然后在控制器中你所要做的就是:

    /**
     * @param User    $user
     * @param Request $request
     *
     * @return array
     *
     * @Route(path="/edit/{slug}", name="trans_edit")
     * @ParamConverter("user", class="AppBundle:User", options={"slug" = "slug"})

     * @Template()
     */
    public function editAction(User $user, Request $request)
    {
        dump($user);
    }

// ...

Slug in 自动转换成User对象。无需手动调用DB,ParameterConvereter会自动为您完成。