使用数据库条目映射slug

时间:2016-03-10 06:52:58

标签: php symfony routing slug

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

/resource/{id}

我可以将其转换为缓慢的网址

/resource/{slug} 

使用symfony webiste中提供的文档。

但是,我不知道如何将此{slug}映射到数据库中的记录。除了在实体类中创建一个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(),
    ));
}

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

2 个答案:

答案 0 :(得分:2)

你提到的是正确的, 你应该从一个字符串生成一个独特的Slug(例如:帖子标题),将它存储在数据库中,并通过Slug找到实体

示例:

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

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

答案 1 :(得分:2)

您所要做的就是使用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;

// ...

因此,在路由中,您将拥有用户的名字。

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

    /**
     * @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会自动为您完成。