本文实例讲述了对PHP依赖注入的理解。分享给大家供大家参考,具体如下:
看Laravel的IoC容器文档只是介绍实例,但是没有说原理,之前用MVC框架都没有在意这个概念,无意中在phalcon的文档中看到这个详细的介绍,感觉豁然开朗,复制粘贴过来,主要是好久没有写东西了,现在确实很懒变得!
首先,我们假设,我们要开发一个组件命名为SomeComponent。这个组件中现在将要注入一个数据库连接。
在这个例子中,数据库连接在component中被创建,这种方法是不切实际的,这样做的话,我们将不能改变数据库连接参数及数据库类型等一些参数。
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();$some->someDbTask();
为了解决上面所说的问题,我们需要在使用前创建一个外部连接,并注入到容器中。就目前而言,这看起来是一个很好的解决方案:
class SomeComponent { protected $_connection; /** * Sets the connection externally */ public function setConnection($connection) { $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($connection);$some->someDbTask();
现在我们来考虑一个问题,我们在应用程序中的不同地方使用此组件,将多次创建数据库连接。使用一种类似全局注册表的方式,从这获得一个数据库连接实例,而不是使用一次就创建一次。
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($connection){ $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();
现在,让我们来想像一下,我们必须在组件中实现两个方法,首先需要创建一个新的数据库连接,第二个总是获得一个共享连接:
新闻热点
疑难解答