如何使用简单的PHP函数“依赖注入”,我要这么做?
-
20-09-2019 - |
题
我听到人们在谈论依赖注入和它的所有时间的益处,但我并不真正了解它。
我想知道,如果它是在“我通过数据库连接作为参数的所有时间”问题的解决方案。
我想它阅读维基百科的条目,但示例用Java编写的,所以我不明白扎实它正试图弄清楚的差异。 ( http://en.wikipedia.org/wiki/Dependency_injection )。
我读这种依赖性喷射中的PHP文章( HTTP ://www.potstuck.com/2009/01/08/php-dependency-injection/ ),它好像目的是不直接传递依赖关系的对象,而是为了封锁了的创建与创建它沿对象的依赖。我不知道如何应用在使用PHP功能方面,虽然。
此外,是以下依赖注入,我要这么做试图做依赖注入在功能方面?
版本1:(我创建,但不喜欢那种代码,每一天)
function get_data_from_database($database_connection){
$data = $database_connection->query('blah');
return $data;
}
版本2:(?不必经过一个数据库连接,但也许不是依赖注入)
function get_database_connection(){
static $db_connection;
if($db_connection){
return $db_connection;
} else {
// create db_connection
...
}
}
function get_data_from_database(){
$conn = get_database_connection();
$data = $conn->query('blah');
return $data;
}
$data = get_data_from_database();
版本3:(?创建“对象” /数据是分开的,并且该数据库代码是静止的,所以,这可能算作依赖注入的)
function factory_of_data_set(){
static $db_connection;
$data_set = null;
$db_connection = get_database_connection();
$data_set = $db_connection->query('blah');
return $data_set;
}
$data = factory_of_data_set();
任何人有这使得该方法的好资源,或只是洞察力和受益-crystal-清楚了吗?
解决方案
依赖注入是“我在构造函数中的一些更多的参数”的一大词。
这是当你不喜欢全局你的awfull辛格尔顿波前所做的:
<?php
class User {
private $_db;
function __construct($db) {
$this->_db = $db;
}
}
$db = new Db();
$user = new User($db);
现在,唯一的办法就是使用一个类来管理你的依赖,这样的事情:
class DependencyContainer
{
private _instances = array();
private _params = array();
public function __construct($params)
{
$this->_params = $params;
}
public function getDb()
{
if (empty($this->_instances['db'])
|| !is_a($this->_instances['db'], 'PDO')
) {
$this->_instances['db'] = new PDO(
$this->_params['dsn'],
$this->_params['dbUser'],
$this->_params['dbPwd']
);
}
return $this->_instances['db'];
}
}
class User
{
private $_db;
public function __construct(DependencyContainer $di)
{
$this->_db = $di->getDb();
}
}
$dependencies = new DependencyContainer($someParams);
$user = new User($dependencies);
您一定会认为你只是一个类和更多的复杂性。但是,您的用户类可能需要的东西,记录消息像很多其他类的。只需添加一个getMessageHandler功能,以您的依赖容器,有的$this->_messages = $di->getMessageHandler()
到您的用户类。在你的代码的其余部分没有任何改变。
您会得到很多的相关信息在 symfony中的doc 一>
其他提示
您第一示例的 IS 强>扶养注射,你正在注入数据库对象的依赖到函数。
莎拉说,这不是,但国际海事组织是的,我相信她是想依赖注入容器,是下一级的:
这是你的例子没有一只看起来像依赖注入,一个版本是,虽然最近的一刻。依赖注入是在面向对象的编程中使用的技术,其中一个对象的构造具有参数为对象它所需要的服务,并且这些服务对象由该实例的创建者(其可以是一个工厂,测试,或通过在一个依赖注入框架)。
要摆脱你的“永远传递连接对象”的问题,你可能要考虑的模板模式。模板图案基本上是一个抽象基类与重复的代码块的公共部分,和抽象方法,以允许那些重复的代码块的实例之间的变化。基本上基座是一个代码块的模板,和抽象方法是在待填充的空白。我个人使用模板方法图案做在Java中我的数据库资源控制。
我做了一番搜索有关这个主题的自己(PHP依赖注入),并没有发现太多我喜欢的。很多已经写在其他语言的主题(谷歌吉斯 - http://code.google .COM / p /谷歌吉斯/ ; Java的春天),但我找不到太多可供PHP。不管语言的,然而,挑战是相似的。
您在您的问题列表中的三个版本是典型的做法。第3版是最接近我已经看到了行业经营的方向。通过移动你的类之外的创建依赖对象的责任,你可以自由操纵他们为你在你的测试代码讨好。但是,我这种做法所遇到的问题是,你最终在你的构造函数依赖的对象有可能甚至不能由接收对象所使用的长链,但打通传递给二级依赖对象。它就会变得混乱,你失去的东西是从哪儿来的知识。
依赖容器例如通过@Arkh和@mmmshuddup是一个好的开始,但是我仍然发现这种做法局限性。当我到达最终的解决方案是在斯卡拉蛋糕图案流行后有所建模的定制解决方案。它可以让你通过一个单一的依赖您的每一个构造函数,它可以让你定义每的类依赖对象的默认的建设。这让您摆脱长期依赖链以及失去你依赖的默认实现的控制。
我叫系统柴油和我已经与它真的很高兴。我发表的代码在GitHub上的人感兴趣。你可以从我关于这个问题,它描述的基本用法以及进入对您的问题详细写的博客得到它。 http://developers.blog.box。 COM / 2012/02/15 / introducting柴油-PHP-依赖注入/
依赖注入是为了专注于他们为什么取决于除去2个部件之间的依赖关系的想法。
假设你有需要使用另一组分B的服务的组分A
如果你硬编码B的存在内部的,那么你将被卡住的时候,你会希望有一个使用萨姆斯服务,而是由其他组件来实现。
所以通常情况下,您可以定义B和C将实现服务接口,并且您确保当你使用,你用所需的接口兼容的对象喂养它。
在你的情况,你可能会认为你的界面上,你可以进行查询的服务。
您第一种情况是所述一个那就是依赖注入的想法越接近。