How to get controller from within controller plugi

2019-07-11 04:05发布

问题:

I am writing a controller plugin in zf2. I use the following method to get controller from within plugin, but it returns null.

$controller = $this->getController()

Any suggestion?

回答1:

There are two options for which you have no controller set in your plugin.

  1. You call the plugin from the plugin manager prior to dispatch, so no controller is set yet
  2. You call the controller inside the plugin during __construct()

For the first one, a typical example is an onBootstrap() method in a module class where obviously you have no controller:

public function onBootstrap($e)
{
  $app = $e->getApplication();
  $sm  = $app->getServiceManager();

  $plugins = $sm->get('ControllerPluginManager');
  $plugin  = $plugins->get('my-plugin');

  // $plugin->getController() === null
}

This seems an obvious example, but there are other occasions where you are mistakenly assuming a controller exists already (for example, during run of the application, at the route phase; the dispatch still has to come).

The second example is because the controller is injected with setter injection. The setter is called after construction. In pseudo code, this happens:

$plugin = new $class;
$plugin->setController($controller);

If you have a plugin like this:

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class MyPlugin extends AbstractPlugin
{
  public function __construct()
  {
    // $this->getController() === null
  }
}

You notice there is no controller set at that phase.



回答2:

Note, this answer was based on my experience with ZF1, and a quick look at the ZF2 code. Check out this answer.

I haven't played with ZF2 yet, but if the dispatch process and plugins are similar to ZF1, a plugin can't access the controller (at least not in a trivial way) as the controller isn't even instantiated for some of the plugin hooks.

Update: Took a quick look at some of the stock ZF2 controller plugins (as I can't seem to find official docs on creating a custom plugin), and see checks like the following:

$controller = $this->getController();
if (!$controller || !method_exists($controller, 'plugin')) {
//...

So it seems like the controller may not be set in some cases. Since the plugins also support (what I understand to be) an event listener, my guess is that they still can be used at various times in the response process, which may be before a controller is assigned.

Hopefully someone who's used ZF2 can come along and set me straight; but perhaps I've at least pointed you in a somewhat reasonable direction.