I have worked on my own factory class that instantiates dependencies and passes through constructs when a dependency is set/requested. If the dependency is cached ( Has already been instantiated by another class ) i pass that class instance instead of instantiating all over again ( mainly used for db connection ). The issue i am having at the moment is as follows.
** To avoid a large question & save reading time i am attempting to illustrate the issue as simply as possible, if the actual code is needed i can paste in.
Class View {
// Construct Requests User Model
}
Class Controller {
// Construct Requests User Model & Class View
$this->user->set($newuserid);
$this->view->display('file');
}
So Controller
is instantiated, since View
is set as a dependencies it is instantiated and passed to Controller
via __construct
. Everything is fine, but for things like a profile page. Where i set a new user ( illustrated above ) setting the new userid also alters the userid that is contained within the View
User Model. I am not using static vars so i am confused as to why changed made in controller
affect the view
user model. This causes an issue for me because the logged in User's ID is set via entry point of site ( bootstrap ) & errors are caused when the profile page overwrites the logged in users id. I have added a newInstance
option within my factory, to instead instantiate a new user model for the user profile. Things work fine, but i am still curious as to why i had/have this issue.
In PHP5, variables that hold objects do not contain the actual object itself, but an identifier to reference the actual object.
So when you pass objects around, you actually pass a copy of the identifier to the object which of course points to the same object.
So when you use the same user object in both, your Controller and your View and manipulate it, the actual User Object will be changed. Since both object variables still hold the same identifier to the object, the objects state will be the same in your Controller as well as in your View.
<?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
The cruicial thing to understand is that both, the View and the Controller are referencing the same object, thus manipulating the object in one class will result in also manipulating it in the other class (technically that's wrong because both just point to the same object).
Now let's use the clone keyword in the View:
public function __construct( User $user )
{
$this->user = clone $user;
}
Now the $user
property of the view will hold a "pointer" to a copy of the user object. Changes made on that object will not affect the initial object that was passed.
Thus the output will be: JeffreyThomas
I want to lose a few words of caution:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.