【问题标题】:How to use multiple method annotations on specific routes?如何在特定路由上使用多个方法注释?
【发布时间】:2015-04-17 12:14:14
【问题描述】:

我知道有人讨论了在 Symfony2 中处理路由的最佳实践(routing.yml 与注释)。让我提一下,我想使用注释保持原样。

当我在控制器中为单个操作定义多个路由时,@Method 注释的最后一个定义似乎覆盖了所有其他,这就是我收到以下错误的原因:

No route found for "POST /index": Method Not Allowed (Allow: GET, HEAD)

这只是我正在使用的一小段代码。

namespace MySelf\MyBundle\Controller;

use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

class MyController extends Controller{

    /**
     * @Route(
     *     "/index",
     *     name="index_default"
     * )
     * @Method({"GET", "POST"})
     *
     * @Route(
     *     "/index/{id}",
     *     name="index",
     *     requirements={
     *          "id": "\d+"
     *     }
     * )
     * @Method({"GET"})
     *
     * @return Response
     */
     public function indexAction($id = null){
          /*DO SOME FANCY STUFF*/
          ...
          return $response;
     }
}

虽然效果很好!

index_default:
    pattern: /index
    defaults: { _controller: MyBundle:MyController:index }
    requirements:
      _method: GET|POST

index:
    pattern: /index/{id}
    defaults: { _controller: MyBundle:MyController:index }
    requirements:
      _method: GET
      id: \d+

有什么想法可以通过使用注释来实现它与 routing.yml 一起使用的方式吗?

【问题讨论】:

  • 尝试直接在路由注解中指定方法(methods="GET|POST")
  • 谢谢,这正是我希望得到的 :) 只需将其作为单独的答案发布,这样我就可以勾选这个 :)

标签: php symfony controller annotations http-protocols


【解决方案1】:

你应该在每个路由注解中指定方法,@Method 只能声明一次。事实上,每种类型的注解都是分开处理的,它们彼此并不了解。

/**
 * @Route(
 *     "/index",
 *     name="index_default",
 *     methods="GET|POST"
 * )
 *
 * @Route(
 *     "/index/{id}",
 *     name="index",
 *     requirements={
 *          "id": "\d+"
 *     },
 *     methods="GET"
 * )
 *
 * @return Response
 */

【讨论】:

    【解决方案2】:

    我认为不可能两次声明@route 或@Method 注释。您可以像这样为 $id 创建一个默认值:

    /**
     * @Route(
     *     "/index/{id}",
     *     name="index",
     *     requirements={
     *          "id": "\d+"
     *     },
     *     defaults={"id" = null}
     * )
     *
     * @Method({"GET", "POST"})
     *
     * @return Response
     */
    public function indexAction($id)
    {
        /*DO SOME FANCY STUFF*/
          ...
          return $response;
    }
    

    [编辑] 好的,实际上可以在注解中声明多个路由。但是,我认为您不应该再次声明 @Method 。我不确定这一点,但似乎是这样的:

    @Method({"GET"})
    

    覆盖这个:

    @Method({"GET", "POST"})
    

    当你覆盖它时,你只剩下 GET 了。删除只声明 GET 的注解,它应该可以工作。

    【讨论】:

    • 可以声明多条路由!我还在单个操作中使用了带有 4 条路线的注释,它们都按预期工作。截图只是一个例子!
    • 嗯,我认为这可以实现您想要实现的目标,对吧?另外,为什么你需要多条路线来执行相同的操作?对我来说似乎没有必要。
    • 我会亲自拆分这些方法。有一个编程最佳实践指出:“一个方法应该做一件事并且只做一件事”。考虑到这一点,您应该有一种发布项目的方法、一种用于索引的方法和一种用于读取单个项目的方法。
    • 我知道 Clean Code 的规则,这就是我想要实现的目标,但是要解释为什么我目前需要这种方法是很复杂的。稍后这件事需要修复,但还有比这个问题更严肃的工作要做。不过,谢谢你的建议:)
    猜你喜欢
    • 2011-12-08
    • 1970-01-01
    • 2018-07-13
    • 2021-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    相关资源
    最近更新 更多