Ik ben om te leren OOP te programmeren met php een forum aan het maken.
Wat is nu de beste methode om je objecten te vullen met de data uit de database? Moet je een constructor (of aparte functie) maken met daarin de SQL om je hele object te van zijn data te voorzien door bijvoorbeeld een id mee te geven? Of is het de bedoeling dat je buiten het object een query uitvoert en d.m.v. je setters de data in je object pompt?
Na lang denken en wikken en wegen ben ik hier nog steeds uit.
Ik ben gewend programma's te schrijven in C++ en Java, en dat allemaal OOP. Het voordeel daar is dat je objecten over het hele programma blijven bestaan, tenzij je de destruct. Hoe moet je dat oplossen in php?
De mooiste manier is een ORM. Dat kan op twee manieren (voor zover ik weet)
- Active record. Je Domain Object (User) extend een bepaalde klasse. Je vindt dit oa in Doctrine 1.
<?php
$user = User::find($id);
$user->setEmail('bla');
$user->save();
?>
Dit heeft het nadeel dat je Domain Objects afhankelijk worden van je Active Record mechanisme. Mooier is methode twee:
- Data mapper. Een andere klasse regelt de 'persistence' (opslag) van je objecten. Je vindt oa in Doctrine 2. De andere klasse heet daar de Entity Manager.
<?
$user = $em->find('User', $id);
$user->setEmail('bla');
@Pim, hier ben ik precies toch nog niet echt mee weg. Zo een Entity Manager, wat doet dat precies? Kan je eens een voorbeeldje geven?
Wat me ook nog steeds niet duidelijk is, is de algemene structuur van een opgeroepen pagina. Stel, ik roep de pagina op die gewoon het overzicht van forums ('categorien') laat zien. Hoe ziet dat er dan uit?
Ik heb als 'model' gewoon een paar klassen die Forum, Topic en Post voorstellen. Maar deze klassen hebben tot nu toe nog geen enkele functionaliteit. Ik neem aan dat iets zoals het volgende niet de bedoeling is?
<?php
$sql = "SELECT * FROM forums ORDER BY title ASC";
// uitvoeren
$forums = array();
foreach($result as $forum)
{
$forums[] = new Forum(/* data in $forum hierin stoppen */);
}
// html bla bla bla
for($i = 0; $i < count($forums); $i++)
{
$f = $forums[$i];
// uitschrijven dmv $f->getTitle(); etc
}
?>
Elders op dit forum heb ik al kenbaar gemaakt dat ik op zijn zachtst gezegd geen fan ben van Active Record. Zelf gebruik ik vaak het Data Mapper pattern. En ja, die schrijf ik allemaal handmatig.
De beste manier om objecten te vullen vanuit een query vindt ik dan ook:
Wat ik, over het algemeen, vind wanneer men vraagt naar de zinnigheid van OOP en hoe men het moet aanpassen...
Bekijk het eens van de andere kant.
Vergeet even de class op zich en denk aan het gebruik er van, buiten de class.
Schrijf je logica en doe alsof de methodes van je class al precies doen wat je wil.
Als je dat hebt, vul dan je class in en zorg dat het doet wat je vraagt.
Een voorbeeld: een gastenboek:
Wat is dat? Een formulier, een lijst berichten en de mogelijkheid om een nieuw bericht te posten.
Voor mij zijn dat dus drie publieke methodes (+ een constructor uiteraard).
Je zou er zo-iets van kunnen maken:
<?php
require_once('guestbook.php');
$m_guestbook = new guestbook();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$m_guestbook->postMessage($_POST);
header('location ...');
}
else {
$guestbook = $m_guestbook->form() . $m_guestbook->messages();
echo '<html>...<body>... '. $guestbook .'</body></html>';
}
?>
Als je dit hebt, dan kan je beginnen nadenken over hoe je guestbook.php precies aanpakt.
Oké, bedankt. Het een en ander is nu wel duidelijk, denk ik. Ik kan wel eens aan de slag.
Nog iets, jij hebt functies om een heel form of de rest uit te printen? Is dat wel zo goed?
En als ik dit nu met Smarty ofzo wil doen? Kan ik dan via een assign een heel object meegeven en dat object 'ondervragen' (data uithalen) in de tpl-files?
edit:
Dat van Smarty heb ik gevonden, assign_by_ref() :)