“多重”的上下文是什么;参考资料;(对象指针)在PHP中?

“多重”的上下文是什么;参考资料;(对象指针)在PHP中?,php,oop,object,Php,Oop,Object,有时我在其他人的代码中看到这一点 $object->Something_1->Something_2; 我理解指向和反对函数或变量本身 $object->Something_1; $object->Something_1(); 但我不明白串在一起的多个对象指针是如何工作的。我在网上找不到任何东西来解释这一点,所以也许我搜索的术语是错误的,但是有人能解释一下或者给我指一篇我可以学到这一点的文章吗 我不知道实现这种用法需要什么,我想看看这是否能从我的编码中获益。基本上,当

有时我在其他人的代码中看到这一点

$object->Something_1->Something_2;
我理解指向和反对函数或变量本身

$object->Something_1;
$object->Something_1();
但我不明白串在一起的多个对象指针是如何工作的。我在网上找不到任何东西来解释这一点,所以也许我搜索的术语是错误的,但是有人能解释一下或者给我指一篇我可以学到这一点的文章吗


我不知道实现这种用法需要什么,我想看看这是否能从我的编码中获益。

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

例如:

class Car 
{
    public string $name;
    public Engine $engine;
}
class Engine
{
    public $someProp;
}
如果变量中有一辆车,可以访问引擎的属性,如下所示:

$car->engine->someProp;
(假设汽车已初始化,汽车中的发动机也已初始化)

这:

$object->Something_1->Something_2();
与此基本相同:

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

这意味着
Something\u 1
本身就是一个对象,它也有成员,在本例中是方法
Something\u 2
。语法没有什么特别之处。任何解析为对象的对象都可以使用
->
调用其成员。因此,
$object
解析为一个对象,在这种情况下,
$object->Something\u 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;
}
要实现这一点,方法的定义类似于:

$invoice
    ->setSender('John Doe')
    ->setReceivedOn(time())
    ->setOrder($data);
public function setSender($sender) {
    $this->sender = $sender;
    return $this;
}
这个特定的用例没有其他用例那么糟糕,因为类实际上并没有在
->
链的链接之间改变(这使得前两个示例的调试变成了一场噩梦)。但我个人仍然会避免这种方法,因为setter不应该返回任何内容,getter不应该更改对象的状态


TL;DR:不要采用这种类型的代码。

对象->某物的值本身就是一个对象。不多不少。与
$array['foo']['bar']
,数组中的数组没有什么不同。我总是在构造或初始化时使用单例,而不是您在这里提到的
setSender
方法。我认为调试它将比
setSender
方法容易得多。另外,您可以使用
return($this->sender instanceof sender)?真:假
而不是
返回$this用于
setSender
方法。“有了这一点,它就更有意义了。”ICE IMHO,最好的办法是根本不从二传手那里回来,坚持自己的观点。至于单身人士,他们被认为是一种反模式(观察了解原因)。至于在构造函数中传递依赖项,我个人更喜欢只使用构造函数来注入强制依赖项,并且,除非您使用,否则setter完全可以改变实体的状态。感谢围绕这个问题的进一步上下文以及编码标准和视频!谢谢你!总是很好,谢谢!谢谢。我给你的答案是因为这是最简单的解释。我还做了一个小的代码示例,我认为它很容易理解,也基于您告诉我的内容。如果你愿意,也许你可以把它加到你的答案或类似的东西上。不管怎样,谢谢!@你好你能用这样的字符串声明一个类引用吗?比如公共类名?我尝试使用您的代码,但出现了意外的字符串错误。我想我明白你的意思,想知道是否有一个简单的方法来做这样的事情。要在类级别而不是类函数级别声明类。@噢,数据类型仅适用于PHP7+,如果您使用的是旧版本,则可以删除数据类型(字符串和引擎),它们主要用于说明