我遇到了一些关于laravel(4.2)的神奇事物,我真的想要解释它是如何可能的。
当我在 A类
中启动MessageBag类时并将该变量传递给 B类,不管怎样,B类会覆盖A类MessageBag而不会声明它。
class ClassA {
public function test()
{
$msgBag = new \Illuminate\Support\MessageBag;
new ClassB($msgBag);
if($msgBag->any()) {
#This will trigger and spit out "Message from Class B"
dd($msgBag);
}else{
print('nope no messages');
}
}
}
class ClassB {
protected $msgBag;
function __construct(\Illuminate\Support\MessageBag $msgBag)
{
$this->msgBag = $msgBag;
$this->setMessage();
}
public function setMessage()
{
$this->msgBag->add('message', 'Message from Class B');
}
}
我用普通对象测试了同样的东西,但表现得像我预期的那样。
class ClassA {
public function test()
{
$object = (object) ['class'=>'A'];
new ClassB($object);
dd($object->class); # Will return A
}
}
class ClassB {
protected $object;
function __construct($object)
{
$this->object = $object;
$this->setMessage();
}
public function setMessage()
{
$this->object = (object) ['class'=>'B'];
}
}
很明显,Laravel正在做一些背后的事情以使这成为可能,但我还没有找到它。
有谁知道如何复制这个?
答案 0 :(得分:1)
这里没有Laravel魔法。在PHP中,对象的行为就好像它们是通过引用传递的(虽然它们在技术上不是,但在这里并不相关)。
这意味着在您的第一个示例中,您创建的MessageBag
对象与$this->msgBag
中分配给ClassB
的对象相同。因此,当您检查ClassB
中$msgBag
方法中的test()
对象时,将会看到对ClassA
内的对象所做的任何修改。
在第二个示例中并非如此,因为在setMessage()
方法中,您使用全新的对象覆盖第一个对象。
基本上一切都像普通PHP一样。