Componente Despachador

Resumen
Phalcon\Mvc\Dispatcher es el componente responsable de instanciar los controladores y ejecutar las acciones pertinentes en ellos en una aplicación MVC. Despachar es el proceso de tomar el objeto de solicitud, extraer el nombre del módulo, el nombre de controlador, el nombre de la acción, y los parámetros opcionales que contenga, y luego instanciar un controlador y llamar una acción de ese controlador.
<?php
use Phalcon\Di;
use Phalcon\Mvc\Dispatcher;
$container = new Di();
$dispatcher = new Dispatcher();
$dispatcher->setDI($container);
$dispatcher->setControllerName("posts");
$dispatcher->setActionName("index");
$dispatcher->setParams([]);
$controller = $dispatcher->dispatch();
Métodos
public function callActionMethod(
mixed $handler,
string $actionMethod,
array $params = []
)
Llama a un método de acción con un manejador y parámetros
public function dispatch(): object | bool
Procesa el resultado del enrutador llamando a la(s) acción(es) apropiadas del controlador incluyendo cualquier dato de enrutado o parámetros inyectados. Devuelve la clase manejadora despachada (el Controlador para el despachamiento Mvc o una Tarea para el despachamiento CLI) o false
si ocurre una excepción y la operación se detiene devolviendo false
en el manejador de la excepción. Lanza Exception
si tiene lugar una excepción no capturada o manejada durante el proceso de despacho.
public function forward(
array $forward
): void
Reenvía el flujo de ejecución a otro controlador/acción.
<?php
use Phalcon\Events\Event;
use Phalcon\Mvc\Dispatcher;
use App\Back\Bootstrap as Back;
use App\Front\Bootstrap as Front;
$modules = [
"frontend" => [
"className" => Front::class,
"path" => __DIR__ . "/app/Modules/Front/Bootstrap.php",
"metadata" => [
"controllersNamespace" => "App\Front\Controllers",
],
],
"backend" => [
"className" => Back::class,
"path" => __DIR__ . "/app/Modules/Back/Bootstrap.php",
"metadata" => [
"controllersNamespace" => "App\Back\Controllers",
],
],
];
$application->registerModules($modules);
$eventsManager = $container->getShared("eventsManager");
$eventsManager->attach(
"dispatch:beforeForward",
function (
Event $event,
Dispatcher $dispatcher,
array $forward
) use ($modules) {
$metadata = $modules[$forward["module"]]["metadata"];
$dispatcher->setModuleName(
$forward["module"]
);
$dispatcher->setNamespaceName(
$metadata["controllersNamespace"]
);
}
);
// Forward
$this->dispatcher->forward(
[
"module" => "backend",
"controller" => "posts",
"action" => "index",
]
);
public function getActionName(): string
Obtiene el nombre de la última acción despachada
public function getActionSuffix(): string
Obtiene el sufijo de acción por defecto
public function getActiveController(): ControllerInterface
Devuelve el controlador activo en el despachador
public function getActiveMethod(): string
Devuelve el método actual a ser ejecutado en el despachador
public function getBoundModels(): array
Devuelve los modelos vinculados de la instancia del enlazador
<?php
use Phalcon\Mvc\Dispatcher;
/**
* @property Dispatcher $dispatcher
*/
class InvoicesController extends Controller
{
public function viewAction(Invoices $invoice)
{
$boundModels = $this
->dispatcher
->getBoundModels()
;
}
}
public function getControllerClass(): string
Posible nombre de la clase del controlador que será localizada para despachar la petición
public function getControllerName(): string
Obtiene el nombre del último controlador despachado
public function getDefaultNamespace(): string
Devuelve el espacio de nombres por defecto
public function getHandlerClass(): string
Posible nombre de clase que será localizada para despachar la petición
public function getHandlerSuffix(): string
Obtiene el sufijo del manejador por defecto
public function getLastController(): ControllerInterface
Devuelve el último controlador despachado
public function getModelBinder(): BinderInterface | null
Obtiene el enlazador de modelos
public function getModuleName(): string
Obtiene el módulo donde está la clase del controlador
public function getNamespaceName(): string
Obtiene el espacio de nombres a anteponer al nombre del manejador actual
public function getParam(
mixed $param,
string | array $filters = null,
mixed $defaultValue = null
): mixed
Obtiene un parámetro por su nombre o índice numérico
public function getParams(): array
Obtiene los parámetros de la acción
public function getPreviousActionName(): string
Obtiene el nombre de la acción despachada anterior
public function getPreviousControllerName(): string
Obtiene el nombre del controlador despachado anterior
public function getPreviousNamespaceName(): string
Obtiene el espacio de nombres despachado anterior
public function getReturnedValue(): mixed
Devuelve el valor devuelto por la última acción despachada
public function hasParam(
mixed $param
): bool
Comprueba si un parámetro existe
public function isFinished(): bool
Comprueba si el bucle de despachado se ha terminado o tiene más controladores/tareas pendientes de despachar
public function setActionName(
string $actionName
): void
Establece el nombre de la acción a despachar
public function setActionSuffix(
string $actionSuffix
): void
Establece el sufijo de acción por defecto
public function setControllerName(
string $controllerName
)
Establece el nombre del controlador a despachar
public function setControllerSuffix(
string $controllerSuffix
)
Establece el sufijo de controlador por defecto
public function setDefaultAction(
string $actionName
): void
Establece el nombre de acción predeterminado
public function setDefaultController(
string $controllerName
)
Establece el nombre predeterminado del controlador
public function setDefaultNamespace(
string $namespaceName
): void
Establece el espacio de nombres por defecto
public function setHandlerSuffix(
string $handlerSuffix
): void
Establece el sufijo por defecto del manejador
public function setModelBinder(
BinderInterface $modelBinder,
mixed $cache = null
): DispatcherInterface
Habilita el enlazado de modelos durante el despacho
$container->set(
'dispatcher',
function() {
$dispatcher = new Dispatcher();
$dispatcher->setModelBinder(
new Binder(),
'cache'
);
return $dispatcher;
}
);
public function setModuleName(
string $moduleName
): void
Establece el módulo donde está el controlador (sólo informativo)
public function setNamespaceName(
string $namespaceName
): void
Establece el espacio de nombres donde está la clase controlador
public function setParam(
mixed $param,
mixed $value
): void
Establece un parámetro por su nombre o índice numérico
public function setParams(
array $params
): void
Establece los parámetros de la acción a despachar
public function setReturnedValue(
mixed $value
): void
Establece manualmente el último valor devuelto por una acción
public function wasForwarded(): bool
Comprueba si la acción ejecutada actual fue reenviada desde otra
Bucle de Despacho
Es un proceso importante que tiene mucho por hacer con el flujo MVC en sí mismo, especialmente con la parte del controlador. El trabajo ocurre dentro del despachador del controlador. Los ficheros del controlador son leídos, cargados e instanciados. Luego se ejecutan las acciones requeridas. Si una acción reenvía el flujo a otro controlador/acción, el despachador del controlador empieza de nuevo. Para ilustrar mejor esto, el siguiente ejemplo muestra aproximadamente el proceso ejecutado en el componente Phalcon\Mvc\Dispatcher.
<?php
$finished = false;
while (true !== $finished) {
$finished = true;
$controllerClass = $controllerName . 'Controller';
$controller = new $controllerClass();
call_user_func_array(
[
$controller,
$actionName . 'Action',
],
$params
);
$finished = true;
}
El el código anterior, estamos calculando el nombre del controlador, instanciándolo y llamando a la acción relevante. Después de eso terminamos el bucle. El ejemplo está muy simplificado y carece de validaciones, filtros y comprobaciones adicionales, pero demuestra el flujo normal de operación dentro del despachador.
Reenvío
El bucle de despacho le permite reenviar el flujo de ejecución a otro controlador/acción. Esto es muy útil en situaciones donde comprobamos si el usuario tiene acceso a ciertas áreas, y si no se le permite es reenviado a otros controladores y acciones, lo que le permite reutilizar código.
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
/**
* @property Dispatcher $dispatcher
*/
class InvoicesController extends Controller
{
public function saveAction($year, $postTitle)
{
// ...
$this->dispatcher->forward(
[
'controller' => 'invoices',
'action' => 'list',
]
);
}
}
NOTA: Tenga en cuenta que ejecutar forward
no es lo mismo que hacer una redirección HTTP. Aunque producen el mismo resultado, la ejecución de forward
no recargará la página actual, mientras que la redirección HTTP necesita dos peticiones para completar el proceso.
Ejemplos:
<?php
$this->dispatcher->forward(
[
'action' => 'search',
]
);
Reenvía el flujo a otra acción en el controlador actual
<?php
$this->dispatcher->forward(
[
'action' => 'search',
'params' => [1, 2, 3],
]
);
Reenvía el flujo a otra acción en el controlador actual, pasando parámetros
Una acción forward
acepta los siguientes parámetros:
Parámetro |
Descripción |
controller |
Un nombre de controlador válido al que reenviar. |
action |
Un nombre de acción válido al que reenviar. |
params |
Un vector de parámetros para la acción. |
namespace |
Un espacio de nombres válido del que forma parte el controlador. |
Parámetros
Preparación
Usando eventos o puntos de enganche disponibles mediante Phalcon\Mvc\Dispatcher, puede fácilmente ajustar su aplicación para aceptar cualquier esquema de URL que se adapte a su aplicación. Esto es particularmente útil cuando actualiza su aplicación y quiere transformar algunas URLs antiguas. Por ejemplo, podría querer que sus URLs fuesen:
https://domain.com/controller/key1/value1/key2/value
Ya que los parámetros se pasan a la acciones en el orden en el que fueron definidos en la URL, puede transformarlos al esquema deseado:
<?php
use Phalcon\Dispatcher;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
$container->set(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeDispatchLoop',
function (Event $event, $dispatcher) {
$params = $dispatcher->getParams();
$keyParams = [];
foreach ($params as $index => $value) {
if ($index & 1) {
$key = $params[$index - 1];
$keyParams[$key] = $value;
}
}
$dispatcher->setParams($keyParams);
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
Si el esquema deseado es:
https://example.com/controller/key1:value1/key2:value
puede usar el siguiente código:
<?php
use Phalcon\Dispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
$container->set(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeDispatchLoop',
function (Event $event, $dispatcher) {
$params = $dispatcher->getParams();
$keyParams = [];
foreach ($params as $param) {
$parts = explode(':', $param);
$key = $parts[0];
$value = $parts[1];
$keyParams[$key] = $value;
}
$dispatcher->setParams($keyParams);
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
Obtención
Cuando una ruta proporciona parámetros con nombres puede obtenerlos en un controlador, vista o cualquier otro componente que extienda Phalcon\Di\Injectable
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
/**
* @property Dispatcher $dispatcher
*/
class InvoicesController extends Controller
{
public function viewAction()
{
$invoiceId = $this
->dispatcher
->getParam('invoiceId', 'int')
;
$filter = $this
->dispatcher
->getParam('filter', 'string')
;
// ...
}
}
En el ejemplo anterior, obtenemos invoiceId
como primer parámetro pasado y automáticamente se sanea como integer
. El segundo parámetro es filter
, que es saneado como string
Acciones
También puede definir un esquema arbitrario para acciones antes
de que el bucle de despacho sea invocado.
Camelizar Nombres
SI la URL original es
https://example.com/admin/invoices/show-unpaid
y por ejemplo quiere camelizar show-unpaid
a ShowUnpaid
, se puede usar para lograrlo beforeDispatchLoop
.
<?php
use Phalcon\Text;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager as Manager;
$container->set(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeDispatchLoop',
function (Event $event, $dispatcher) {
$dispatcher->setActionName(
Text::camelize(
$dispatcher->getActionName()
)
);
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
Filtro Extensiones de Fichero
Si la URL original siempre contiene una extensión .php
:
https://example.com/admin/invoices/show-unpaid.php
https://example.com/admin/invoices/index.php
Puede eliminarla antes de despachar la combinación controlador/acción:
<?php
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
$container->set(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeDispatchLoop',
function (Event $event, $dispatcher) {
$action = $dispatcher->getActionName();
$action = preg_replace('/\.php$/', '', $action);
$dispatcher->setActionName($action);
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
NOTA: El código anterior se puede usar tal cual o ajustado para ayudar con las transformaciones de URL antiguas u otros casos de uso donde necesitamos manipular el nombre de la acción.
Inyección de Modelo
Hay instancias en las que puede querer inyectar automáticamente instancias del modelo que se han emparejado con los parámetros pasados en la URL.
Nuestro controlador es:
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;
/**
* @property View $view
*/
class InvoicesController extends Controller
{
public function viewAction(Invoices $invoice)
{
$this->view->invoice = $invoice;
}
}
viewAction
recibe una instancia del modelo Invoices
. Si intenta ejecutar este método sin ninguna comprobación ni manipulación, la llamada fallará. Sin embargo puede inspeccionar los parámetros pasados antes del bucle de despacho y manipular los parámetros en consecuencia.
<?php
use \Exception;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use \ReflectionMethod;
$container->set(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeDispatchLoop',
function (Event $event, $dispatcher) {
$controllerName = $dispatcher->getControllerClass();
$actionName = $dispatcher->getActiveMethod();
try {
$reflection = new ReflectionMethod(
$controllerName,
$actionName
);
$parameters = $reflection->getParameters();
foreach ($parameters as $parameter) {
$className = $parameter->getClass()->name;
if (is_subclass_of($className, Model::class)) {
$model = $className::findFirstById(
$dispatcher->getParams()[0]
);
$dispatcher->setParams(
[
$model,
]
);
}
}
} catch (Exception $e) {
}
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
En el ejemplo anterior, obtenemos la clase controlador y el método activo desde el despachador. Recorriendo los parámetros, usamos la reflexión para comprobar el método a ejecutar. Calculamos el nombre del modelo y también comprobamos si el parámetro espera un nombre de modelo. Si es así, anulamos el parámetro pasando el modelo encontrado. Si se lanza alguna excepción, podemos manejarla en consecuencia, por ejemplo si la clase o acción no existen, o no se ha encontrado el registro.
El ejemplo anterior se ha simplificado. Puede ajustarlo acorde a sus necesidades e inyectar a una acción cualquier tipo de dependencia o modelo antes de que se ejecute.
El despachador también viene con una opción para manejar esto internamente para todos los modelos pasados en una acción de controlador usando el objeto Phalcon\Mvc\Model\Binder.
<?php
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Model\Binder;
$dispatcher = new Dispatcher();
$dispatcher->setModelBinder(
new Binder()
);
return $dispatcher;
NOTA: El componente Phalcon\Mvc\Model\Binder usa internamente la API de Reflexión de PHP, que consume ciclos de procesamiento adicionales. Por esa razón, tiene la habilidad de usar una instancia de cache
o un nombre de servicio de cache. Para usar esta característica, puede pasar el nombre del servicio de cache o la instancia como segundo argumento en el método setModelBinder()
o sólo pasar la instancia de cache en el constructor Binder
.
También, mediante el uso de Phalcon\Mvc\Model\Binder\BindableInterface en controladores, puede definir la vinculación de los modelos en los controladores base.
En el ejemplo anterior, tenemos un controlador base CrudController
que extiende desde InvoicesController
.
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\View;
/**
* @property View $view
*/
class CrudController extends Controller
{
public function viewAction(Model $model)
{
$this->view->model = $model;
}
}
En InvoicesController
definimos con qué modelo está asociado el controlador. Esto se hace implementando Phalcon\Mvc\Model\Binder\BindableInterface, que hará que el método getModelName()
esté disponible. Este método se usa para devolver el nombre del modelo. Puede devolver una cadena con un nombre de modelo o un vector asociativo donde la clave es el parámetro nombre.
<?php
use Phalcon\Mvc\Model\Binder\BindableInterface;
class InvoicesController extends CrudController implements BindableInterface
{
public static function getModelName()
{
return Invoices::class;
}
}
Al declarar el modelo asociado en InvoicesController
el vinculador (binder) puede comprobar el controlador para el método getModelName()
antes de pasar el modelo definido a la acción view
del padre.
Si la estructura de su proyecto no usa ningún controlador base, por supuesto todavía puede vincular el modelo directamente en la acción del controlador:
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;
/**
* @property View $view
*/
class InvoicesController extends Controller
{
public function showAction(Invoices $invoice)
{
$this->view->invoice = $invoice;
}
}
Actualmente, el vinculador (binder) solo utilizará la clave primaria de los modelos para realizar un findFirst()
. Una ruta de ejemplo para lo anterior podría ser /posts/show/{1}
No-Encontrado (404)
Si se define un Gestor de Eventos, puede usarlo para interceptar excepciones que se muestran cuando el par controlador/acción no se encuentra.
<?php
use Exception;
use Phalcon\Dispatcher;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
use Phalcon\Mvc\Dispatcher\Exception as DispatchException;
$container->setShared(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeException',
function (
Event $event,
$dispatcher,
Exception $exception
) {
// 404
if ($exception instanceof DispatchException) {
$dispatcher->forward(
[
'controller' => 'index',
'action' => 'fourOhFour',
]
);
return false;
}
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
o usar una comprobación de sintaxis alternativa para la excepción.
<?php
use Exception;
use Phalcon\Dispatcher\Exception as DispatcherException;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
$container->setShared(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch:beforeException',
function (
Event $event,
$dispatcher,
Exception $exception
) {
switch ($exception->getCode()) {
case DispatcherException::EXCEPTION_HANDLER_NOT_FOUND:
case DispatcherException::EXCEPTION_ACTION_NOT_FOUND:
// 404
$dispatcher->forward(
[
'controller' => 'index',
'action' => 'fourOhFour',
]
);
return false;
}
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
Podemos mover este método a una clase plugin:
<?php
use Exception;
use Phalcon\Events\Event;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Dispatcher\Exception as DispatchException;
class ExceptionsPlugin
{
public function beforeException(
Event $event,
Dispatcher $dispatcher,
Exception $exception
) {
$action = 'fiveOhThree';
if ($exception instanceof DispatchException) {
$action = 'fourOhFour';
}
$dispatcher->forward(
[
'controller' => 'index',
'action' => $action,
]
);
return false;
}
}
NOTA: Sólo las excepciones producidas por el despachador y las excepciones producidas en la acción ejecutada notifican los eventos beforeExcepcion
. Las excepciones producidas en oyentes o eventos de controlador son redirigidas al último try/catch.
Eventos
Phalcon\Mvc\Dispatcher es capaz de enviar eventos a un Gestor si está presente. Los eventos son disparados usando el tipo dispatch
. Algunos eventos cuando devuelven el booleano false
podrían detener la operación activa. Se soportan los siguientes eventos:
Nombre de evento |
Disparado |
Puede detener |
afterBinding |
Después de que los modelos estén enlazados pero antes de ejecutar la ruta |
Si |
afterDispatch |
Después de ejecutar el método controlador/acción. |
Si |
afterDispatchLoop |
Después de salir del bucle de despacho |
No |
afterExecuteRoute |
Después de ejecutar el método controlador/acción. |
No |
afterInitialize |
Permite inicializar globalmente el controlador en la petición |
No |
beforeDispatch |
Después de entrar en el bucle de despacho. El Despachador sólo conoce la información pasada por el Enrutador. |
Si |
beforeDispatchLoop |
Antes de entrar en el bucle de despacho. El Despachador sólo conoce la información pasada por el Enrutador. |
Si |
beforeException |
Antes de que el despachador lance cualquier excepción |
Si |
beforeExecuteRoute |
Antes de ejecutar el método controlador/acción. El Despachador ha inicializado el controlador y conoce si existe la acción. |
Si |
beforeForward |
Antes de reenviar al método controlador/acción. (Despachador MVC) |
No |
beforeNotFoundAction |
cuando la acción no se ha encontrado en el controlador |
Si |
La aplicación de ejemplo INVO, demuestra cómo puede sacar ventaja del despacho de eventos, implementando un filtro de seguridad con Acl
En el ejemplo siguiente se muestra cómo adjuntar oyentes (listeners) a este componente:
<?php
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
$container->set(
'dispatcher',
function () {
$eventsManager = new Manager();
$eventsManager->attach(
'dispatch',
function (Event $event, $dispatcher) {
// ...
}
);
$dispatcher = new MvcDispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
},
true
);
Un controlador instanciado automáticamente actúa como un oyente para despachar eventos, puede implementar métodos como llamadas de retorno (callbacks):
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class InvoicesController extends Controller
{
public function beforeExecuteRoute(
Dispatcher $dispatcher
) {
// ...
}
public function afterExecuteRoute(
Dispatcher $dispatcher
) {
// ...
}
}
NOTA: Los métodos de oyentes de eventos aceptan un objeto Phalcon\Events\Event como primer parámetro - los métodos en controladores no.
Gestor de Eventos
Puede usar el evento dispatcher::beforeForward
para cambiar los módulos y realizar redirecciones más fácilmente.
<?php
use App\Back\Bootstrap;
use Phalcon\Di;
use Phalcon\Events\Manager;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Events\Event;
$container = new Di();
$modules = [
'backend' => [
'className' => Bootstrap::class,
'path' => '/app/Modules/Back/Bootstrap.php',
'metadata' => [
'controllersNamespace' => 'App\Back\Controllers',
],
],
];
$manager = new Manager();
$manager->attach(
'dispatch:beforeForward',
function (
Event $event,
Dispatcher $dispatcher,
array $forward
) use ($modules) {
$moduleName = $forward['module'];
$metadata = $modules[$moduleName]['metadata'];
$dispatcher->setModuleName($moduleName);
$dispatcher->setNamespaceName(
$metadata['controllersNamespace']
);
}
);
$dispatcher = new Dispatcher();
$dispatcher->setDI($container);
dispatcher->setManager($manager);
$container->set('dispatcher', $dispatcher);
$dispatcher->forward(
[
'module' => 'backend',
'controller' => 'invoices',
'action' => 'index',
]
);
echo $dispatcher->getModuleName();
Personalizado
Se debe implementar la interfaz Phalcon\Mvc\DispatcherInterface para crear su propio despachador.
<?php
namespace MyApp\Mvc
use Phalcon\Mvc\DispatcherInterface;
class MyDispatcher implements DispatcherInterface
{
/**
* Dispatches a handle action taking into account the routing parameters
*/
public function dispatch(): object | bool;
/**
* Forwards the execution flow to another controller/action
*/
public function forward(array $forward): void;
/**
* Gets last dispatched action name
*/
public function getActionName(): string;
/**
* Gets the default action suffix
*/
public function getActionSuffix(): string;
/**
* Returns the active controller in the dispatcher
*/
public function getActiveController(): ControllerInterface;
/**
* Gets last dispatched controller name
*/
public function getControllerName(): string;
/**
* Gets the default handler suffix
*/
public function getHandlerSuffix(): string;
/**
* Returns the latest dispatched controller
*/
public function getLastController(): ControllerInterface;
/**
* Gets a param by its name or numeric index
*
* @param string|array filters
*/
public function getParam($param, $filters = null);
/**
* Gets action params
*/
public function getParams(): array;
/**
* Returns value returned by the latest dispatched action
*/
public function getReturnedValue();
/**
* Check if a param exists
*/
public function hasParam($param): bool;
/**
* Checks if the dispatch loop is finished or has more pendent
* controllers/tasks to dispatch
*/
public function isFinished(): bool;
/**
* Sets the action name to be dispatched
*/
public function setActionName(string $actionName): void;
/**
* Sets the default action suffix
*/
public function setActionSuffix(string $actionSuffix): void;
/**
* Sets the default controller suffix
*/
public function setControllerSuffix(string $controllerSuffix);
/**
* Sets the controller name to be dispatched
*/
public function setControllerName(string $controllerName);
/**
* Sets the default action name
*/
public function setDefaultAction(string $actionName): void;
/**
* Sets the default controller name
*/
public function setDefaultController(string $controllerName);
/**
* Sets the default namespace
*/
public function setDefaultNamespace(string $defaultNamespace): void;
/**
* Sets the default suffix for the handler
*/
public function setHandlerSuffix(string $handlerSuffix): void;
/**
* Sets the module name which the application belongs to
*/
public function setModuleName(string $moduleName): void;
/**
* Sets the namespace which the controller belongs to
*/
public function setNamespaceName(string $namespaceName): void;
/**
* Set a param by its name or numeric index
*
* @param mixed value
*/
public function setParam($param, $value): void;
/**
* Sets action params to be dispatched
*/
public function setParams(array $params): void;
}