Проблема наследования классов PHP Factory

Я работал над собственным классом фабрики, который создает экземпляры зависимостей и проходит через конструкции, когда зависимость установлена ​​/ запрошена. Если зависимость кэшируется (уже был создан другим классом), я передаю этот экземпляр класса вместо того, чтобы создавать его заново (в основном используется для соединения с БД). Проблема, с которой я столкнулся на данный момент, заключается в следующем.

** Чтобы избежать большого вопроса & сэкономить время на чтение Я пытаюсь проиллюстрировать проблему как можно проще, если нужен реальный код, который я могу вставить.

Class View {
// Construct Requests User Model
}

Class Controller {
// Construct Requests User Model & Class View
$this->user->set($newuserid);
$this->view->display('file');
}

Так Controller создается, так как View устанавливается как зависимость, он создается и передается Controller с помощью __construct, Все хорошо, но для таких вещей, как страница профиля. Когда я устанавливаю нового пользователя (показано выше), установка нового идентификатора пользователя также изменяет идентификатор пользователя, содержащийся в View Модель пользователя. Я не использую статические переменные, поэтому я не понимаю, почему изменения сделаны в controller влиять на view пользовательская модель. Это вызывает у меня проблему, потому что идентификатор пользователя, вошедшего в систему, устанавливается через точку входа сайта (начальная загрузка) & Ошибки возникают, когда страница профиля перезаписывает идентификатор пользователя, вошедшего в систему. Я добавил newInstance вариант в моей фабрике, вместо того, чтобы создать новую модель пользователя для профиля пользователя. Все работает хорошо, но мне все еще интересно, почему у меня была эта проблема.

0

Решение

В PHP5 переменные, которые содержат объекты, содержат не сам фактический объект, а идентификатор для ссылки на фактический объект.

Поэтому, когда вы передаете объекты, вы фактически передаете копию идентификатора объекту, который, конечно, указывает на тот же объект.

PHP документы на объекты и ссылки

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

<?php

class User {

protected $name;

public function __construct($name)
{
$this->setName($name);
}

public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}

}

class View {

protected $user;

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

public function render()
{
echo $this->user->getName();
$this->user->setName('Tony');
}

}

class Controller {

protected $user;
protected $view;

public function __construct( User $user, View $view )
{
$this->user = $user;
$this->view = $view;
}

public function someAction()
{
$this->user->setName('Thomas');
$this->view->render();
echo $this->user->getName();
}

}

$user = new User('Jeffrey');
$view = new View($user);
$controller = new Controller($user, $view);

$controller->someAction(); // Output: ThomasTony

Крайне важно понять, что и View, и Controller ссылаются на один и тот же объект, поэтому манипулирование объектом в одном классе приведет также к манипулированию им в другом классе (технически это неверно, поскольку оба указывают только на один и тот же объект) ,


Теперь давайте используем ключевое слово clone в представлении:

public function __construct( User $user )
{
$this->user = clone $user;
}

Теперь $user Свойство представления будет содержать «указатель» на копию объекта пользователя. Изменения, внесенные в этот объект, не влияют на исходный объект, который был передан.

Таким образом, результат будет: JeffreyThomas

Я хочу потерять несколько слов предостережения:

  • Вместо того, чтобы клонировать объект, вы должны убедиться, что у ваших объектов чистый поток. Ваш вид не должен манипулировать состоянием пользователя после его прохождения.
  • Использование клона может привести к нежелательному поведению. Если кто-то передает объект одному из ваших классов и ожидает, что класс изменит состояние объектов (здесь мы не говорим о «представлениях»), в то время как это не так, это может дать им очень трудное время для отладки.
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]