将实例对象传输到 class

Transfer of an instanced object into a class

我想知道将实例化对象传输到另一个 class 以供本地使用的最佳方法是什么。我也很好奇这是否会对内存使用产生影响。

我想了想,主要有两种方式:

1.) 通过引用 $GLOBALS 来传输实例对象:

class UserLogHandler {
  public function __construct() {
    $this->DB = $GLOBALS['DB'];
    $this->Security = $GLOBALS['Security'];
  }
  public function doSomeWork() {
    $this->DB->someMethod;
  }
}

2.) 交接转账:

class UserLogHandler($DB,$Security) {
    public function doSomeWork() {
        $DB->someMethod;
    }
}

在我看来,选项 2 可能更适合复杂的环境,尽管我觉得选项 1 更有吸引力。无论如何,我更喜欢技术 and/or 逻辑解释为什么使用一个选项而不是另一个。如果有其他更好的选择也请告诉我。

提前致谢并致以最良好的祝愿, 托马斯

这确实是个好问题。我会说这取决于你的需要。让我们一一分析您的选择。

开始之前,请记住您的对象应该始终是一个完整的对象。它不应该有一个不完整的状态。可以参考这篇文章加深理解https://matthiasnoback.nl/2018/07/objects-should-be-constructed-in-one-go/

1.) 通过引用 $GLOBALS 来传输实例对象:

切勿使用此类方法,因为它们会造成混淆。 $GLOBALS 无法告诉您特定变量是在何处以及如何创建的,因此您永远无法确定该变量是否存在或它包含什么。我建议你使用依赖注入

use DB;
use Security;

class UserLogHandler
{
    public function __construct(DB $DB, Security $Security)
    {
        $this->DB = $DB;
        $this->Security = $Security;
    }

    public function doSomeWork()
    {
        $this->DB->someMethod;
    }

}

了解您现在如何确定 $DB 和 $Security 从何处注入以及它们持有什么。您甚至可以使用 Security $Security.

等类型指示来强制执行变量类型

当您的 class 严重依赖于特定变量时,此方法会派上用场。例如模型 class 始终需要 DB 适配器,或者 PDF 生成器库本质上需要 PDF class。

2.) 交接转移

这按您预期的方式工作,但我认为您在定义它时犯了错误。你需要像下面这样写。

class UserLogHandler
{
    public function doSomeWork($DB, $Security)
    {
        $DB->someMethod;
    }
}

当您仅需要特定函数中的特定变量时,此方法会派上用场。例如,就像我们需要从某个特定条件下的模型中获取记录一样。所以我们可以在函数中传值,根据值得到结果。

use DB;
use Security;

class UserLogHandler
{
    public function __construct(DB $DB, $Security)
    {
        $this->DB = $DB;
        $this->Security = $Security;
    }

    public function doSomeWork($value)
    {
        if ($value = 'something') {
            $this->DB->someMethod;
        }
    }

}

如您所见,这两种方法都可以结合使用。这只取决于你的要求