【问题标题】:How can I get the action name in a Symfony2 controller?如何在 Symfony2 控制器中获取操作名称?
【发布时间】:2014-04-04 02:54:42
【问题描述】:

有没有办法在 Symfony2 控制器中获取动作的名称?

public function createAction(Request $request, $title) {

    // Expected result: create
    $name = $this->getActionName();

}

【问题讨论】:

    标签: php symfony controller action


    【解决方案1】:

    使用:

    $request->attributes->get('_controller');
    // will get yourBundle\Controller\yourController::CreateAction
    
    $params = explode('::',$request->attributes->get('_controller'));
    // $params[1] = 'createAction';
    
    $actionName = substr($params[1],0,-6);
    // $actionName = 'create';
    

    【讨论】:

    • 这也是错误的。动作方法不需要被调用“somethingAction”如果“动作”是拖尾,这可以通过添加对名称的检查来解决。
    • @Touki,正如我在对我的回答的评论中提到的,这个问题是 Symfony2 问题(见标签)。考虑在此处阅读有关控制器命名约定的信息:symfony.com/doc/current/book/…
    • 更重要的是,一个动作可能在其函数参数声明中没有请求占位符,然后变量 $request 将无法访问。
    • 如何获取控制器中的所有操作?
    【解决方案2】:

    我找到了这个 sn-p (here):

    $matches    = array();
    $controller = $this->getRequest()->attributes->get('_controller');
    preg_match('/(.*)\\\(.*)Bundle\\\Controller\\\(.*)Controller::(.*)Action/', $controller, $matches);
    

    这似乎是一个很有前途的方法。 这个正则表达式实际上不起作用。但是使用strstr()获取动作名称并不难。 Works!

    然后返回 (see example)

    Array
    (
        [0] => Acme\MyBundle\Controller\MyController::myAction
        [1] => Acme
        [2] => My
        [3] => My
        [4] => my
    )
    

    如果输入是Acme\MyBundle\Controller\MyController::myAction

    【讨论】:

    • 我最后一句话的补充:看看@leo的回答:)
    • 不,这是错误的。控制器can be defined as service 因此不必称为“SomethingController”。动作也是如此。
    • 我不明白你的意思。我想用当前选择的动作名称(日志记录)做一些事情。不,是的,这应该通过侦听器或服务来完成。但我不明白你,为什么这是错误的?你能准确吗?
    • 我坚持。它不是太本地化,因为它基于 Symfony2 命名约定!
    • 我认为它是有效的,正则表达式必须适应您正在使用的项目命名约定。如果您没有在所有控制器中使用 Action,只需将其从正则表达式中删除即可。
    【解决方案3】:

    现在,我将它与 Symfony 2.8(和 Symfony3)一起使用:

    <?php
    
    namespace Company\Bundle\AppBundle\Component\HttpFoundation;
    
    use Symfony\Component\HttpFoundation\Request as BaseRequest;
    
    /**
     * Request shortcuts.
     */
    class Request extends BaseRequest
    {
        /**
         * Extract the action name.
         *
         * @return string
         */
        public function getActionName()
        {
            $action = $this->get('_controller');
            $action = explode('::', $action);
    
            // use this line if you want to remove the trailing "Action" string
            //return isset($action[1]) ? preg_replace('/Action$/', '', $action[1]) : false;
    
            return $action[1];
        }
    
        /**
         * Extract the controller name (only for the master request).
         *
         * @return string
         */
        public function getControllerName()
        {
            $controller = $this->get('_controller');
            $controller = explode('::', $controller);
            $controller = explode('\\', $controller[0]);
    
            // use this line if you want to remove the trailing "Controller" string
            //return isset($controller[4]) ? preg_replace('/Controller$/', '', $controller[4]) : false;
    
            return isset($controller[4]) ? $controller[4] : false;
        }
    }
    

    要使用此自定义请求类,您必须在您的 web/app*.php 控制器中“使用”它:

    use Company\Bundle\AppBundle\Component\HttpFoundation\Request;
    // ...
    $request = Request::createFromGlobals();
    // ...
    

    然后在你的控制器中:

    class AppController extends Controller
    {
        /**
         * @Route("/", name="home_page")
         * @Template("")
         *
         * @return array
         */
        public function homePageAction(Request $request)
        {
            $controllerName = $request->getControllerName();
            $actionName = $request->getActionName();
    
            dump($controllerName, $actionName); die();
    
            // ...
        }
    

    将输出:

    AppController.php on line 27:
    "AppController"
    AppController.php on line 27:
    "homePageAction"
    

    您也可以通过RequestStack服务访问这些功能:

    class MyService
    {
        /**
         * @param RequestStack $requestStack
         */
        public function __construct(RequestStack $requestStack)
        {
            $this->requestStack = $requestStack;
        }
    
        public function myService()
        {
            $this->controllerName = $this->requestStack->getMasterRequest()->getControllerName();
            $this->actionName = $this->requestStack->getMasterRequest()->getActionName();
    
            // ...
        }
    

    【讨论】:

    • 如何获取控制器中的所有操作?
    • 请提出一个新问题。
    【解决方案4】:

    如果您使用 Controller as a Service,那么架构会有所不同:

    $request-&gt;attributes-&gt;get('_controller'); 将返回“service_id:createAction”

    两种模式的可能解决方案:

    $controller = $request->attributes->get('_controller');
    $controller = str_replace('::', ':', $controller);
    list($controller, $action) = explode(':', $controller);
    

    【讨论】:

      【解决方案5】:

      在所有版本的 symfony 中,没有 $request 或容器、服务或其他任何东西......,直接在你的方法中

      public function myMethod(){
         $methodName = __METHOD__;
         return $methodName;
      }
      
      // return App\Controller\DefaultController::myMethod
      
      public function mySecondMethod(){
         $methodName = explode('::', __METHOD__);
         return $methodName[1];
      }
      
      // return mySecondMethod
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-19
        • 2015-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多