有时我在其他人编码中看到了这一点......
$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;
(假设汽车已初始化,汽车中的发动机也已初始化)