MVC Applications ================ All the hard work behind orchestrating the operation of MVC in Phalcon is normally done by :doc:`Phalcon\\Mvc\\Application <../api/Phalcon_Mvc_Application>`. This component encapsulates all the complex operations required in the background, instantiating every component needed and integrating it with the project, to allow the MVC pattern to operate as desired. Single or Multi Module Applications ----------------------------------- With this component you can run various types of MVC structures: Single Module ^^^^^^^^^^^^^ Single MVC applications consist of one module only. Namespaces can be used but are not necessary. An application like this would have the following file structure: .. code-block:: php single/ app/ controllers/ models/ views/ public/ css/ img/ js/ If namespaces are not used, the following bootstrap file could be used to orchestrate the MVC flow: .. code-block:: php registerDirs( [ "../apps/controllers/", "../apps/models/", ] ); $loader->register(); $di = new FactoryDefault(); // Registering the view component $di->set( "view", function () { $view = new View(); $view->setViewsDir("../apps/views/"); return $view; } ); $application = new Application($di); try { $response = $application->handle(); $response->send(); } catch (\Exception $e) { echo $e->getMessage(); } If namespaces are used, the following bootstrap can be used: .. code-block:: php registerNamespaces( [ "Single\\Controllers" => "../apps/controllers/", "Single\\Models" => "../apps/models/", ] ); $loader->register(); $di = new FactoryDefault(); // Register the default dispatcher's namespace for controllers $di->set( "dispatcher", function () { $dispatcher = new Dispatcher(); $dispatcher->setDefaultNamespace("Single\\Controllers"); return $dispatcher; } ); // Register the view component $di->set( "view", function () { $view = new View(); $view->setViewsDir("../apps/views/"); return $view; } ); $application = new Application($di); try { $response = $application->handle(); $response->send(); } catch (\Exception $e) { echo $e->getMessage(); } Multi Module ^^^^^^^^^^^^ A multi-module application uses the same document root for more than one module. In this case the following file structure can be used: .. code-block:: php multiple/ apps/ frontend/ controllers/ models/ views/ Module.php backend/ controllers/ models/ views/ Module.php public/ css/ img/ js/ Each directory in apps/ have its own MVC structure. A Module.php is present to configure specific settings of each module like autoloaders or custom services: .. code-block:: php registerNamespaces( [ "Multiple\\Backend\\Controllers" => "../apps/backend/controllers/", "Multiple\\Backend\\Models" => "../apps/backend/models/", ] ); $loader->register(); } /** * Register specific services for the module */ public function registerServices(DiInterface $di) { // Registering a dispatcher $di->set( "dispatcher", function () { $dispatcher = new Dispatcher(); $dispatcher->setDefaultNamespace("Multiple\\Backend\\Controllers"); return $dispatcher; } ); // Registering the view component $di->set( "view", function () { $view = new View(); $view->setViewsDir("../apps/backend/views/"); return $view; } ); } } A special bootstrap file is required to load a multi-module MVC architecture: .. code-block:: php set( "router", function () { $router = new Router(); $router->setDefaultModule("frontend"); $router->add( "/login", [ "module" => "backend", "controller" => "login", "action" => "index", ] ); $router->add( "/admin/products/:action", [ "module" => "backend", "controller" => "products", "action" => 1, ] ); $router->add( "/products/:action", [ "controller" => "products", "action" => 1, ] ); return $router; } ); // Create an application $application = new Application($di); // Register the installed modules $application->registerModules( [ "frontend" => [ "className" => "Multiple\\Frontend\\Module", "path" => "../apps/frontend/Module.php", ], "backend" => [ "className" => "Multiple\\Backend\\Module", "path" => "../apps/backend/Module.php", ] ] ); try { // Handle the request $response = $application->handle(); $response->send(); } catch (\Exception $e) { echo $e->getMessage(); } If you want to maintain the module configuration in the bootstrap file you can use an anonymous function to register the module: .. code-block:: php registerModules( [ "frontend" => function ($di) use ($view) { $di->setShared( "view", function () use ($view) { $view->setViewsDir("../apps/frontend/views/"); return $view; } ); }, "backend" => function ($di) use ($view) { $di->setShared( "view", function () use ($view) { $view->setViewsDir("../apps/backend/views/"); return $view; } ); } ] ); When :doc:`Phalcon\\Mvc\\Application <../api/Phalcon_Mvc_Application>` have modules registered, always is necessary that every matched route returns a valid module. Each registered module has an associated class offering functions to set the module itself up. Each module class definition must implement two methods: registerAutoloaders() and registerServices(), they will be called by :doc:`Phalcon\\Mvc\\Application <../api/Phalcon_Mvc_Application>` according to the module to be executed. Application Events ------------------ :doc:`Phalcon\\Mvc\\Application <../api/Phalcon_Mvc_Application>` is able to send events to the :doc:`EventsManager ` (if it is present). Events are triggered using the type "application". The following events are supported: +---------------------+--------------------------------------------------------------+ | Nom d'évt | Triggered | +=====================+==============================================================+ | boot | Executed when the application handles its first request | +---------------------+--------------------------------------------------------------+ | beforeStartModule | Before initialize a module, only when modules are registered | +---------------------+--------------------------------------------------------------+ | afterStartModule | After initialize a module, only when modules are registered | +---------------------+--------------------------------------------------------------+ | beforeHandleRequest | Before execute the dispatch loop | +---------------------+--------------------------------------------------------------+ | afterHandleRequest | After execute the dispatch loop | +---------------------+--------------------------------------------------------------+ The following example demonstrates how to attach listeners to this component: .. code-block:: php setEventsManager($eventsManager); $eventsManager->attach( "application", function (Event $event, $application) { // ... } ); External Resources ------------------ * `MVC examples on Github `_