www.6766.com对PHP依赖注入的理解实例分析_php技巧_脚本之家

在此个例子中,数据库连接在component中被创建,这种办法是不符合实际的,这样做的话,我们将不可能更正数据库连接参数及数据库类型等部分参数。

本人想,大家只好在应用程序的不在少数地点创建那几个指标。假设您无需依附的机件后,大家又要去代码注入部分移除构造函数中的参数也许是setter方法。为了减轻这一个主题材料,我们再次重回去行使一个大局注册表来创制组件。然而,在创建对象以前,它扩大了一个新的抽象层:

鉴于Phalcon高度解耦,PhalconDI
是框架用来集成别的零器件的必须的有个别,开辟人士也足以利用那一个组件重视注入和管理应用程序中不相同类文件的实例。

//Create the Dependency Injector Container$di = new PhalconDI();//By its class name$di->set("request", 'PhalconHttpRequest');//Using an anonymous function, the instance will lazy loaded$di->set{ return new PhalconHttpRequest;//Registering directly an instance$di->set("request", new PhalconHttpRequest;//Using an array definition$di->set("request", array( "className" => 'PhalconHttpRequest'));

后生可畏种实用和平淡的来消除这几个主题素材,是选用容器的依赖注入,像大家在后面看见的,容器作为全局注册表,使用容器的依赖注入做为生龙活虎种桥梁来解决信任能够使大家的代码耦合度更低,很好的下挫了组件的千头万绪:

为了缓和地点所说的难点,大家需求在行使前创办贰个外表连接,并流入到容器中。就现阶段来说,那看起来是三个很好的解决方案:

在上头的例子中,当向框架央求访谈叁个伸手数据时,它将首先明确容器中是否留存那一个”reqeust”名称的服务。

大略,这些组件达成了 Inversion of Control
格局。基于此,对象不再以构造函数选取参数大概接收setter的办法来贯彻注入,而是一向伸手服务的信赖性注入。那就大大减少了完整程序的复杂,因为独有二个办法用以拿到所急需的多少个构件的信赖关系。别的,这种方式加强了代码的可测验性,进而使它不轻便失误。在容器中注册服务

$di->setParameter("db", 0, array( "host" => "localhost", "username" => "root", "password" => "secret"));

PhalconDI 同期允许服务重用,为了拿到二个生机勃勃度实例化过的劳动,能够动用
getShared(State of Qatar 方法的款式来获得劳动。具体的 PhalconHttpRequest
伏乞示例:

www.6766.com对PHP依赖注入的理解实例分析_php技巧_脚本之家。我们得以行使统意气风发的办法从组件得到二个结构化的全局实例服务能够因此以下二种方法注入到容器:

PhalconDI
提供劳动的延迟加载。除非开荒职员在注入服务的时候一向实例化二个对象,然后存存款和储蓄到容器中。在容器中,通过数组,字符串等方法存款和储蓄的服务都将被延迟加载,即唯有在伸手对象的时候才被开端化。

看Laravel的IoC容器文书档案只是介绍实例,但是从未说原理,以前用MVC框架都未有留意那么些定义,无意中在phalcon的文书档案中看看这些详细的介绍,以为出现转机,复制粘贴过来,首假使漫长未有写东西了,今后确实很懒变得!

如上那二种服务的注册格局发出相通的结果。然后,通过数组定义的,在前面须要的时候,你能够改善服务参数:

更加多关于PHP相关内容感兴趣的读者可查看本站专项论题:《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP运算与运算符用法总括》、《PHP网络编制程序本事总计》、《PHP数组操作技巧大全》、《php字符串用法总括》、《php+mysql数据库操作入门教程》及《php不可胜道数据库操作技艺汇总》

这种工作方法为大家提供了众多亮点:

class SomeComponent { protected $_connection; /** * Sets the connection externally */ public function setConnection { $this->_connection = $connection; } public function someDbTask() { $connection = $this->_connection; // ... }}$some = new SomeComponent();//Create the connection$connection = new Connection(array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "invo"));//Inject the connection in the component$some->setConnection;$some->someDbTask();

先是,我们假如,大家要花销叁个构件命名称叫SomeComponent。这么些组件中以后将在注入八个数据库连接。

class SomeComponent{ // ... /** * Define a factory method to create SomeComponent instances injecting its dependencies */ public static function factory() { $connection = new Connection(); $session = new Session(); $fileSystem = new FileSystem(); $filter = new Filter(); $selector = new Selector(); return new self($connection, $session, $fileSystem, $filter, $selector); }}
class Registry{ /** * Returns the connection */ public static function getConnection() { return new Connection(array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "invo" )); }}class SomeComponent{ protected $_connection; /** * Sets the connection externally */ public function setConnection{ $this->_connection = $connection; } public function someDbTask() { $connection = $this->_connection; // ... }}$some = new SomeComponent();//Pass the connection defined in the registry$some->setConnection(Registry::getConnection;$some->someDbTask();

从容器中拿走劳动的最简便易行方法正是使用”get”方法,它将从容器中回到二个新的实例:

//Create the dependencies or retrieve them from the registry$connection = new Connection();$session = new Session();$fileSystem = new FileSystem();$filter = new Filter();$selector = new Selector();//Pass them as constructor parameters$some = new SomeComponent($connection, $session, $fileSystem, $filter, $selector);// ... or using setters$some->setConnection;$some->setSession;$some->setFileSystem;$some->setFilter;$some->setSelector;

诸如,假使组件中有超多的依赖关系,大家须求创造多少个setter方法传递,或创设架构函数举行传递。此外,每一回使用组件时,都亟需创立依赖新组合件,使代码维护不太易,大家编辑的代码大概像这么:

容器会反回一个伸手数据的实例,开发人士最后赢得他们想要的零器件。在上边示例中的每意气风发种艺术都有利害,具体应用哪大器晚成种,由开荒进度中的特定情景来支配的。

今昔,该器件唯有访问某种service的时候才需求它,假诺它无需,它依旧不带头化,以节约能源。该器件是莫斯中国科学技术大学学解耦。他们的表现,或许说他们的别的其他方面都不会潜移暗化到构件自身。大家的落真实处境势

意在本文所述对我们PHP程序设计有所帮忙。

PhalconDI 是三个完结了劳务的信赖注入效用的零部件,它自个儿也是三个容器。

$component = $di->get("MyComponent", array("some-parameter", "other"));

近来,让我们来想像一下,大家一定要在组件中落到实处四个点子,首先必要创立一个新的数据库连接,第二个一而再两次三番拿到二个共享连接:

//Register a service "db" with a class name and its parameters$di->set("db", array( "className" => "PhalconDbAdapterPdoMysql", "parameters" => array( "parameter" => array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "blog" ) )));//Using an anonymous function$di->set{ return new PhalconDbAdapterPdoMysql(array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "blog" ));});

这一刻,大家好像回到了难点的上马,大家正在创立组件内部的依赖,咱们每回都在校正甚至寻找豆蔻年华种缓和难题的方法,但这都不是很好的做法。

class SomeComponent { /** * The instantiation of the connection is hardcoded inside * the component so is difficult to replace it externally * or change its behavior */ public function someDbTask() { $connection = new Connection(array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "invo" )); // ... }}$some = new SomeComponent;

抑或经过上面这种魔术点子的款型调用:

作者们能够调换二个组件,从她们小编依旧第三方轻便创设。在组件宣布以前,我们得以充足的决定指标的最初化,并对指标举行各样设置。

用二个字符串来设定一个劳务特别轻易,但贫乏灵活性。设置服务时,使用数组则提供了更多的八面驶风,并且能够利用较复杂的代码。lambda函数是两个之间二个很好的平衡,但也恐怕引致更加的多的掩护管理资金财产。

$request = $di->getShared;
class SomeComponent{ protected $_di; public function __construct { $this->_di = $di; } public function someDbTask() { // Get the connection service // Always returns a new connection $connection = $this->_di->get; } public function someOtherDbTask() { // Get a shared connection service, // this will return the same connection everytime $connection = $this->_di->getShared; //This method also requires a input filtering service $filter = $this->_db->get; }}$di = new PhalconDI();//Register a "db" service in the container$di->set{ return new Connection(array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "invo" ));});//Register a "filter" service in the container$di->set{ return new Filter;//Register a "session" service in the container$di->set{ return new Session;//Pass the service container as unique parameter$some = new SomeComponent;$some->someTask();

到此甘休,大家早已见到了哪些使用注重注入解决大家的主题素材。不是在代码内部创设注重关系,而是让其视作一个参数传递,那使得大家的次序更易于保险,减弱程序代码的耦合度,达成风度翩翩种松耦合。但是从遥远来看,这种样式的信任注入也是有大器晚成都部队分瑕玷。

$request = $di->getRequest();
$request = $di->get;

正文实例叙述了对PHP重视注入的接头。共享给我们供大家参照他事他说加以考查,具体如下:

class Registry{ protected static $_connection; /** * Creates a connection */ protected static function _createConnection() { return new Connection(array( "host" => "localhost", "username" => "root", "password" => "secret", "dbname" => "invo" )); } /** * Creates a connection only once and returns it */ public static function getSharedConnection() { if (self::$_connection===null){ $connection = self::_createConnection(); self::$_connection = $connection; } return self::$_connection; } /** * Always returns a new connection */ public static function getNewConnection() { return self::_createConnection(); }}class SomeComponent{ protected $_connection; /** * Sets the connection externally */ public function setConnection{ $this->_connection = $connection; } /** * This method always needs the shared connection */ public function someDbTask() { $connection = $this->_connection; // ... } /** * This method always needs a new connection */ public function someOtherDbTask { }}$some = new SomeComponent();//This injects the shared connection$some->setConnection(Registry::getSharedConnection;$some->someDbTask();//Here, we always pass a new connection as parameter$some->someOtherDbTask(Registry::getConnection;

框架本人或开辟人士都得以挂号服务。当贰个组件A须求调用组件B,能够从容器中呼吁调用组件B,并不是创制组件B的八个实例。

参数还是能在伸手的时候经过将贰个数组参数字传送递给布局函数的法子:

近年来大家来伪造一个难题,大家在应用程序中的分化地点选取此组件,将每每创办数据库连接。使用生龙活虎体系似全局注册表的不二等秘书技,从那获得二个数据库连接实例,并不是运用三次就创设一次。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图