- Hoe moet ik een control-, model- en viewclass maken voor dat gastenboek
Ik zou het als volgt doen:
De controller bevat de methods om berichten te plaatsen, weer te geven en te verwijderen. Dus zeg eens:
> showMessages()
> showMessage($messageId)
> editMessage(optioneel $messageId)
Meer heb je er niet echt nodig. editMessage() kan prima gebruikt worden voor het nieuw aanmaken van een bericht naar mijn idee. Gewoon een leeg Model voeren :)
Iedere method van de controller geeft een instantie van een klasse die de interface View implementeert terug. De interface View bevat maar 1 eis: de method 'draw'. Je kan nog wel wat meer eisen - ik eis zelf ook nog de functie isEmbedded bijvoorbeeld - maar dat is voor een gastenboek niet echt nodig.
De methods van de controller doen dus hun ding met de models - kom ik zo op terug bij je 2e vraag - en geven vervolgens een instantie van View terug - kom ik bij je 3e vraag op terug.
- Ik heb eraan gedacht om een class Message te maken, dus elk bericht als een object. Dit lijkt mij toch niet helemaal de beste oplossing. Klopt dat?
Zou ik wel doen. Iedere instantie van Message representeert dan een bericht, en dus een enkele regel in de database. Of nog niet :) Je Model, Message in dit geval bevat in ieder geval 2 methods: save() en delete(). Dezen voeren de query uit die het bericht opslaat of invoert, of verwijdert. De Model is dus in staat zichzelf toe te voegen en te verwijderen uit de database.
Verder bevat de Model properties die gelijk zijn aan de veldnamen van de tabel in de database. Ik zou trouwens Message::$id wel even protected maken, en een method id() of ROWID() toevoegen om deze uit te kunnen lezen. Zo is het onmogelijk om die van buiten te veranderen - zoals het hoort.
Via je SQL klasse maak je dan voor iedere row in het resultaat een nieuwe instantie aan, of je kloont er eentje. PDO heeft daar bijvoorbeeld 'FETCH_CLASS' en 'FETCH_INTO' voor.
- Hoe pak ik het aan met een TPL parser? Een TPL parser gebruiken zoals bijvoorbeeld Smarty, Template Power of er zelf 1 maken?
Een template parser is hoogstens een hulpmiddel om de amateur-modus van Dreamweaver te kunnen gebruiken, je medewerkers de vrijheid te ontnemen of op te scheppen, of om jezelf te leren presentatie van de rest te scheiden.
De view doet dat laatste ook wel, daarvoor kun je dus gewoon PHP gebruiken in je View, en hoef je op zich niet ingewikkeld te gaan doen met templates compilen.
Een voorbeeldje van een simpele View klasse:
<?php
interface View {
public function draw();
}
class SimpleView implements View {
protected
$_delegate,
$_template;
public function __construct($delegate = null)
{
if(is_object($delegate)) {
$this->_delegate = $delegate;
} else {
$this->_delegate = $this;
}
}
public function setTemplate($file)
{
$this->_template = $file;
}
public function __get($key)
{
return $this->_delegate->$key;
}
public function __isset($key)
{
return isset($this->_delegate->$key);
}
public function draw()
{
include $this->_template;
}
}
?>
Je controller maakt dus een instantie van die klasse aan, geeft hem vervolgens alle variabelen die je in je template wilt gebruiken mee. Of je geeft gewoon in 1 keer een $delegate mee, dan haalt hij daar zijn waarden weg.
Je template is dan gewoon een simpel PHP bestandje zoals deze:
<h1><?php echo $this->titel; ?></h1>
met als controller dan dus bijvoorbeeld dit:
<?php
class TestController {
public function groet()
{
$view = new SimpleView();
$view->setTemplate('template.phtml');
$view->titel = 'Pindakaas';
return $view;
}
}
?>
Roep je nu [TestController]->groet()->draw() aan, dan krijg je "Pindakaas" in grote letters te zien :) Alles mooi gescheiden, maar in dit voorbeeld gebruik ik nog geen Models.
Maar verder kom ik helaas niet.....
Enige wat nu nog mist is iets dat de Controller aanroept: een Router. Een Router doet niets meer dan aan de hand van de opgevraagde URL dit uitvoeren:
<?php
$controllerInstance = new $controller();
$viewInstance = $controllerInstance->$method();
$viewInstance->draw();
?>
Je kan hem nog wat uitbreiden en opsplitsen, bijvoorbeeld een 2e view erbij doen om de standaard-zooi te laten afhandelen. Stel je maakt er nog even een MainController bij:
<?php
class MainController {
public function default(View $childView)
{
$view = new SimpleView();
$view->setTemplate('index.phtml');
$view->childView = $childView;
return $view;
}
}
?>
met als index.phtml:
<html>
<body>
<h1>Mijn Site</h1>
<?php $this->childView->draw() ?>
</body>
</html>
en als router:
<?php
$mainControllerInstance = new MainController();
$controllerInstance = new $controller();
$viewInstance = $controllerInstance->$method();
$mainController->default($viewInstance)->draw();
?>