8
votes

I have an Action method in Foo Controller which requires parameters:

public function fooAction($one, $two) {
    $a = one;
    $b = $two;
}

And I need to forward to that method from the other method of some Boo Controller. And one of those parameters has to be by reference parameter. The only example that the manual has is this:

$result = $this->forward()->dispatch('Boo\Controller\Boo', array('action' => 'boo'));

No any additional parameters. But they write:

$params is an optional array of parameters with which to see a RouteMatch object for purposes of this specific request.

So, I tried:

$result = $this->forward()->dispatch('Boo\Controller\Boo', array(
                                                      'action' => 'boo',
                                                      'one' => &$one,
                                                      'two' => $two,
                                                 ));

But it doesn't work.

Is there any way to pass additional parameters to forward controller?

UPD:

These do not work too:

$result = $this->forward()->dispatch('Boo\Controller\Boo', array(
                                                      'action' => 'boo',
                                                      'params' => array(
                                                          'one' => &$one,
                                                          'two' => $two,
                                                     )));


$result = $this->forward()->dispatch('Boo\Controller\Boo', array(
                                                      'action' => 'boo',
                                                      'options' => array(
                                                          'one' => &$one,
                                                          'two' => $two,
                                                     )));

UPD 2:

I still can't get the functionality I want (to pass parameters with the forward plugin) but I found other solutions. Before calling the forward plugin I set the variables to the Request object and after the forward I get them from the Request in my boo Action of my Boo\Controller\BooController:

// in Foo::fooAction
$this->getRequest()->one = &$one;
$this->getRequest()->two = $two;
$result = $this->forward()->dispatch('Boo\Controller\Boo', array('action' => 'boo'));

// in Boo::booAction
$a = $this->getRequest()->one;
$b = $this->getRequest()->two;

Stupid solution, it will not work with Ajax requests. Still interested how to pass parameters with the forward plugin. OR MAYBE how to get them in the booAction. Because there in no anything in the Request if I pass them with the forward.

UPD 3 and Final:

I finally found where they've decided to hide parameters I pass with the forward plugin. They put them in the RouteMatch object.

- Tryyyy to guess where we've hidden your params... Oh yeeah, they are in the RouteMatch, of course they are there, didn't you think smth else?

And NO ANY info in the forward plugin section of the manual!

To get params, I have to do this in my BooController::booAction:

$param = $this->getEvent()->getRouteMatch()->getParam('nameOfParam');
5
is Boo a valid Controller-Alias? As pointed out by the documentation Boo needs to be either a fully qualified ClassName (e.g.Mymodule\Controller\BooController) or it should be an alias to this controller which you define inside your configurationSam
Yes, it's a fully qualified ClassName, it is 'Boo\Controller\Boo' I have. I wrote like this in the question to make it shorter. Change now to avoid obscurity.Green
This still is only an alias. It's safe to assume you've set up an invokables alias from Boo\Controller\Boo => Boo\Controller\BooController ? Other than that your first approach is the right one. How do you test if the params are present? Are they defined in route-configuration, too? Tihs blogpost uses the functionality you're looking for a lot: michaelgallego.fr/blog/2012/10/06/…Sam

5 Answers

8
votes

You can create a container class and use it in both controllers

in module.conf

public function getServiceConfig()
{
    return array(
        'invokables' => array(
            'my_handy_container'        => 'path\container_class_name',
        )
    );
}

Create a getter in both controllers:

public function getMyHandyContainer()
{
    if (!$this->myHandyContainer) {
        $this->myHandyContainer = $this->getServiceLocator()->get('my_handy_container');
    }
    return $this->myHandyContainer;
}

And call it using:

$myContainer = $this->getMyHandyContainer()->myHandyContainer;
$myContainer->foo = 5; // set something

ZF2 way to pass vars using forward

In the passing method do:

return $this->forward()->dispatch('controller_name', [
    'action' => 'whatever',
    'varname' => $value,
    'varname2' => $value2
]);

In the invoked controller method, do:

$param2 = $this->params()->fromRoute('varname2',false);
12
votes

Why not to use the params plugin?

This works for me:

public function indexAction() {

        $object = new SomeObject();

        return $this->forward()->dispatch('Application\Controller\Index', [
                'action'     => 'show',
                'myObject'   => $object,
        ]);
    }

public function showAction() {

        $object = $this->params('myObject');

        var_dump($object);

        return [];
}
2
votes

Thought I would add another option that works for me.

You can simply pass the params straight through the forward function and use the routeMatch function to access them at the other end.

return $this->forward()
            ->dispatch('Module\Controller\Foo', array(
                                            'action' => 'bas', 
                                             'id' => 6)
                                              );

Passes to Foo Controller, basAction in this method you can then use the following code to access the id param

$myParam = (int) $this->getEvent()->getRouteMatch()->getParam('id');

Not sure if this meets your requirements - but works for me.

1
votes

Thanks for the question, helped me a lot. Found an easy way for getting all params passed to forward()->dispatch(...). In the controller's action method:

$params = $this->params()->fromRoute();

returns array $data as passed as $data into forward()->dispatch($controllerName, $data).

1
votes

Here in the official ZF2 documentation is written exactly how it works:

$params is an optional array of parameters with which to seed a RouteMatch object for purposes of this specific request. Meaning the parameters will be matched by their key to the routing identifiers in the config (otherwise non-matching keys are ignored).

So pass like this:

$params = array(
    'foo' => 'foo',
    'bar' => 'bar'
);
$this->forward()->dispatch('My\Controller', $params)

And then you can get your route match params in your My\Controller like normally:

$foo = $this->params()->fromRoute('foo');
$bar = $this->params()->fromRoute('bar');

For people struggling with accessing parameters within their controller here a nice overview from this CheatSheet.

$this->params()->fromPost('foo');  //POST
$this->params()->fromQuery('foo'); //GET
$this->params()->fromRoute('foo'); //RouteMatch
$this->params()->fromHeader('foo');//Header
$this->params()->fromFiles('foo'); //Uploaded file