Question

Is there a way to get the name of the action in a Symfony2 controller?

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

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

}
Was it helpful?

Solution

use:

$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';

OTHER TIPS

I found this snippet (here):

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

which seems to be a promising approach. This regexp actually doesn't work. But it won't be hard to fetch the action name by using strstr(). Works!

And returns (see example)

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

If input was Acme\MyBundle\Controller\MyController::myAction.

Now, I am using this with Symfony 2.8, (and 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;
    }
}

To use this custom request class, you must "use" it in your web/app*.php controllers:

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

Then in your controller:

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();

        // ...
    }

Will output:

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

You can also access these functions through the RequestStack service:

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();

        // ...
    }

If you use Controller as a Service than the schema is different:

$request->attributes->get('_controller'); will return "service_id:createAction"

A possible solution for both schemas:

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

In all version of symfony and without $request or container, service or nothing else... , directly in your method

public function myMethod(){
   $methodName = __METHOD__;
   return $methodName;
}

// return App\Controller\DefaultController::myMethod

public function mySecondMethod(){
   $methodName = explode('::', __METHOD__);
   return $methodName[1];
}

// return mySecondMethod
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top