【问题标题】:Symfony2 directly call actions of controllers without routingSymfony2 直接调用控制器的动作,无需路由
【发布时间】:2016-07-26 00:25:07
【问题描述】:
目前我正在使用 Symfony2 开发一个新项目。
来自 Zend,我真的很喜欢能够直接在 url 中调用控制器及其操作,如下所示:http://www.example.com/dog/bark/loudly
然后无需编写路由,框架将调用 DogController 的 barkAction 并将参数 loudly 传递给它。
不幸的是 Symfony2 似乎不喜欢这样做,我做了一些谷歌搜索,查看了文档,但无济于事。
我很想知道如何在 Symfony2 中实现这一点。
【问题讨论】:
标签:
php
symfony
routing
frameworks
【解决方案1】:
您可以按照in the documentation 的说明创建自己的路由加载器。
然后使用ReflexionClass 列出您的操作。
您还可以使用 DirectoryIterator 在每个控制器上进行迭代
例子:
// src/AppBundle/Routing/ExtraLoader.php
namespace AppBundle\Routing;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
class ExtraLoader extends Loader
{
private $loaded = false;
public function load($resource, $type = null)
{
if (true === $this->loaded) {
throw new \RuntimeException('Do not add the "extra" loader twice');
}
$routes = new RouteCollection();
$controllerName = 'Default';
$reflexionController = new \ReflectionClass("AppBundle\\Controller\\".$controllerName."Controller");
foreach($reflexionController->getMethods() as $reflexionMethod){
if($reflexionMethod->isPublic() && 1 === preg_match('/^([a-ZA-Z]+)Action$/',$reflexionMethod->getName(),$matches)){
$actionName = $matches[1];
$routes->add(
strtolower($controllerName) & '_' & strtolower($actionName), // Route name
new Route(
strtolower($controllerName) & '_' & strtolower($actionName), // Path
array('_controller' => 'AppBundle:'.$controllerName.':'.$actionName), // Defaults
array() // requirements
)
);
}
}
$this->loaded = true;
return $routes;
}
public function supports($resource, $type = null)
{
return 'extra' === $type;
}
}
【解决方案2】:
每个框架都有自己的特点。对我来说,下面的粗略示例是最简单的方法,因此您应该可以通过 http://www.my_app.com/dog/bark/loudly 调用它
将控制器定义为服务。 How to Define Controllers as Services
namespace MyAppBundle\Controller\DogController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
/**
* @Route("/dog", service="my_application.dog_controller")
*/
class DogController extends Controller
{
/**
* @Route("/bark/{how}")
*/
public function barkAction($how)
{
return new Response('Dog is barking '.$how);
}
}
服务定义
services:
my_application.dog_controller:
class: MyAppBundle\Controller\DogController