PHP中多个“引用”(对象指针)的上下文是什么?

时间:2017-06-20 12:19:31

标签: php oop object

有时我会在别人的编码中看到这个...

$object->Something_1->Something_2;

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

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

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

我不知道实现这种用法需要什么,并且想知道我的编码是否可以从中受益。

3 个答案:

答案 0 :(得分:3)

此:

$object->Something_1->Something_2();

几乎与此相同:

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

所有这意味着Something_1本身就是一个也有成员的对象,在本例中是方法Something_2。语法没有什么特别之处。解析为对象的任何内容都可以使用->调用其成员。所以$object解析为一个对象,在这种情况下$object->Something_1也是如此。

答案 1 :(得分:3)

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

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

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

但这种方法也被认为是code smell。它还会使调试非常烦人,并且经常导致违反Law of Demeter

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

唯一的例外是,当使用域实体时,常见的是设置器的链接。在这种情况下,看到这样的代码是很常见的:

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

要实现它,方法将被定义如下:

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

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

TL; DR :不采用这种代码。

答案 2 :(得分:1)

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

例如:

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

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

$car->engine->someProp;

(假设汽车已初始化,汽车发动机也是如此)