I’m writing my first real MVC-application with PHP. I’m not using a framework because my application is so small that I figured it would be faster to write everything from scratch.
In my app, users can register, login and then write/edit/delete content. Each piece of content references its owner by a userid-column in the database.
I am now about to implement user access restrictions (in the sense that users can only view/edit/delete their OWN content/items/models). I’m wondering where the check for “valid access” should happen and where user-objects are instantiated.
I mean, I definitely need information about the current user in controllers, models and views. So I’m thinking if it’s viable to have a global user object (defined in index.php) that stores all the user information so I could access it comfortably from each part of my application.
At the moment, this snippet grants my controllers access to user information which I then also store in the data-array that is passed to the view:
class Controller {
protected $data, $id, $user;
public function __construct($action = null, $data = null) {
if (User::isLoggedIn()) {
$this->user = new User($_SESSION['user']);
$this->data['user'] = $this->user;
}
}
}
Following this pattern, I’d have to pass on user information to each model I create or alternatively have them instantiate their own user-object.
What is the way to go here? Global user object, instantiation in each model or passing the user-object as a parameter to models and views?
Thank you for your help!
There are several things to note here. Firstly: “I then also store in the data-array that is passed to the view:”
In MVC, the view has direct access to the model, see my answer here How is MVC supposed to work in CodeIgniter for an overview of that.
Secondly, your question is really about Dependency Management. Globals (and by extension statics) are problematic ( Make all variables global, PHP , Are global variables bad? , Static methods or not? ). The preferred method is passing the fully-constructed $user object into class which requires it.
However, in this case you can’t have a fully-constructed user object because you need to know whether the user is logged in prior to constructing the object so pass a mapper, factory or DAO object into the constructor and create the user as needed.
Finally, however, if you take my first point, that Views can access their model directly and don’t get passed data by their controller, then your controller may not even need to know whether the user is logged in. This is, after all, domain logic so belongs in the model.