Nu wil ik dit uitbreiden met een database, maar wil ik de sql scheiden uit de controller (model). Hoe moet nu bijvoorbeeld een indexModel.class.php er uit zien?
Dat is voor mij een beetje het probleem, als er zoals die link bovenaan een duidelijke basis (met een voorbeeldje voor een nieuwssysteempje of mini-blog ofzo) zou zijn zou ik dit verder kunnen uitwerken voor grotere systemen. Alleen nu heb ik die link, alleen is het model niet compleet. Zou iemand misschien de moeite kunnen/willen nemen om dat script verder te verwerken (niet compleet, maar één of twee functies ofzo) zodat het mij duidelijk wordt. Dan zal ik het complete systeem aan de libary toevoegen als het klaar is.
Je kan heel simpel beginnen. Je maakt in je database een tabel met nieuwsberichten aan en zet er vast wat nieuwsberichten in.
Vervolgens maak je de class die een nieuwsbericht representeert. Eigenlijk is dit niet veel meer dan een veredelde array waarvan alle keys alvast bekend zijn :) Maar dit is programmeren in objecten, en arrays gebruik je dan alleen nog om lijsten mee te schrijven ;)
<?php
class News_Item
{
public $id;
public $title;
public $content;
public $pubDate;
}
?>
De properties komen eigenlijk direct overeen met de kolommen van je database-tabel.
Mooi, nu heb je de records in de database, en het vormpje waarin die records gegoten moeten worden. Daarvoor de News_Store:
<?php
class News_Store
{
protected $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function findAll()
{
$stmt = $this->pdo->query('SELECT id, title, content, pubDate FROM news_items');
// dit zorgt ervoor dat je News_Item objecten terugkrijgt
// van PDO, compleet ingevuld en wel. Later zal dit wss
// niet meer kunnen omdat je News_Item class ingewikkelder
// wordt, maar voor nu is het heerlijk kort :)
$stmt->setFetchMode(PDO::FETCH_CLASS, 'News_Item');
return $stmt->fetchAll();
}
public function findById($id)
{
$stmt = $this->pdo->prepare('SELECT id, title, content, pubDate FROM news_items WHERE id = :id');
return $stmt->fetch();
}
}
?>
Nu kan je je controller vullen. Bijvoorbeeld
<?php
// (wat een stomme naamgeving, classes met een kleine letter
// beginnen? Dat is zooo not done!)
class NewsController extends baseController
{
public function __construct($register)
{
parent::__construct($register);
$this->news_store = new News_Store($this->register->db);
}
public function index()
{
$news_items = $this->news_store->findAll();
@Jelmer mooi voorbeeldje. Maar om het even wat moeilijker te maken ;). Wat als je ook de mogelijkheid hebt om ook bij elk nieuwsbericht reacties te plaatsen. En je wilt bijvoorbeeld bij elk nieuwsbericht alleen de laatste 5 reacties tonen.
In je template wil je dan waarschijnlijk zo iets doen
<? foreach ($news_item->getLatestComments(5) as $comment): ?>
hier wat html
<? endforeach ?>
En dan voor je News_Item een method setCommentStore(Comment_Store $store) zodat elk nieuwsbericht zelf zijn laatste reacties kan ophalen via de Comment_Store. Dit is zo ongeveer de manier waarop ik dit zou doen. Maar ik ben benieuwd of er betere manieren zijn en hoe jij dit oplost? :)
Ik denk dat je inderdaad de News_Item wel kan koppelen aan de comments. Mocht je dat niet willen, dan kan je altijd nog iets doen a la $comment_store->getLatestForNewsItem($news_item, 5). Want comments zijn wel afhankelijk van nieuws, maar andersom niet.