我正在使用spl_autoload进行依赖注入。
spl_autoload_register(function ($class)
{
$cFilePath = _CLASSLIB_ . "/class.$class.php";
if(file_exists($cFilePath))
{
include($cFilePath);
}
else
{
die("Unable to include the $class class.");
}
});
这很好用。但是,让我们说这些是我的课程:
class Test
{
public function foo()
{
echo "Here.";
}
}
和
class OtherTest
{
public function bar()
{
global $Test;
$Test->foo();
}
}
所以,在我执行的代码中:
<?php
$OT = new OtherTest(); //Dependency Injection works and loads the file.
$OT->bar();
?>
我会收到错误,因为bar()在测试类中尝试全局(没有实例化,因此从不自动加载)。
除了在尝试在每个方法中使用它之前检查$ Test global是否为对象之外,实现此方法的最佳方法是什么?
答案 0 :(得分:0)
尽可能避免使用全局变量。您在评论中提到了依赖注入:您可以使用DI来解决此问题。
如果OtherTest依赖于Test的一个实例,那么在构造它时,应该将该Test实例提供给OtherTest,例如
$T = new OtherTest($Test);
您显然需要修改您的OtherTest类以将Test的实例作为属性,并将Test作为参数的构造函数,如:
class OtherTest
{
protected $test = null;
public function __construct(Test $test)
{
$this->test = $test;
}
public function bar()
{
return $this->test->foo();
}
}
然后您可以执行以下操作:
$test = new Test();
$otherTest = new OtherTest($test);
$otherTest->bar();
答案 1 :(得分:0)
我认为你混淆了依赖注入的含义。类自动加载不是依赖注入。依赖注入是实际将对象可能具有的依赖项注入对象的位置,以便它可以使用它。因此,接收依赖项的对象与需要创建其依赖项完全脱离。
在这种情况下,实现依赖注入的最佳方法是在OtherTest实例化上将对Test类的依赖注入OtherTest。所以Othertest可能看起来像这样:
class OtherTest
{
protected $test_object = NULL;
public function __construct($test_obj) {
if ($test_obj instanceof Test === false) {
throw new Exception('I need a Test object');
}
$this->test_obj = $test_obj;
}
public function bar()
{
$this->$test_obj->foo();
}
}
实例化的代码可能如下所示:
$OT = new OtherTest(new Test()); // both OtherTest and Test would be autoloaded here if not previously loaded.
请注意,引用未声明的变量(示例中为$Test
)不会自动加载一个类,因为变量名本身没有类的上下文。您最终会因尝试在非对象上调用方法而收到错误。