如何在Symfony中为example.com/username创建路由并保留所有旧URL

时间:2017-08-24 14:11:38

标签: php symfony routing routes

目标:

我想要Facebook,Twitter等用户名网址:example.com/Username

问题

如果我添加

,则无法访问/register等网址
   * @Route("/{user}", name="user_profile")

当然我可以/user/username,但我需要这个案例/username

实现此目的的正确方法是什么?

一个想法是为404个页面添加一个事件监听器,检查URL是否为example.com/abc并检查用户名是否存在。但这似乎是一个糟糕的黑客。

简短问题:

如何以专业的方式制作像www.example.com/username这样的路线,而不会与/registe等冲突?

1 个答案:

答案 0 :(得分:4)

首先,您需要定义如何处理路径冲突,例如/register/login/impressum和与这些路径冲突的用户名(如“register”,“登录“和”impressum“)。您可能希望拥有一个不允许的用户名黑名单,因为它们会与您预先定义的路径发生冲突。

要解决实际问题,您可以为/{username}创建一个“catchall”路线(可能在{username}部分使用正则表达式有一些限制) 之后所有其他路线。

当您在symfony项目中请求路径时,symfony将按照定义的顺序检查路由。因此,如果您最后定义用户配置文件路由(在routing.yml文件的底部),则仅在所有其他路由与请求不匹配时才使用它。 这意味着,如果您的用户名称为“register”,则他将无法打开其个人资料页面,因为注册页面的/register路径将首先与请求匹配。

在Symfony Standard Edition中,路由是这样的:

app:
    resource: '@AppBundle/Controller/'
    type: annotation

除非在routing.yml文件中写入多个条目,否则无法使用注释处理路径位置。要确保用户配置文件路由是最后一个,您应该删除此操作的注释并使用yml创建路由,如下所示:

app:
    resource: '@AppBundle/Controller/'
    type: annotation

user_profile:
    path: /{user}
    defaults:
        _controller: App:User:profile