【问题标题】: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
      

      【讨论】:

        猜你喜欢
        • 2015-10-02
        • 1970-01-01
        • 2012-10-13
        • 2012-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-11
        相关资源
        最近更新 更多