我目前正在将一个现有的应用程序迁移到Symfony2,它有大约100个控制器,每个控制器中有大约8个动作。所有当前的操作都命名如下:
public function index(){}
然而,Symfony的默认命名约定是indexAction()。 是否可以保留我当前的所有操作并告诉Symfony在方法名称后面没有“Action”字样的情况下使用它? 谢谢。
答案 0 :(得分:2)
是的,这是可能的。您应该能够正常定义路由,但您需要更改内核找到控制器的方式。执行此操作的最佳方法是替换/装饰/扩展服务' controller_name_converter'。这是一项私人服务,并被注入' controller_resolver'服务。
您要替换的类的源代码位于Symfony \ Bundle \ FrameworkBundle \ Controller \ ControllerNameParser'。
基本上,代码就像这样运行。 '捆绑:控制器:动作'您在创建路由时指定的内容保存在缓存中。当一个路由匹配时,该字符串将被返回给内核,而内核又会调用' controller_resolver'它调用' controller_name_resolver'。该类将字符串转换为" namespace :: method"符号
查看decorating services以了解如何操作。
这是一个可以使用的未经测试的课程
class ActionlessNameParser
{
protected $parser;
public function __construct(ControllerNameParser $parser)
{
$this->parser = $parser;
}
public function parse($controller)
{
if (3 === count($parts = explode(':', $controller))) {
list($bundle, $controller, $action) = $parts;
$controller = str_replace('/', '\\', $controller);
try {
// this throws an exception if there is no such bundle
$allBundles = $this->kernel->getBundle($bundle, false);
} catch (\InvalidArgumentException $e) {
return $this->parser->parse($controller);
}
foreach ($allBundles as $b) {
$try = $b->getNamespace().'\\Controller\\'.$controller.'Controller';
if (class_exists($try)) {
// You can also try testing if the action method exists.
return $try.'::'.$action;
}
}
}
return $this->parser->parse($controller);
}
public function build($controller)
{
return $this->parser->build($controller);
}
}
并替换原始服务,如:
actionless_name_parser:
public: false
class: My\Namespace\ActionlessNameParser
decorates: controller_name_converter
arguments: ["@actionless_name_parser.inner"]
答案 1 :(得分:0)
显然,Action后缀用于区分映射到路由的内部方法和方法。 (根据这个question)。
确定的最佳方式是尝试。
// src/AppBundle/Controller/HelloController.php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class HelloController
{
/**
* @Route("/hello/{name}", name="hello")
*/
public function indexAction($name)
{
return new Response('<html><body>Hello '.$name.'!</body></html>');
}
}
尝试从方法名称中删除Action,看看会发生什么。