php中的父对象

Ant*_*nti 12 php oop class

有没有办法遍历一个对象来获取父对象数据?对于"父对象",我不是指父类,而是字面上的对象.这里有一个例子,在javascripty世界:-):

$parent->test = "hello world!";

$parent->child = new B();
Run Code Online (Sandbox Code Playgroud)

如果我可以访问子对象中父节点的所有数据,那就太好了:

class B{

//I know this doesn't exists, but it's what I wanted do do
    function B(){
        $this->parent = $this->parent();
        echo $this->parent->test; //it would ouput "hello world"
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我的解决方案是将父对象传递给子对象(作为参考)或使父对象成为全局对象.你有更好的解决方案吗?

谢谢!

Gor*_*don 22

没有办法调用

$parent->test = "hello world!";
$parent->child = new B();
Run Code Online (Sandbox Code Playgroud)

并自动在B中引用$ parent.


通常,有四种方法来构建类:

1.通过注入聚合父对象,例如

class B
{
     private $parent;

     public function __construct($parent) 
     {
         $this->parent = $parent;
     }

     public function setParent($parent) 
     {
         $this->parent = $parent;
     }

     public function accessParent() 
     {
        $this->parent->someMethodInParent();
     }
}
Run Code Online (Sandbox Code Playgroud)

当对象在创建父对象时必须具有父对象时,请使用构造函数注入.这是一种关系,它会产生非常松散的耦合.B中没有硬编码的依赖项,因此您可以轻松地换出Parent实例,例如在UnitTesting时使用Mock.使用依赖注入将使您的代码更易于维护.

在您的UseCase中,您$parent在创建B时将传递给B:

$parent->child = new B($parent);
Run Code Online (Sandbox Code Playgroud)

2.使用组合物

class B
{
     private $parent;

     public function __construct() 
     {
         $this->parent = new Parent;
     }

     public function accessParent() 
     {
        $this->parent->someMethodInParent();
     }
}
Run Code Online (Sandbox Code Playgroud)

这也是一个has-a关系,但将Parent类耦合到B.它也不是现有的Parent实例,而是一个新实例.从措辞中我发现孩子创建父母有点奇怪.当依赖是一个不被认为存在于根类之外的类,但它是它所代表的整个事物的一部分时,使用它.

对于你的UseCase,$parent->child = new B();除非$ parent是Singleton,否则在使用这种方法时无法做到并知道父是什么.如果是这样,你可以获得Singleton实例,例如Parent::getInstance()实现你想要的,但请注意Singletons不是每个人最喜欢的模式,例如难以测试.

3.使用继承

class B extends Parent 
{
    public function accessParent() 
    {
        $this->someMethodInParent();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以创建一个is-a关系.来自Parent类的所有公共和受保护方法和属性(但不是特定实例)将在B中可用,您可以通过$thisB实例的关键字访问它们.

对于你的UseCase,这种方法不起作用,因为你根本不必拥有Parent的实例,但B会在创建Parent时封装Parent的所有内容.

$b = new B;
Run Code Online (Sandbox Code Playgroud)

4.使用全局关键字

class B extends Parent 
{
    private $parent;

    public function __construct() 
    {
        global $parent;
        $this->parent = $parent;
    }

    public function accessParent() 
    {
        $this->parent->someMethodInParent();
    }
}
Run Code Online (Sandbox Code Playgroud)

global关键字进口全局变量到当前范围.通常,您应该避免在OO上下文中使用global关键字,但是使用上面其他三种方法之一,最好是第一种方法.虽然它是一种语言功能,但它不赞成 - 虽然它是第一个与第一个最接近的东西,例如

$parent->child = new B();
Run Code Online (Sandbox Code Playgroud)

无论如何,希望有所帮助.