Reputation: 1
PHP - MVC question: So this is a pretty high level question about building an MVC. I have a class called page, and it needs to pull in classes for the model, view, and controller. There is also a Route class that has mostly attributes regarding the Path: /Class/Method/arg1/arg2 , etc
Right now the Page pulls in that Route object as its constructor param.
Should Model, View and Controller extend Page ? Whihle M,V,&C need certain information from the Route object, I don't think that logically a Model for instance extends a Page - because while it's a part of a page, it's not a different kind of page, and I'm not sure the M,V, & C need to be that intimate with each other.
But I thought I'd ask anyway. What I'm finding myself doing is the Page will pass that Route object to the controller when it instantiates it, then the same with the Model, View, etc.
I know every time you find yourself doing redundant things like this, it might be time to step back and rethink before you do too much work down that path.
But again, in my mind, the M,V, & C are not forms of a page, its more a composition thing.
Thoughts?
Thanks!
Upvotes: 0
Views: 604
Reputation: 48897
M,V,&C need certain information from the Route object
Then inject the required data into those objects.
class Controller
{
protected $router;
public function __construct(Router $router)
{
$this->router = $router;
}
}
$router = new Router();
$controller = new Controller($router);
http://www.slideshare.net/fabpot/dependency-injection-with-php-and-php-53
Beyond that, if Page is a front controller, perhaps it shouldn't be instantiating models and views at all. If Controller is to be extended, it could handle the view instantiation via a render
method and pass routing information there.
Models should be completely unaware of routing and simply provide business functionality. They shouldn't care if the request is coming from a website or a desktop application.
Upvotes: 0
Reputation: 58444
If i understand you correctly, the your Page
class is actually a hybrid between autoloader, mvc factory and a container for the whole application. That's three different responsibilities, and one of which is completely pointless. PHP is not Java. .. we do not use a "containment" class.
Also, you should question, why your Model
and View
needs access to Route
. Ok, i could see a reason for it in View, if you are also using it for generating new URLs, but there is nothing to do with Route
in the Model.
The responsibility of Controller is to take the request, and based on that execute the right command (action). Then it changes the state of Model layer and binds Domain Objects
from the said layer to the View instance or other form of response. Then controller returns that View instance.
As for other parts, Controller will be initiating the structures from the Model layer, but you should have new
operators in the Controller. That would create a tight coupling to the name of the structures. Instead you should equip Controller instance with a model factory. This factory then becomes responsible for initialization of structures from the Model layer. It would also allow you to initialize a single DB connection outside the Controller (and maybe some Cache object) and then provide it to the factory. Now you can ensure that each Model layer's item, which deals with data access, has already initialized DB connection. And you can share the same connection between all the Data Access Objects.
As for how to pass route to the Controller instance :
class Controller
{
protected $route = null;
public function setRoute( $route )
{
$this->route = $route;
}
}
because you will most likely use it like this:
class FooBarController extends Controller{}
And somewhere in bootstrap.php:
$controller = new $controllerName;
$controller->setRoute( $route );
You must remember that constructors in PHP are not inherited.
P.S. you might find this comment related to your research.
Upvotes: 0
Reputation: 4397
Your Models and Views should probably not extend page.
When it comes down to the way MVC works, you have to separate the three concerns into their logical basis.
Your routing, in my opinion is another, separate entity which directs your bootstrap to an action contained within a controller.
Controllers handle the user's input and if it represents a type of control such as a Page then it does make sense to extend a base PageController for all common functionality which must be executed in the production of a page.
The Controllers takes the interaction of the user and interacts with Models. It's unlikely that these two should have a common ancestry. Models act as an interface to business logic and data, controlling interactions with persistent stores and transforming data.
The data/transformation produced in the Models and instantiated by the Controllers is passed to the View.
Views control the presentation logic about how the data should be presented to the user. No data transformation should occur in the layer in an ideal world.
So in my MVC, I'd have base Model, View and Controller classes which are inherited by child classes.
Upvotes: 1