A Better Way of Using Dispatcher in Controller or Model ?

This is how I use it now in my custom Library or Model. Is there a better way to use Dispatcher anywhere in my project without having to always reuse $di = \Phalcon\DI::getDefault(); and $dp = $di['dispatcher']; anywhere I need to call getControllerName() ?

function test() {
  $di = \Phalcon\DI::getDefault();
  $dp = $di['dispatcher'];
  return $dp->getControllerName();
} #test

Please provide some snippet code examples when possible. Thank you so much!

Yea, extends Injectable and add your class as a service and you can just access it using $this->dispatcher

Also you are missing public/private/protected keyword.

Hello

If you have a look at what your controller extends it has DI injection available in it by default.

abstract class Controller extends \Phalcon\Di\Injectable

edited Jun '18

I have a trait that can be included in models (and wherever else it's needed) that give a shortcut to the DI. I'm not sure if it's ideal, but it works.

<?PHP
/**
 * This file contains the "DI" trait.
 */

namespace Traits;

/**
 * This trait contains methods for simplifying access to the Dependency Injector.
 */
trait DI{
    /**
     * Shortcut function for accessing the Dependency Injector (DI) and its contents
     * 
     * ####Example usage
     * * `di()` - returns the DI
     * * `di('router)` - returns the router in the DI
     * * `di('router',['user'])` - retrieves the router from the DI, passing 'user' as the first parameter
     * 
     * @param string $thing_in_di **[OPTIONAL]**    If provided, causes the method to return that item in the DI, rather than the DI itself
     * @param array $parameters_for_thing **[OPTIONAL]** If provided, passes the parameters on to the closure method for creating the thing
     * @return mixed result of diBody()
     */
    public function di($thing_in_di=NULL,$parameters_for_thing=NULL){
        return self::diBody($thing_in_di,$parameters_for_thing);
    }

    /**
     * Shortcut function for accessing the DI and its contents, in a static way
     * @param string $thing_in_di **[OPTIONAL]**    If provided, causes the method to return that item in the DI, rather than the DI itself
     * @param array $parameters_for_thing **[OPTIONAL]** If provided, passes the parameters on to the closure method for creating the thing
     * @return mixed result of diBody()
     */
    public static function diStatic($thing_in_di=NULL,$parameters_for_thing=NULL){
        return self::diBody($thing_in_di,$parameters_for_thing);
    }

    /**
     * Body of di() and diStatic() methods
     * @param string $thing_in_di **[OPTIONAL]**    If provided, causes the method to return that item in the DI, rather than the DI itself
     * @param array $parameters_for_thing **[OPTIONAL]** If provided, passes the parameters on to the closure method for creating the thing
     * @return \Phalcon\Di|mixed    Either the DI container, or a particular service
     */
    private static function diBody($thing_in_di=NULL,$parameters_for_thing=NULL){
        if($thing_in_di == NULL){
            return \Phalcon\DI::getDefault();
        }
        else{
            return \Phalcon\DI::getDefault()->get($thing_in_di,$parameters_for_thing);
        }
    }
}

In bootstrap.php, I've set up namespace autoloading to load from the proper traits/ directory.

Then in the model:

use \Traits\DI;

and

$this->di('dispatcher')->getControllerName()

As a side note - you really shouldn't be trying to retrieve the controller name from the model - the model shouldn't care what the controller is.