更改Symfony 3控制器文件夹

时间:2016-12-01 13:55:20

标签: symfony path controller

我正在使用Symfony 3进行一个项目,我想让我的AppBundle文件夹像这样:

  • 的appbundle /
    • 域/
    • 应用程序/
    • Infrasctructure /
    • 用户界面/
      • 控制器/
        • DefaultController /

我想将“Controller”文件夹放在UserInterface图层中。问题是加载控制器的Symfony魔术方法是在“AppBundle / Controller”路径上搜索它们。

是否可以选择在我的routing.yml文件中指定控制器路径?

app.home_page:
  path: /test
  defaults: {_controller: AppBundle:UserInterface\Default:indexAction}

2 个答案:

答案 0 :(得分:4)

您也可以使用其完全限定的类名称和方法(Ref.)来引用此控制器:

app.home_page:
    path: /test
    defaults: { _controller: AppBundle\UserInterface\Controller\DefaultController::indexA‌​ction }

答案 1 :(得分:4)

<@> @ Yonel的答案确实是解决这类问题的最简单方法。但是,如何调整控制器旋转变压器的问题确实经常出现。已经有一段时间了,因为我搞乱了覆盖框架服务,所以我决定完成Symfony 3.2中的步骤。

目标是能够定义如下路线:

// routing.yml
app.home_page:
  path: /test
  defaults: {_controller: AppBundle:UserInterface\Controller:Default:indexAction}

请注意_controller中有四个:&#39; s。我们的想法是第二个参数将用于确定给定包中的控制器目录。

要实现这一点,我们需要覆盖默认的ControllerNameParser。通过FrameworkBundle \ Resources \ config搜索,我们发现该服务在web.xml中定义,其id为controller_name_converter。回到好日子里,所有框架类都有相关的参数值。我们实际上可以通过简单地为类名提供新的参数值来修改服务。现在,我们需要修改我们需要编译器传递的实际服务定义。接线:

// AppBundle.php
namespace AppBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use AppBundle\DependencyInjection\Compiler\CustomPass;

class AppBundle extends Bundle
{
    // http://symfony.com/doc/current/service_container/compiler_passes.html
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new CustomPass());
    }
}

// CustomPass.php
namespace AppBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

// http://symfony.com/doc/current/bundles/override.html#services-configuration
class CustomPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('controller_name_converter');
        $definition->setClass('AppBundle\Controller\ControllerNameParser');
        $definition->addArgument('SomeParameter');
    }
}

请注意,我在名称解析器中添加了一个额外的参数,以显示它是如何完成的。因此,您实际上可以使用一些参数值来指示搜索控制器的位置。

自定义名称解析器的实际实现有点混乱,主要是因为任务的性质。它当然可以被改进,但基本上任何具有四个冒号的控制器字符串都会被处理。

namespace AppBundle\Controller;

use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser as ControllerNameParserBase;

class ControllerNameParser extends ControllerNameParserBase
{
    public function __construct(KernelInterface $kernel, $someParameter)
    {
        return parent::__construct($kernel);
    }

    public function parse($controllerString)
    {
        $parts = explode(':', $controllerString);
        if (4 !== count($parts)) {
            return parent::parse($controllerString);
        }
        list($bundleName, $controllerDir, $controller, $action) = $parts;
        $controller = str_replace('/', '\\', $controller);

        $bundle = $this->kernel->getBundle($bundleName, false)[0];

        $try = $bundle->getNamespace().'\\'.$controllerDir.'\\'.$controller.'Controller';

        if (class_exists($try)) {
            return $try.'::'.$action;
        }
        return parent::parse($controllerString);
    }
}

所以即使有更简单的方法来回答这个问题,如果你真的需要调整解析器的工作方式,那么这个答案也许可以作为参考。