Родительский объект в php

существует ли способ пересечь объект получить данные родительского объекта? С "родительским объектом" я не имею в виду родительского класса, но буквально возражаю. Здесь пример, в javascripty мире :-):

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

$parent->child = new B();

Было бы замечательно, Если я мог бы получить доступ ко всем данным из родителя в дочернем объекте:

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"
    }
}

На данный момент мое решение состоит в том, чтобы передать родительский объект ребенку (как ссылка) или сделать родителя глобальным. У Вас есть какое-либо лучшее решение?

Спасибо!

12
задан Gordon 11 March 2010 в 08:07
поделиться

4 ответа

Невозможно вызвать

$parent->test = "hello world!";
$parent->child = new B();

и автоматически получить ссылку на $ parent в B.


Обычно существует четыре способа структурировать классы:

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();
     }
}

Используйте внедрение конструктора, когда объект должен иметь родительский элемент при его создании. Это отношение имеет-, и оно создает очень слабую связь. В B нет жестко запрограммированных зависимостей, поэтому вы можете легко заменить родительский экземпляр, например, с помощью Mock при UnitTesting. Использование внедрения зависимостей сделает ваш код более удобным в сопровождении.

В вашем сценарии использования вы должны передать $ parent в B при создании B:

$parent->child = new B($parent);

2. Использовать композицию

class B
{
     private $parent;

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

     public function accessParent() 
     {
        $this->parent->someMethodInParent();
     }
}

Это также отношение has-a , но связывает родительский класс с B. Это также не существующий родительский экземпляр, а новый экземпляр. Судя по формулировке, мне кажется несколько странным, что родитель создан ребенком. Используйте это, когда зависимость - это класс, который не считается существующим вне корневого класса, но является частью всего, что он представляет.

Для вашего UseCase нет способа выполнить $ parent-> child = new B (); и узнать, какой родитель является при использовании этого подхода, если только $ parent не является синглтоном. Если это так, вы можете получить экземпляр Singleton, например Parent :: getInstance () , чтобы добиться желаемого, но учтите, что синглтоны не всем любимый шаблон, например трудно проверить.

3. Использовать наследование

class B extends Parent 
{
    public function accessParent() 
    {
        $this->someMethodInParent();
    }
}

Таким образом вы создаете отношение is-a .Все общедоступные и защищенные методы и свойства родительского класса (но не конкретного экземпляра) будут доступны в B, и вы можете получить к ним доступ через ключевое слово $ this экземпляра B.

Для вашего UseCase этот подход не работает, так как вам вообще не нужно иметь экземпляр Parent, но B инкапсулирует все Parent при его создании

$b = new B;

4. Используйте ключевое слово global

class B extends Parent 
{
    private $parent;

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

    public function accessParent() 
    {
        $this->parent->someMethodInParent();
    }
}

Ключевое слово global импортирует глобальные переменные в текущую область. В общем, вам следует избегать использования глобального ключевого слова в объектно-ориентированном контексте, но использовать один из трех других методов, описанных выше, предпочтительно первый. Несмотря на то, что это языковая функция, она не одобряется - хотя это следующая вещь, которая ближе всего к первой, например

$parent->child = new B();

В любом случае, надеюсь, что это поможет.

22
ответ дан 2 December 2019 в 05:27
поделиться

Я почти уверен, что в PHP нет чего-то подобного.

Ваше решение передачи родительского объекта -объект для ребенка - лучшее решение, я думаю. Вам следует подумать о том, чтобы установить свойство Parent только в конструкторе дочернего элемента, чтобы не допустить, чтобы у нескольких родителей был один и тот же ребенок.

1
ответ дан 2 December 2019 в 05:27
поделиться

Нет.

Вы можете получить доступ к переменным из суперкласса, используя $ this:

<?php
class A {
    public function __construct()
    {
        $this->foo = 'hello';
    }
}

class B extends A {
    public function printFoo()
    {
        echo $this->foo;
    }
}

$b = new B();
$b->printFoo();
?>
0
ответ дан 2 December 2019 в 05:27
поделиться

Передача родитель для ребенка - лучшее решение. Хотя это несколько нежелательные симбиотические отношения.

Должен ли B () знать об объекте, атрибутом которого он является? Скорее всего, нет. Они лишь слабо связаны через композицию.

Почему B () должен быть атрибутом своего родителя? Вам нужна эта реализация в B () или она должна быть частью родительского?

3
ответ дан 2 December 2019 в 05:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: