Ik ben bezig met het ontwikkelen van een eigen MVC. Via htaccess stuur ik alles door naar mijn index. Mijn index bepaalt vervolgens welke controller moet worden aangeroepen. Stel mijn url is /nieuws/nieuwsitem. In dit geval moet de NewsitemController worden aangeroepen om het nieuwsitem te tonen. Stel mijn URL is /over-ons. Dan moet de ContentController worden aangeroepen en een contentpagina getoond worden. Maar nu mijn vraag.. Hoe weet index welke controller moet worden aangeroepen?
Zou je niet gewoon controllers maken van je pagina's ? En deze dezelfde naam geven als de URL[0] ?
if(file_exists('controllers/' . $route[0] . '.php')) {
require('controllers/' . $route[0] . '.php');
//Controle of de Controller-class bestaat, anders doorsturen naar een 404 ???
if(class_exists($route[0]))
$this->controller = new $route[0];
else
header('location: 404.php');
} else {
//Controller file bestaat niet, doorsturen naar een 404 ?
header('location: 404.php');
}
Ik ben zelf ook nog altijd bezig met MVC te leren hoor.. Misschien heb je hier wat aan.
Het kan mooier door van de route ook een object te maken. En eigenlijk ook van het request. Alles is een object.
Verder laat je de applicatie nu allerlei models en controllers langslopen, maar kun je dat ook overdragen aan een front controller.
Schematisch krijg je dan zoiets:
<?php
// HTTP-verzoek
$request = new Request();
// Verzoek centraal opslaan
$registry = new Registry();
$registry->set('request', $request);
// Front controller
$front_controller = new FrontController($registry);
// Het verzoek bepaalt de route
if ($request->hasRoute()) {
$route = $request->getRoute();
} else {
$route = new Route('error/404');
}
// Front controller zet andere controller aan het werk
$front_controller->dispatch($route);
?>
Je steekt daarnaast steeds een model in een controller, bijvoorbeeld:
<?php
$model = new HomeModel();
$controller = new HomeController($model);
$model = new NewsitemModel();
$controller = new NewsitemController($model);
?>
Als elke FooController in jouw architectuur echter een bijbehorend FooModel heeft, kun je ook alleen de controller aanroepen. In MVC wil je liever alleen controllers met andere controllers laten communiceren. Jij hebt echter nu naast die bovenwereld nog een schaduwwereld: je moet parallel steeds alle models instantiëren voordat je überhaupt een controller aan het werk kunt zetten.
Verder is dat ook niet efficiënt. De controller bepaalt (bijvoorbeeld op basis van het request) of het model eigenlijk wel nodig is. Sommige models zijn slechts nodig als je een UPDATE of een INSERT wilt uitvoeren. Die models hoef je dus lang niet altijd te laden en te instantiëren.
Vuistregel: alleen de controller communiceert met het eigen model.
Alleen de controller weet waar Abraham de mosterd haalt. Dat kan bijvoorbeeld data uit een database zijn, maar diezelfde data kunnen ook uit een bestand komen, uit een cache, uit een cURL-request, enzovoort. Dat moet allemaal voorbij gaan aan andere objecten. Die spreken de controller gewoon aan en krijgen het antwoord dat ze verwachten.
Je hebt die regel nu omgekeerd met een "voorschrift": je instantieert eerst een model en schrijft dat vervolgens voor aan de controller door het te injecteren in de controller.
Vuistregel: alleen de controller communiceert met het eigen model.
Alleen de controller weet waar Abraham de mosterd haalt. Dat kan bijvoorbeeld data uit een database zijn, maar diezelfde data kunnen ook uit een bestand komen, uit een cache, uit een cURL-request, enzovoort. Dat moet allemaal voorbij gaan aan andere objecten. Die spreken de controller gewoon aan en krijgen het antwoord dat ze verwachten.
Je hebt die regel nu omgekeerd met een "voorschrift": je instantieert eerst een model en schrijft dat vervolgens voor aan de controller door het te injecteren in de controller.
Hoe zou ik dat kunnen verbeteren dan?
Misschien een setModel() methode?
Dat is dan het MVC model waarin ik toch een ernstige tekortkoming zie. In Symfony bijvoorbeeld kun je gewoon vanuit de VIEW nog een andere controller aanroepen. Mijn ervaring is dat dat echt heerlijk werkt. Wat ik maar wil zeggen is dat het MVC niet heilig is en dat het mij persoonlijk om gebruiksgemak gaat. @Ward: Ik zie met die layers niet hoe je nu meerdere views in één response kunt verwerken. (Bijv. layer1 -> algemene pagina layout, layer 2 sidebar en layer 3 de specifieke content van de huidige pagina)