Symfony2直接调用控制器的动作而不进行路由

时间:2016-07-26 00:25:07

标签: php symfony routing frameworks

目前我正在使用Symfony2开发一个新项目。 来自Zend我真的很高兴能够直接在网址中调用控制器及其操作,如下所示:http://www.example.com/dog/bark/loudly

然后在不必编写路线的情况下,框架会调用DogController的barkAction并将参数loudly传递给它。

不幸的是Symfony2似乎并不喜欢这样做,我做了一些谷歌搜索,看了一下文档,但是没有用。 我很想知道如何在Symfony2中实现这一点。

2 个答案:

答案 0 :(得分:0)

您可以像解释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;
    }
}

答案 1 :(得分:0)

每个框架都有自己的特色。对我来说,下面的粗略示例是最简单的方法,因此您应该可以通过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