一个控制器的两条路线或一组动作的两条路线

Mee*_*ons 2 routing symfony

以下是所需 URL 的方案:

/service/getBalance    should map to CustomerController::getBalance
/service/addBalance    should map to CustomerController::addBalance

/customer/getBalance    should map to CustomerController::getBalance
/customer/addBalance    should map to CustomerController::addBalance
Run Code Online (Sandbox Code Playgroud)

这是一个简单的控制器

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class CustomerController extends Controller {

    /**
     * @Route("/getBalance")
     */
    public function getBalanceAction(Request $request) {

    }

    /**
     * @Route("/addBalance")
     */
    public function addBalanceAction(Request $request) {

    }

} // class CustomerController
Run Code Online (Sandbox Code Playgroud)

试过以下方法。他们都没有工作。

# rounting.yml
v1:
    resource: "@AppBundle/Controller/CustomerController.php"
    prefix:   /service
    type:     annotation

v2:
    resource: "@AppBundle/Controller/CustomerController.php"
    prefix:   /customer
    type:     annotation
Run Code Online (Sandbox Code Playgroud)

加载具有不同前缀的相同资源总是会覆盖上一次出现(最后一次有效)。以下也不会出于相同的原因并具有相同的行为。

# rounting.yml
v1:
    resource: "@AppBundle/Resources/config/routing_customer.yml"
    prefix:   /service

v2:
    resource: "@AppBundle/Resources/config/routing_customer.yml"
    prefix:   /customer


# routing_customer.yml
getBalance:
    path: /getBalance
    defaults : { _controller: "AppBundle:Customer:getBalance" }

addBalance:
    path: /addBalance
    defaults : { _controller: "AppBundle:Customer:addBalance" }
Run Code Online (Sandbox Code Playgroud)

第三个不工作的选项:

# rounting.yml
v1:
    resource: "@AppBundle/Resources/config/routing_v1.yml"
    prefix:   /     # evenr putting /service here instead of inside

v2:
    resource: "@AppBundle/Resources/config/routing_v2.yml"
    prefix:   /     # evenr putting /customer here instead of inside

# routing_v1.yml
getBalance:
    path: /service/getBalance
    defaults : { _controller: "AppBundle:Customer:getBalance" }

addBalance:
    path: /service/addBalance
    defaults : { _controller: "AppBundle:Customer:addBalance" }

# routing_v2.yml
getBalance:
    path: /customer/getBalance
    defaults : { _controller: "AppBundle:Customer:getBalance" }

addBalance:
    path: /customer/addBalance
    defaults : { _controller: "AppBundle:Customer:addBalance" }
Run Code Online (Sandbox Code Playgroud)

我实际上需要路由//customer到同一个控制器: /getBalance/customer/getBalance.

我想为一组方法提供两个前缀。如何在 Symfony 中做到这一点?

我的试验结论、@goto 的回答和@Cerad 的评论:

如果我使用不同的路由名称,上面的最后一个示例可能会起作用。路线名称在整个项目中是唯一的(不仅在文件中唯一)。v1_getBalancev2_getBalance

另一种解决方案是使用@goto 描述的自定义加载器

got*_*oto 6

你可以这样做路由:

     @Route(
          "/{subject}/getBalance",
          requirements={
              "subject": "customer|service"
          }
      )
Run Code Online (Sandbox Code Playgroud)

在 yml 中:

subject_getbalance:
  path:     /{subject}/getBalance
  requirements:
      subject:  customer|service
Run Code Online (Sandbox Code Playgroud)

要求比什么都不安全:它允许您像foo/getBalance在另一个控制器上一样路由另一条路线(因为它不符合要求)

编辑:对于您的特殊情况,因为您也需要 /getBalance 映射到您的路线,您可以这样做:

subject_getbalance:
      path:     /{subject}/getBalance
      default: { _controller: YourBundle:Controller }
      requirements:
          subject:  customer|service
default_getbalance:
      path:     /getBalance
      default: { _controller: YourBundle:Controller, subject: customer }
Run Code Online (Sandbox Code Playgroud)

编辑:最后一个想法是自定义路由加载器(但我从未尝试过):

class ExtraLoader extends Loader
{
    public function load($resource, $type = null)
    {

       /* ... */

        $prefixes = [ 'default_' =>'','customer_' =>'/customer','service_' =>'/service']

        // prepare a new route
        $path = '/getbalance/{parameter}';
        $defaults = array(
            '_controller' => 'YourBundle:Actiona',
        );
        $requirements = array(
            'parameter' => '\d+',
        );
       foreach($prefixes as $prefixName => $prefixRoute) {
          $route = new Route($prefixRoute . $path, $defaults, $requirements);
          $routes->add($prefixName . 'getBalance', $route);
       }
Run Code Online (Sandbox Code Playgroud)

这将允许您生成 3 条路线:

default_getBalance: /getBalance
customer_getBalance: /customer/getBalance
service_getBalance: /service/getBalance
Run Code Online (Sandbox Code Playgroud)

  • 从 Symfony 4.1 开始,您可以为导入的路由名称添加前缀:https://symfony.com/blog/new-in-symfony-4-1-prefix-imported-route-names 这样,您可以在一个路由文件中导入两次使用不同的名称前缀以避免任何路由名称被覆盖 (2认同)