Hello dear habrazhiteli.
More recently, Zend Framework 2 was released. However, studying it is complicated by the lack of Russian documentation and a single community. Also in the second branch of this framework, a lot of innovations and buns appeared, about which the usual PHP programmer had never even heard of. But they can be studied especially without sweating. But to understand how ZF2 works without an understanding of the logic of its MVC system is rather difficult. Therefore, I decided to make a translation from the official site of this particular section. And so let's start.
MVC in Zend Framework 2
Zend \ Mvc is a completely new implementation of the MVC system for the Zend Framework 2. The focus was on performance and flexibility.
')
The MVC layer is built on the basis of the following components:
- Zend \ ServiceManager - Zend Framework provides a variety of different services defined in Zend \ Mvc \ Service. ServiceManager creates and configures an instance of your application and workflow.
- Zend \ EventManager - MVC are events. This component is used everywhere. For the initial loading of the application, return of responses (response) and requests (request), settings and receiving routes (routes), as well as for processing (render) scripts of the view (views).
- Zend \ Http is a special request and response object. Used with Zend \ Stdlib \ DispatchableInterface. All controllers are “dispatch” objects.
The MVC layer uses the following auxiliary components:
- Zend \ Mvc \ Router - contains classes for routing requests. In other words, forwards requests to the correct controllers.
- Zend \ Http \ PhpEnvironment — provides a set of object decorators for HTTP requests and responses that inject requests into the current environment (including GET and POST parameters, HTTP headers).
- Zend \ Mvc \ Controller - a set of abstract controller classes with basic functionality, such as creating events, scheduling actions, etc.
- Zend \ Mvc \ Service is the ServiceManager set of factories and definitions for various application processes.
- Zend \ Mvc \ View - provides standard visualization of view scripts, registration helpers and much more. It also provides various listeners who “bind” the MVC workflow, providing features such as automatic resolution of template names, automatic creation of a view model and injection, etc.
The starting point for MVC operation is the Zend \ Mvc \ Application object (hereinafter referred to as the Application). The main responsibilities of which are the initial loading of resources, sending (routing) requests, receiving and sending controllers corresponding to the routing.
Basic application structure
application_root/ config/ application.config.php autoload/ global.php local.php
The file public / index.php is responsible for redirecting all user requests to the site. It then receives an array of application settings, located in config / application.config.php. After it launches the Application (Application) by calling the run () function, which processes requests and eventually sends the result back to the user.
The “config” settings directory contains the necessary settings used in ZendModuleManager for loading modules and merging configurations (database connection settings, menus, ACL, etc.). More on what was said a little later.
The vendor subdirectory contains any third-degree (auxiliary, third-party) library modules necessary to ensure the health of your application. For example, Zend Framework 2 itself, user libraries, or other auxiliary libraries of various projects can be placed there directly. Libraries and modules located in this “vendor” subdirectory should not be changed in any way, should not differ from the original, they should not be performed on any actions from the application or third-party programs.
The “module” directory contains one or more modules providing the main functionality of your application.
Basic module structure
Module content can be absolutely anything: PHP code, functional MVC structures, library codes, view scripts, public (public) resources, such as images, CSS style sheets, JavaScript code, etc. The only requirement is that it is not mandatory - the module must act as a namespace (namespace) and contain the class Module.php within this namespace. This class is necessary for the normal operation of Zend \ ModuleManager and a number of other tasks.
It is recommended to adhere to the following structure when creating a module:
module_root<named-after-module-namespace>/ Module.php autoload_classmap.php autoload_function.php autoload_register.php config/ module.config.php public/ images/ css/ js/ src/ <module_namespace>/ <code files> test/ phpunit.xml bootstrap.php <module_namespace>/ <test code files> view/ <dir-named-after-module-namespace>/ <dir-named-after-a-controller>/ <.phtml files>
Because the module is a namespace, the root directory of the module is that namespace. The namespace can include a vendor membership prefix. For clarity, the module provides the basic functionality for the user "User", developed by the Zend team may be called (preferably, but not necessarily) "ZendUser" - this is also the name of the module root folder and namespace at the same time. File Module.php, located immediately in the root folder of the module will already be in the namespace of the module. See the example below:
namespace ZendUser; class Module { }
If the init () method is defined, it will be invoked by a Zend \ ModuleManager listener, after the class has been loaded, and the default instance manager is passed. This approach allows you to create special event listeners. BUT! Be careful with the init () method! It is called for each module for each request and should be used exclusively for “lightweight” tasks, such as registering listeners.
The same applies to the onBootstrap () method, which accepts an instance of the MvcEvent object and is called for each module on each request.
Three autoload _ *. Php files are optional but desirable. They provide the following:
- autoload_classmap.php
Returns an array of class maps containing pairs class name / file name. Class names are determined using the magic constant __DIR__). - autoload_function.php
Returns a callback function that can be passed to spl_autoload_register (). Typically, the callback function uses the map returned in autoload_classmap.php. - autoload_register.php
Registers a callback function. As a rule, it is in autoload_function.php.
These three files provide default loading of classes that are in the module without using Zend \ ModuleManager. For example, to use the module outside of ZF2.
The “config” directory should contain various specific module settings. These settings can be in any format that supports Zend \ Config. It is advisable to use the name “module.format” for the main configuration file. For example, for a configuration file in PHP format, the name of the main configuration file should be: module.config.php. As a rule, you will have to create configuration files for routing and dependency injection.
The “src” directory should be compatible with the PSR-0 format and contain the main module code. At a minimum, it should contain a subdirectory named after the module namespace (the root folder of the module). However, it may contain code with different namespaces, if necessary.
The “test” directory should contain your unit tests. As a rule, they are written using PHPUnit and contain files related to its configuration.
The “public” directory is used for publicly available resources. These can be images, CSS, JavaScript, etc. Fully at the discretion of the developer.
The "view" directory contains view scripts associated with various controllers.
Initial application download
The application has six main dependencies:
- Configuration - usually an array or object Traversable
- ServiceManager Instance
- An instance of EventManager, which by default is “born” from the ServiceManager, by specifying the name of the service “EventManager”
- An instance of the ModuleManager, which by default is “born” from the ServiceManager, by specifying the name of the service “ModuleManager”
- Request instance, which is “born” by default from the ServiceManager, by specifying the Request service name
- Instance Response, which by default is “born” from the ServiceManager, by specifying the name of the Response service
The above may be implemented upon initialization:
use Zend\EventManager\EventManager; use Zend\Http\PhpEnvironment; use Zend\ModuleManager\ModuleManager; use Zend\Mvc\Application; use Zend\ServiceManager\ServiceManager; $config = include 'config/application.config.php'; $serviceManager = new ServiceManager(); $serviceManager->setService('EventManager', new EventManager()); $serviceManager->setService('ModuleManager', new ModuleManager()); $serviceManager->setService('Request', new PhpEnvironmentRequest()); $serviceManager->setService('Response', new PhpEnvironmentResponse()); $application = new Application($config, $serviceManager);
After doing all that has been described above, you have a choice of two actions.
First: You can start downloading the application (bootstrap). In the default implementation, it looks like this:
- A default listener for routing is attached: Zend \ Mv \ cRouteListener
- A default listener for dispatch is added: Zend \ Mvc \ DispatchListener
- A ViewManager listener joins: Zend \ Mvc \ View \ ViewManager
- Triggers a bootstrap event.
If you do not need to perform these actions, you can set alternatives yourself by extending the Application class and / or simply writing the necessary code.
Second: Just start the application by calling the run () method. This method will do the following:
- will trigger the event "route"
- event "dispatch" will work
- and depending on the performance of the previous two, the “render” event may trigger
- after completing the above, the “finish” event will fire and a copy of the response will be returned.
If errors occur during the execution of the “route” or “dispatch” events, the “dispatch.error” event will be triggered.
For a start, it seems that you need to remember a lot of information to launch the application, so we do not list all the available services. For starters, using ServiceManager will be quite sufficient.
use Zend\Loader\AutoloaderFactory; use Zend\Mvc\Service\ServiceManagerConfig; use Zend\ServiceManager\ServiceManager;
Very quickly you will notice that you have a very flexible system in your hands with lots of different settings. Using ServiceManager you get control over other available services, their initialization and dependency injection. Using EventManager you get the opportunity to intercept any events occurring in the application (“bootstrap”, “route”, “dispatch”, “dispatch.error”, “render”, “finish”), at any time and in any place that allows you to create their processes in the application if necessary.
Initial load of modular application
The approach described earlier works. But the question arises, where did the application settings come from? It is logical to assume that the settings are taken directly from the module itself. And how then to get these settings at your disposal?
The answer to these questions is Zend \ ModuleManager \ ModuleManager. First, this component allows you to specify where the modules are located. It then finds each module and initializes it. Module classes are linked by various listeners in the ModuleManager to provide configuration, settings, listeners, and more. If it seems difficult to you, then this is an erroneous assumption.
Configuring Module Manager
At first we will be engaged in the Module Manager setup. Just tell the Module Manager which modules you need to load, and if necessary, you can also specify the settings for the module listeners.
Now let's recall the application.config.php file described earlier. Set the settings as follows:
<?php
To add modules, you just need to add elements to the array of modules.
Each Module class Module must define a getConfig () method. It should return an array or a Traversable object, such as Zend \ Config \ Config. Consider an example:
namespace ZendUser; class Module { public function getConfig() { return include __DIR__ . '/config/module.config.php' } }
There are also a number of methods that can be defined to perform tasks such as autoloading settings, provision of services from the ServiceManager, load event listeners, etc. For more information, refer to the ModuleManager documentation.
findings
The ZF2 MVC layer is incredibly flexible, making it easy to create modules and workflows in your application using the ServiceManager and EventManager. The ModuleManager is an easy and simple approach to the issue of a modular architecture that encourages pure separation of interests and code reuse.
Links
More information can be found with the documentation on the website of the
Ukrainian community ZF2 .
Original article