PHP 中多"References"(对象指针)的上下文是什么?



有时我在其他人编码中看到了这一点......

$object->Something_1->Something_2;

我理解指向和反对这样的函数或变量......

$object->Something_1;
$object->Something_1();

但我不明白串在一起的多个对象指针是如何工作的。我无法在网上找到任何解释这一点的东西,所以也许我搜索的术语是错误的,但有人会解释或指出我可以找到这篇文章吗?

我不知道实现这种用法需要什么,我想看看这是否是我可以在我的编码中受益的东西。

这个:

$object->Something_1->Something_2();

几乎和这个一样:

$temp = $object->Something_1;
$temp->Something_2();

它的意思是Something_1本身是一个对象,它也有成员,在这种情况下,方法Something_2。 语法没有什么特别之处。 任何解析为对象的东西都可以使用->调用其成员。 因此,$object解析为对象,在这种情况下,$object->Something_1也是如此。

原始代码示例可以重写为:$invoice->sender->getName();

在此代码中,变量$sender已定义为public(在类中,用于实例化$invoice对象)。这意味着,对象的封装被破坏了。该代码还期望$sender实际上包含一个对象。

您可以通过使用 getter 而不是直接访问变量来改进封装:$invoice->getSender()->getName();

但这种方法也被认为是一种代码异味。这也会使调试非常烦人,并且经常导致违反得墨忒耳定律。

这种链接被认为是一种不好的做法。我强烈建议避免它。

唯一的例外(常见)是使用域实体时的资源库链接。在这种情况下,看到这样的代码是很常见的:

$invoice
->setSender('John Doe')
->setReceivedOn(time())
->setOrder($data);

为了实现它,方法的定义如下:

public function setSender($sender) {
$this->sender = $sender;
return $this;
}

这个特殊的用例并不像其他用例那么糟糕,因为该类实际上并没有在链->链接之间变化(这就是使前两个示例的调试成为噩梦的原因)。但我个人仍然会避免这种方法,因为setter不应该返回任何内容,getter不应该改变对象的状态。

TL;DR:不要采用这种风格的代码。

基本上,当一个对象将一个或多个其他对象存储为属性时,就会发生这种情况。

例如:

class Car 
{
public string $name;
public Engine $engine;
}
class Engine
{
public $someProp;
}

如果你在变量中有一辆汽车,你可以像这样访问引擎的属性:

$car->engine->someProp;

(假设汽车已初始化,汽车中的发动机也已初始化)

最新更新