2016-11-01 2 views
2

У меня возникает проблема при передаче объекта через разные классы и попытка иметь только один экземпляр из него вместо нескольких клонов.Передача объектов через несколько вложенных классов

TLDR версия:

Если у меня есть объекты A->B->C, где C получает передается A путем B в качестве параметра по созданию, будет C->A->B доступа оригинальный B, который создал его, или копия этого B? Сколько копий B есть в системной памяти?

Чуть более подробная версия:

Скажу, у меня есть (возможно, слишком запутанная) вложенная структура класса для обработки запроса на основе сервера. Первым шагом является создание объекта класса Session, а затем внутри него, создание объекта $handler класса Handler. Однако, как $handler нужно будет иметь доступ к внутренним атрибутам $session (и множества других объектов, созданных в нем, как $user или $database, чьи цели должны быть понятны), я затем передать его в качестве параметра:

class Session { 
public $handler; 

public function __construct() { 
    $this->handler = new Handler($this); 

    //DO STUFF HERE 
} 
} 

Handler класс наследует сессии, как это:

class Handler { 
private $session; 

public function __construct(Session $inherited_session) { 
    $this->session = $inherited_session; 
} 
} 

Side Примечание: $session установлен в private, чтобы избежать даже малейшего шанса на бесконечных петель вниз по линии, в $this->session->handler->session->handler разновидность.

Теперь, согласно моему пониманию и всему исследованию, которое я сделал, PHP передает объекты по ссылке, поэтому объект $this->session в этом Handler должен иметь доступ к одному и тому же объекту в системной памяти в качестве исходного сеанса? Не копия себя?

Но вот моя проблема. Предположим, теперь я создаю вложенный объект третьего уровня в классе Handler класса Dashboard и хочу передать ему оригинал $session (не так, только сам объект Handler). Off мы идем, поэтому мы помещаем это где-то в пределах Handler класса:

$dashboard = new Dashboard($this->session); 

Dashboard конструктор наследуется сеанс точно так же, как и Handler сделал:

class Dashboard { 
private $session; 

public function __construct(Session $inherited_session) { 
    $this->session = $inherited_session; 
} 
} 

Однако, это не кажется способный получить доступ к экземпляру Handler, который вызвал его, и теперь кажется, что мы имеем несколько копий $session и $handler, плавающих вокруг - и я очень хотел бы понять, почему, потому что это противоречит всему, что я понимаю о ссылках.

Вот пример этого патологического поведения - скажем, мы имеем переменную в Handler:

public $temp_var; 

, что конструктор Handler присваивает значение:

$this->temp_var = '123'; 

и затем мы пытаемся к нему доступ из в классе Dashboard, как $this->session->handler->temp_var. Это возвращает NULL. Зачем? $dashboard наследовать копию $session на инициализацию, которая не имеет инициализированного ->handler, чтобы позвонить? Как я могу сделать так, что есть только один (уникальный) объект каждого класса, и обновление внутренних (общедоступных) переменных $handler будет правильно передано на $dashboard->session->handler? Или я просто делаю какую-то очевидную/идиотскую ошибку где-то и полностью не вижу ее?

Примечание № 1: любая переменная, установленная в $session, как $this->var, правильно доступна из $dashboard->session->var, поэтому двухуровневая вложенность работает, как и ожидалось; это тройной уровень, которого нет.

Примечание # 2: Я уже думал, просто передавая $handler в качестве параметра для всех его вложенных объектов вместе с$session (и если решения не существует, это то, что я должен буду делать), но он не решает исходную проблему $this->session->handler, которая как-то и необъяснимо отличается от исходного $handler внутри своих вложенных объектов.

О, и я благодарю всех, кто сумел прочитать все это!

+1

TL; DR ... Но ... есть только так много объектов, как вы создаете. Каждый 'new' создает новый объект,« clone »копирует объект. Если вы не клонируете свои объекты, вы всегда будете ссылаться на единственный экземпляр этого объекта. – deceze

+0

Ошибка лежит где-то в вашем коде, объекты не клонируются и не копируются, если вы явно не указали PHP на это. – Mjh

+0

Да, это то, о чем я думал, но я буквально просто провел 4 часа этим утром на работе, искал ошибку в коде, и ничего не нашел, поэтому задавать этот вопрос здесь просто отчаяние действительно – ak186

ответ

0

Насколько я понимаю, вы имеете дело с composition не с inheritance здесь.

Итак, у вас есть Session, который передается в Handler, то Handler и Dashboard как «знать» сеанс через композицию (сохраняя ссылку на приватную переменную).

Я не понимаю, зачем вам нужна эта круговая ссылка, но если вы хотите получить доступ к Handler от Dashboard, почему бы не передать Handler?

Кроме того, похоже, что вы храните обработчик в локальной переменной контекстными (я был далеко от PHP за последние два года, но ...)

class Session { 

    public function __construct() { 
    // isnt $this->handler = new Handler($this) ?? 
    $handler = new Handler($this); 
    } 
} 

С концептуальной точки view, там нет «гнездования», только ссылки, поэтому я не думаю, что «три уровня» делают с этим что-то общее.

Надеюсь, это поможет!

Here's an example Я модифицировал сессию и конфиденциальность просто чтобы убедиться, что $ сессия по-прежнему тот же

+0

К сожалению, как упоминалось в другом комментарии выше, я просто не копирую его здесь должным образом, $ handler на самом деле является публичной переменной в классе Session, и это, конечно же, $ this-> handler = new Handler ($ this); Должен заметить, что я скопировал его неправильно, извини. – ak186

+0

Итак, как вы можете видеть в ссылке, это работает, может быть, вы делаете что-то еще, что вызывает ваши ссылки. – sminutoli

+0

Я думаю, ваша проблема в том, что вы пытаетесь получить доступ к '$ this-> session-> handler-> temp_var', поэтому вы должны отлаживать, когда он вам доступен ... но опять же, у вас много рекурсии, похоже, вам нужно больше времени на разработку своих объектов – sminutoli