The document discusses dependency injection and different approaches to implementing it in PHP applications. It provides examples of using Zend Framework, Zend Application, and Symfony's dependency injection container to configure and inject dependencies into classes without hard-coding the dependencies. The examples show how to define services and dependencies in configuration files and inject them into controllers and other classes.
8. Zend_Application & Dependency Injection class My_Application_Resource_Service_UserService extends Zend_Application_Resource_ResourceAbstract { //[.....] } class My_Application_Resource_Service_PostService extends Zend_Application_Resource_ResourceAbstract { //[.....] } class My_Application_Resource_Service_ArticleService extends Zend_Application_Resource_ResourceAbstract { //[.....] } class My_Application_Resource_Service_RoleService extends Zend_Application_Resource_ResourceAbstract { //[.....] } //[.....] //[.....] //[.....]
9. Zend_Application & Dependency Injection class Zend_Application_Resource_Log extends Zend_Application_Resource_ResourceAbstract { //[.....] /** * Defined by Zend_Application_Resource_Resource * * @return Zend_Log */ public function init() { return $this ->getLog(); } //[.....] public function getLog() { if (null === $this ->_log) { $options = $this ->getOptions(); $log = Zend_Log::factory( $options ); $this ->setLog( $log ); } return $this ->_log; } }
10. Конфигурация вместо кода < service id = "log" class = "Zend_Log" constructor = "factory" > < argument type = "collection" > < argument key = "file" type = "collection" > < argument key = "writerName" > Stream </ argument > < argument key = "writerParams" type = "collection" > < argument key = "stream" > /var/log/myapp.log </ argument > </ argument > </ argument > </ argument > </ service > < service id = "log" class = "Zend_Log" > < call method = "addWriter" > < argument type = "service" > < service class = "Zend_Log_Writer_Stream" > < argument > /var/log/myapp.log </ argument > </ service > </ argument > </ call > </ service >
11. Dependency Injection — A specific form of Inversion of Control (IOC) Взято из ®Wikipedia, the free encyclopedia Внедрение зависимости — Специфическая форма «обращения контроля»
13. PHP DI Containers Symfony Dependency Injection Yadif_Container Seasar DI Container (S2Container) Phemto Xyster_Container TYPO3 ...........
14. Symfony DI Container Поддержка XML, YAML, PHP и INI конфигураций Ленивая загрузка Constructor and Method Injection Shared/NotShared ресурсы Конфигураторы Алиасы
15. Замена контейнера require_once 'Zend/Application.php' ; require_once 'sfServiceContainerBuilder.php' ; require_once 'sfServiceContainerLoaderFileXml.php' ; //Create Container and load configuration from file $container = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileXml($container); $loader ->load(APPLICATION_PATH . '/configs/dependencies.xml' ); // Create application, bootstrap, and run $application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $application ->getBootstrap()->setContainer( $container ); $application ->bootstrap() ->run();
16. Dependencies.xml <? xml version = "1.0" encoding = "UTF-8" ?> < container xmlns = "http://symfony-project.org/2.0/container" > < services > < service id = "userMapper" class = "UserMapperImpl" /> < service id = "PostMapper" class = "PostMapperImpl" /> < service id = "CommentMapper" class = "CommentMapperImpl" /> < service id = "postService" class = "PostServiceImpl" > < call method = "setUserMapper" > < argument type = "service" id = "userMapper" /> </ call > < call method = "setPostMapper" > < argument type = "service" id = "postMapper" /> </ call > < call method = "setCommentMapper" > < argument type = "service" id = "commentMapper" /> </ call > </ service > < service id = "userService" class = "UserServiceImpl" > < call method = "setUserMapper" > < argument type = "service" id = "userMapper" /> </ call > </ service > </ services > </ container >
21. Транзакции Транзакции недоступны в сервисном слое в нашей реализации Транзакции это уровень сервисов. Может быть несколько источников данных.
22. Общий интерфейс транзакций interface TransactionManager { /** * Start a new transaction * @return unknown_type */ public function beginTransaction(); /** * Commit the current transaction * @return unknown_type */ public function commit(); /** * Rollback the current transcation * @return unknown_type */ public function rollback(); }
23. Использование нескольких менеджеров транзакций class MultipleTransactionManager implements TransactionManager { private $tms = array (); public function setTransactionManagers( array $tms ) { $this ->tms = $tms ; return $this ; } public function beginTransaction() { /* @var $tm TransactionManager */ foreach ( $this ->tms as $tm ) { $tm ->beginTransaction(); } } //[.....] }
27. Динамические прокси class SomeClass { public function someMethod() {} } class __GeneratedDynamicProxy__ extends SomeClass { private $proxyManager ; public function someMethod() { return $this ->proxyManager->invoke( new ReflectionMethod( get_parent_class( $this ), __FUNCTION__ )); } }
28. Добавим Аннотаций public function someMethod() { $this ->log(__METHOD__ . ' start' ); if ( $this ->user->role != 'ROLE_ADMIN' ) { throw new SecuredException( $this ->user->role); } $tm = $this ->tm; $tm ->beginTransaction(); try { doBusiness(); $tm- >commit(); } catch (Exception $e ) { $tm ->rollback(); throw $e ; } $this ->log(__METHOD__ . ' end' ); } /** * Some business method * @Transactional * @Log * @Secured ROLE_ADMIN */ public function someMethod() { doBusiness(); }
29. Хорошая архитектура — Простота конфигурации < service id = "actionHelperStack" class = "Zend_Controller_Action_HelperBroker" constructor = "getStack" > < call method = "push" > < argument type = "service" > < service class = "Zend_Controller_Action_Helper_ViewRenderer" > < argument type = "service" id = "view" /> </ service > </ argument > </ call > < call method = "push" > < argument type = "service" > < service class = "My_Controller_Action_Helper_DI" /> </ argument > </ call > </ service >
Editor's Notes
* Instead of your program running the system, the system runs your program * Controller