Изменить папку контроллеров Symfony 3
Я работаю над проектом с Symfony 3, и я хочу, чтобы моя папка AppBundle была такой:
- AppBundle/
- домен/
- приложения/
- инфраструктуре/
- UserInterface/
2 ответов
вы также можете обратиться к этому контроллеру, используя его полное имя класса и метода (Ref.):
app.home_page:
path: /test
defaults: { _controller: AppBundle\UserInterface\Controller\DefaultController::indexAction }
@Yonel действительно самым простым решением в такого рода вопросе. Однако вопрос о том, как настроить контроллер-резольвер, возникает так часто. Прошло некоторое время с тех пор, как я возился с переопределением фреймворка, поэтому я решил пройти шаги в Symfony 3.2.
цель состоит в том, чтобы иметь возможность определить маршрут, как:
// routing.yml
app.home_page:
path: /test
defaults: {_controller: AppBundle:UserInterface\Controller:Default:indexAction}
обратите внимание, что в _controller есть четыре:. Идея заключается в том, что второй аргумент будет использоваться для определения каталог контроллера внутри данного пакета.
чтобы реализовать это, нам нужно переопределить ControllerNameParser по умолчанию. Поиск через FrameworkBundle\Resources\config мы находим, что служба определена в интернете.xml с идентификатором controller_name_converter. В хорошие дни ole все классы framework имели связанные значения параметров. Мы могли бы фактически изменить службу, просто указав новое значение параметра для имени класса. В наше время, нам нужно доработать фактическое определение службы, для которого нам нужен пропуск компилятора. Проводка:
// 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);
}
}
таким образом, хотя есть более простые способы ответить на этот конкретный вопрос, если вам действительно нужно настроить, как работает решатель, то этот ответ, возможно, может служить ссылкой.