Maak een Forum
1. Wat is het plan?
2. Alle stapjes
3. Voorbereiding
4. De MySQL Database
5. De functies maken en het verwerken van de formulieren
top
1. Wat is het plan?
Misschien is het de trouwe forum bezoeker al opgevallen dat er daar af en toe wel eens wordt gevraagd hoe men een forum maakt.
De beginstappen, het idee, de uitwerking... alles werd al gevraagd.
Deze tutorial zal hopelijk het antwoord zijn waarop zij al zolang hebben gewacht.
Ik vermeld hier wel bij dat dit zeker GEEN veilig forum is.
Een heel klein ledensysteempje zonder beveiliging zit er in, zodat de beginnende php'er het kan begrijpen, en naar eigen keuze uitbreiden.
Ook is MySQL injection en Header Injection perfect mogelijk.
De bedoeling van de tutorial is een idee geven HOE men een forum maakt, niet om het uiteindelijke forum dan ook te gebruiken.
Uitbreiding zal perfect naar eigen keuze mogelijke zijn.
Maar laten we beginnen...
top
2. Alle stapjes
We gaan natuurlijk van 0 beginnen, en voor dat we beginnen scripten gaan nadenken wat we willen en hoe we dit gaan doen.
De MySQL structuur doordenken, en de mogelijkheden die we hebben.
We gaan via de header gegevens versturen naar onze eigen pagina, deze gegevens uit de header halen en hiermee een query opbouwen.
Deze query haalt dan op zichzelf weer de juiste gegevens uit de MySQL database en geeft deze weer op het scherm.
Dat is ongeveer het hele idee achter een forum, er zijn echter nog honderden manieren, via sessies gegevens versturen bv. mss zelfs via cookies.
Deze 2 laatste ga ik niet behandelen omdat ik me dan extreem ga toespitsen op de beveiliging, en dat is zoals ik al eerder vermelde niet de bedoeling.
Het forum zal bestaan uit 1 pagina die de header leest, en enkele verwerkende pagina's (ook zal er een klein leden systeempje (onveilig) in verwerkt worden.
We gaan via functies alles aanroepen, en dan in een grote if() de header gaan controleren.
Wat natuurlijk de eerste stap is, is een MySQL database structuur overdenken.
Dan volgt het ontwerp van de weergave.
Ik ga simpele tabellejtes, met een border van 1 nemen zodat alles lelijk maar duidelijk neerkomt.
Dan gaan we beginnen met het eigenlijke script.
Eerst alle functies maken en dan kiezen welke functie we gaan uitvoeren.
Elke functie retourneert gegevens.
We maken een functie voor het bekijken van alle categorien, het bekijken van de topics in een categorie, het bekijken van het eigenlijke topic, een nieuw topic maken ,hierin posten en als laatste een functie die controleert of de gebruiker is ingelogd, zoniet dan geeft hij een form weer.
Dit is eigenlijk het geraamte voor een forum, uitbreiding kan je zelf maken.
We hebben dus enkele formuliertjes nodig: een nieuw-topic form ,een reactie-forum en een log-in form.
Dan hebben we een appart scriptje voor de leden om te registreren.
En een appart scriptje voor een admin (heel simpel beveiligd) om een nieuwe categorie aan te maken.
top
3. Voorbereiding
Wat moet je al kunnen/kennen?
Basis PHP en MySQL.
Veel ingewikkelds komt er niet in voor en anders leg ik het wel uit.
Enige kennis over $_GET en $_POST is ook altijd welkom.
Voor de rest heb je een server nodig die PHP en MySQL ondersteund en als laatste: goede moed.
top
4. De MySQL Database
We gaan eerst analyseren wat we willen wegschrijven en daarna inlezen.
We maken 4 tabellen.
1. Een klein leden-tabelletje
2. Een tabel met alle topics en hun gegevens die gelinkt wordt door het categorie-id met de categorien tabel
3. Een tabel met alle berichten die gelinkt wordt door het topic-id nummer met de topic tabel
4. Een tabel met alle categorien en hun id
Allereerst, wat zit er in de ledentabel:
1. ID
2. Naam
3. Pass
Heel makelijk uit te breiden met bv. email-adres, aantal posts, extra beveiliging en dergelijke gegevens.
Dan ziet onze tabel er zo uit:
CREATE TABLE leden(
lid_id INT auto_increment NOT NULL,
naam VARCHAR(100) NOT NULL,
pass VARCHAR(100) NOT NULL,
PRIMARY KEY(lid_id) );
|
Zoals je kan zien heb ik van naam geen unieke row gemaakt, omdat dat alles simpeler maakt, hoe minder script, hoe simpeler het te leren valt.
We analyeren even:
We maken een lid_id integer aan, deze moet automatisch met 1tje verhogen per lid dat er bij komt(auto_increment).
We maken een rij waarin alle namen staan en een rij met de bijbehorende passwoorden.
Nu de MySQL structuur voor de topics en hun gegevens.
1. Degene die het topic heeft gestart
2. Het eerste bericht
3. De bijbehorende categorie
4. Een idee nummer
5. Titel vd topic
Je kan er natuurlijk allerlei extraatjes zoals tijd en laatste poster etc insteken, maar dat laten hier weeral achterwegen.
De code ziet er alsvolgt uit:
CREATE TABLE topics(
topic_id INT auto_increment NOT NULL,
starter VARCHAR(100) NOT NULL,
categorie_id INT NOT NULL,
bericht TEXT NOT NULL,
titel VARCHAR(100) NOT NULL,
PRIMARY KEY(topic_id)
);
|
Weeral een automatisch groeiende id nr.
De naam vd poster, het bijbehorende categorie dat wordt gelinkt in ons script aan de categorie tabel en het startende bericht.
Nu de berichten tabel, waarin al onze berichten worden opgeslagen en gescheiden door het topic_id.
1. bericht_id
2. topic_id
3. naam van de poster
Hierbij kunnen weer een hoop extra's die ik niet ga bespreken.
CREATE TABLE berichten(
bericht_id INT auto_increment NOT NULL,
topic_id INT NOT NULL,
poster VARCHAR(100) NOT NULL,
bericht TEXT NOT NULL,
PRIMARY KEY(bericht_id)
);
|
Ik hoop dat bij dit laatste geen uitleg nodig is, zeker niet als je de 2 vorige hebt begrepen.
Nu nog de categorien en dat was het dan voor het MySQL ontwerp gedeelte.
1. Een categorie id
2. Een categorie naam
3. Uitleg over de gemaakte categorie
Deze laatste is geen must, maar toch even om er iets leuk in te verwerken.
CREATE TABLE categorien(
categorie_id INT auto_increment NOT NULL,
categorie_naam VARCHAR(100) NOT NULL,
categorie_uitleg TEXT NOT NULL,
PRIMARY KEY(categorie_id)
);
|
Dit bovenste gedeelte zou duidelijk moeten zijn.
top
5. De functies maken en het verwerken van de formulieren
We gaan eerst onze functies gewoon aanmaken, samen met het if systeem.
Nadien gaan we de functies opvullen met simpele instructies, en een output terugsturen.
Laat ons eerst eens gaan kijken hoe het if systeem werkt.
<?php
ob_start();
include("config.php");
function laat_categorie_zien(){
//laat alle categorien zien met een bij behorend linkje
}
function laat_topic_zien(){
//laat alle topics zien die bij een bepaalde categorie horen met een bijbehorend linkje
}
function laat_berichten_zien(){
//laat alle berichten zien die overeenkomen met het topic id
}
function maak_nieuw_topic(){
//een formuliertje
}
function post_bericht(){
//nog een formuliertje
}
function login(){
//een if structuur die gaat controleren of de persoon al is ingelogd, zoniet dan laat het een formuliertje zien
}
echo "<center>";
login();
echo "<br />";
if(!isSet($_GET['categorie_id']) && !isSet($_GET['topic_id']) && !isSet($_GET['action'])){
laat_categorie_zien();
}
elseif(isSet($_GET['categorie_id']) && !isSet($_GET['topic_id']) && !isSet($_GET['action'])){
laat_topic_zien();
//hier komt straks een linkje voor het maken van een nieuw topic
}
elseif(isSet($_GET['categorie_id']) && $_GET['action'] == "nieuwtopic" && !isSet($_GET['topic_id'])){
maak_nieuw_topic();
}
elseif(!isSet($_GET['categorie_id']) && isSet($_GET['topic_id']) && !isSet($_GET['action'])){
laat_berichten_zien();
post_bericht();
}
echo "</center>";
?>
|
Niet verschieten, dit lijkt mss veel, maar we gaan nu een voor een bekijken.
De uitleg staat bij de functies, nu het if systeem uitleggen.
Eerst gaan we config.php includen, dit zou je zelf moeten kunnen maken, hierin staat de connectie met de Database.
Ik heb de functie login() buiten de if gezet, omdat hij dit elke keer moet controleren.
Dan gaan we beginnen met de if, eerst kijken we na of dit de begin pagina is.
Dit doen we door te kijken of er geen $_GET is geselecteerd.
Voor de geen die niet weten wat $_GET is: dit is een array die alle gegevens uit de header kan lezen.
Als deze leeg is, in het eerste geval, moeten we alle categorien laten zien, dit is de beginpagina.
Vervolgens gaan we controleren met $_GET of er een categorie_id met de header wordt meegegeven.
Zoja: dan laten we alle bijbehorende gegevens van de categorie zien: de topics die hierbij horen.
Plus een linkje naar het maken van een nieuw topic binnenin de categorie.
Dat linkje gaan we straks een bekijken.
Dan gaan we bekijken of er misschien op die link is geklikt, zoja dan geven we een formulier voor een nieuw topic te maken weer.
En als laatste kijken we of er een topic_id met de header wordt meegegeven.
Zoja, dan geven we alle bijbehorende berichten weer, samen met de functie om te reageren.
Nu gaan we stap voor stap alle functies doorlopen.
Ten eerste de functie om alle categorien te laten zien.
<?php
function laat_categorie_zien(){
$res_categorie = mysql_query("SELECT * from categorien");
//we selecteren alle gegevens uit de tabel categorien
while($obj_categorie = mysql_fetch_object($res_categorie)){
$link_categorie = "<A HREF='". $_SERVER['PHP_SELF'] ."?categorie_id=". $obj_categorie->categorie_id ."'>". $obj_categorie->categorie_naam ."</A>";
//deze variabele bevat de link, zodat we dat straks niet allemaal in de echo moeten schrijven
$info_categorie = $obj_categorie->categorie_uitleg;
echo $link_categorie ."<br />";
echo $info_categorie ."<br />";
echo "<br /><br /><br />";
}
}
?>
|
Die ziet er zo uit, laten we deze eens stap voor stap gaan doorlopen.
Om te beginnen maken we een query die alle gegevens uit de categorien tabel haalt.
Daarna gaan we via een while loop alle gegevens uit de tabel halen, en een voor een weergeven.
<?php
$link_categorie = "<A HREF='". $_SERVER['PHP_SELF'] ."?categorie_id=". $obj_categorie->categorie_id ."'>". $obj_categorie->categorie_naam ."</A>";
?>
|
Dit is een link die ik in een variabele heb gezet.
Deze bevat gegevens uit de tabel, via de header geven we het categorie_id meegeven, en het zichtbare gedeelte wordt de naam van de categorie.
Vevolgens gaan we deze link weergeven met daaronder de beschrijving van de categorie.
Een paar entertjes om het overzichtelijk te houden en we kunnen aan onze volgende functie beginnen.
<?php
function laat_topic_zien(){
$categorie_id = $_GET['categorie_id']; //de gegevens uit de header halen
$res_topic = mysql_query("SELECT * from topics WHERE categorie_id = '". $categorie_id ."'");
while($obj_topic = mysql_fetch_object($res_topic)){
$link_topic = "<A HREF='". $_SERVER['PHP_SELF'] ."?topic_id=". $obj_topic->topic_id ."'>". $obj_topic->titel ."</A>";
echo $link_topic ."<br />";
}
}
?>
|
Hiermee laten we de bijbehorende topics zien.
We halen eerst het categorie_id uit de header.
Vervolgens maken we een query die alle gegevens uit de tabel topics selecteert die overeenkomen met het categorie_id.
Daarna gaan we via een while loop alle gegevens weergeven.
<?php
$link_topic = "<A HREF='". $_SERVER['PHP_SELF'] ."?topic_id=". $obj_topic->topic_id ."'>". $obj_topic->titel ."</A>";
?>
|
Dit is weeral een link waarmee me via de header het topic_id doorsturen.
Het zichtbare gedeelte is weeral de titel, deze keer van het topic.
Nu komt een relatief lange functie.
Voor de berichten van het bijbehorende topic te laten zien.
Eerst laten we het start-bericht zien, dat we uit de tabel topics halen.
En daarna laten we de berichten zien die bij het topic horen, deze halen we uit de tabel berichten.
<?php
function laat_berichten_zien(){
$topic_id = $_GET['topic_id']; //de gegevens uit de hedaer halen
$res_berichten1 = mysql_query("SELECT * from topics WHERE topic_id = '". $topic_id ."'");
$obj_berichten1 = mysql_fetch_object($res_berichten1);
echo "<table border="1" width="50%"><tr><td><center>";
echo "<table border="1" width="50%"><tr><td>";
echo $obj_berichten1->starter;
echo "</td></tr><tr><td>";
echo $obj_berichten1->bericht;
echo "</td></tr></table>";
$res_berichten2 = mysql_query("SELECT * from berichten WHERE topic_id = '". $topic_id ."'");
while($obj_berichten2 = mysql_fetch_object($res_berichten2)){
echo "<table border="1" width="50%"><tr><td>";
echo $obj_berichten2->poster;
echo "</td></tr><tr><td>";
echo $obj_berichten2->bericht;
echo "</td></tr></table";
}
echo "</center></td></tr></table>";
}
?>
|
We halen eerst weer de gegevens uit de header.
Vervolgens maken we een query die alle gegevens uit de tabel topics haalt die overeenkomen met het topic_id.
Deze geven we dan weer, en dan bouwen we een nieuwe query op.
Deze haalt alle gegevens uit de tabel topics die overeenkomen met het topic_id.
Dan geven we die gegevens weer via een while loop.
Mooi via een tabelletje, eerst de naam, en daaronder het bericht.
Nu gaan we een formulier maken, hiermee kan iemand een nieuw topic maken.
<?php
function maak_nieuw_topic(){
if(isSet($_COOKIE['login'])){
$categorie_id = $_GET['categorie_id']; //we moeten weten waar we ons topic gaan steken, dat halen we uit de header
?>
<form action="verwerk_nieuw_topic.php" method="post" name="nieuw_topic">
Titel: <input type="text" name="titel"><br />
Bericht: <textarea cols="25" rows="25" name="bericht"></textarea><br />
<input type="hidden" name="categorie" value="<?php echo $categorie_id; ?>">
<input type="Submit" name="Submit" value="Submit">
</form>
<?php
}
else{
echo "gelieve aan te melden";
}
}
?>
|
We kijken eerst na of er een cookie bestaat die login noemt.
Ons ledensysteem werkt op cookies, dus vandaar, als iemand zich aanmeld laten we deze cookie zetten, maar daar komen we straks op terug.
Daarna geven we een gewoon html formuliertje weer, en we geven via een hidden veld de categorie_id mee, om straks mee te kunnen verwerken.
We laten het formulier verwerken in de pagina: verwerk_nieuw_topic.php.
Deze pagina gaan we nu bekijken.
<?php
ob_start();
include("config.php");
$titel = $_POST['titel'];
$bericht = nl2br($_POST['bericht']); //we zorgen dat alles mooi wordt geenterd
$categorie_id = $_POST['categorie'];
$query = "INSERT into topics
(starter, categorie_id, bericht, titel)
VALUES
('". $_COOKIE['naam'] ."', '". $categorie_id ."', '". $bericht ."', '". $titel ."')";
mysql_query($query) or die(mysql_error());
header("location: forum.php");
?>
|
Eerst includen we weer config.php om connectie te leggen met de database.
Daarna halen we gegevens uit de $_POST array, en lijnen we het $bericht uit zodat niet alle tekst achter elkaar wordt weergegeven.
Vervolgens maken we een query die alle gegevens in de tabel topics steekt.
En dan laten we ons terug doorverbinden met forum.php.
Nu gaan we verder kijken naar onze functies.
We moeten er nog 2 maken: post_bericht() en login().
Laten we beginnen bij het eerste.
<?php
function post_bericht(){
if(isSet($_COOKIE['login'])){
$topic_id = $_GET['topic_id']; //we halen weeral de gegevens uit de header
?>
<form action="verwerk_gepost_bericht.php" method="post" name="nieuw_bericht">
<textarea class="textarea" rows="10" style="width: 40%;" name="bericht"></textarea><br />
<input type="hidden" name="topic" value="<?php echo $topic_id; ?>">
<input class="button" type="Submit" name="Submit" value="Submit">
</form>
<?php
}
else{
echo "U moet u aan melden voordat u reacties kan posten";
}
}
?>
|
Eerst gaan we weeral kijken of de persoon is ingelogd.
Zoja, dan gaan we verder:
We geven een formulier weer met daarin weeral een hidden veld, deze bevat deze keer het topic_id.
Dit sturen we mee via de $_POST array om straks in ons verwerk_gepost_bericht.php bestand in de tabel te steken.
Laten we die pagina nu eens bekijken.
<?php
ob_start();
include("config.php");
$bericht = nl2br($_POST['bericht']);
$topic_id = $_POST['topic'];
$query = "INSERT into berichten (
topic_id, poster, bericht)
VALUES
('". $topic_id ."', '". $_COOKIE['naam'] ."', '". $bericht ."')";
mysql_query($query) or die(mysql_error());
header("location: forum.php");
?>
|
We includen weeral eerst config.php voor de connectie met de database.
Vervolgens lijnen we het bericht uit zodat de tekst niet na een wordt weergegeven.
Daarna bouwen we een query op die de gegevens in de tabel berichten steekt.
De variabele $_COOKIE['naam'] hoort bij het leden systeem, waarbij we de naam in een cookie steken.
Dit is natuurlijk zeer onveilig daar deze makelijk veranderd kan worden, en zo ineens admin rechten kan krijgen.
Ook zou het beter zijn als ik ga controleren of er wel degelijk op Submit is gedrukt in het formulier, maar dat zou je in principe zelf kunnen doen, op je eigen manier.
Daarna verbinden we de gebruiker weer door naar forum.php.
Nu onze laatste functie: login()
<?php
function login(){
if(!isSet($_COOKIE['login'])){
?>
<form action="verwerk_login.php" method="post" name="login">
naam: <input type="text" name="naam"><br />
pass: <input type="password" name="pass"><br />
<input type="Submit" name="Submit" value="Submit">
</form>
<a href="registreren.php">REGISTREER NU</a>
<?php
}
else{
echo "welcome ". $_COOKIE['naam'];
}
}
?>
|
We kijken eerst na of de gebruiker misschien al wel niet is ingelogd.
Is dit niet zo, dan geven we een formulier weer, deze wordt verwerkt in verwerk_login.php.
We geven ook een link naar registreren.php weer, zodat de nieuwe gebruikers zich ook kunnen registreren.
Als de gebruiker al is ingelogd, geven we een welkomst berichtje weer.
Nu gaan we eens kijken hoe verwerk_login.php er uit ziet.
<?php
ob_start();
include("config.php");
$res = mysql_query("SELECT * from leden WHERE
naam = '". $_POST['naam'] ."' AND
pass = '". md5($_POST['pass']) ."'");
while ($obj = mysql_fetch_object($res)){
setCookie("login", "1", time()+3600*24); //1 dag
setCookie("naam", $_POST['naam'], time()+3600*24);
setCookie("pass", md5($_POST['pass']), time()+3600*24);
}
header("location: forum.php");
?>
|
We maken weeral eerst connectie met de database via config.php.
Daarna maken we een query die alle gegevens selecteert die overeenkomen met de ingevoerde gegevens.
Als die gegevens bestaan dan moeten we een cookie zetten genaamd login(om te kijken of de persoon is ingelogd, een voor de naam, en voor jullie gemak heb ik er ook al een gemaakt voor het password, dat ik niet heb gebruikt in mijn forum script.
Ik raad je aan deze wel te gebruiken, omtrent de beveiliging.
Als laatste verbinden we de persoon door naar forum.php.
Nu resteren ons nog 2 pagina's: 1e voor te registreren, en 1tje voor de admin om categorien toe te voegen.
We beginnen met die om te registreren:
<?php
ob_start();
include("config.php");
if(!isSet($_POST['Submit'])){
?>
<form name="register" action="" method="post">
Naam: <input type="text" name="naam"><br />
Pass: <input type="password" name="pass"><br />
<input type="Submit" name="Submit" value="Submit">
<?php
}
else{
$query = "INSERT into leden (naam, pass) VALUES
('". $_POST['naam'] ."', '". md5($_POST['pass']) ."')";
mysql_query($query) or die(mysql_error());
}
header("location: forum.php");
?>
|
We kijken na of er misschien op submit is gedrukt, zoniet geven we een invulformulier weer.
Als er dan op submit wordt gedrukt maken we een query die alle gegevens in de tabel leden steekt.
Daarna laten we de persoon door verbinden naar het forum waar hij of zij zich kan inloggen.
Als laatste een kleine admin pagina:
<?php
ob_start();
include("config.php");
if($_COOKIE['naam'] == "UW NAAM <--> ZELF VERANDEREN" && $_COOKIE['pass'] == md5("UW PASSWORD <--> ZELF VERANDEREN")){
if(!isSet($_POST['Submit'])){
?>
<form action="" method="post" name="nieuw_categorie">
<input type="text" name="naam"><br />
<textarea name="uitleg"></textarea><br />
<input type="Submit" name="Submit" value="Submit">
</form>
<?php
}
else{
$query = "INSERT into categorien (categorie_naam, categorie_uitleg) VALUES ('". $_POST['naam'] ."', '". $_POST['uitleg'] ."')";
mysql_query($query) or die(mysql_error());
header("location: forum.php");
}
}
?>
|
Eerst verbinden met de database, daarna nakijken of de naam en het password overeenkomen met die van de admin.
Vervolgens gaan we controleren of er op submit is gedrukt, zo niet dan geven we een formuliertje weer.
Als er dan op submit is gedrukt dan zetten we alle gegevens in de tabel categorien en verbinden we de admin door naar forum.php.
Nu is er nog een klein ding dat we moeten toevoegen, voor degeen die hebben opgelet weten misschien nog dat ik heb gezegt helemaal op het begin dat we die link voor een nieuw topic te maken later zal komen.
Dat is dan nu:
<?php
echo "<a href="forum.php?categorie_id=". $_GET['categorie_id'] ."&action=nieuwtopic">Nieuw Topic</a>";
?>
|
Zo ziet die eruit. We sturen via de header het topic idee door, en geven een action mee, namelijk nieuwtopic, die controleren we dan straks in de if en dan laten we de gebruiker een nieuw topic toevoegen.
Dit was het dan, ik hoop dat ik je de basis heb geleerd van hoe je een forum maakt.
Dat ik je het systeem heb laten snappen.
Verdere uitwerking kan je zelf, en hoogstwaarschijnlijk komt een zeer uitgebreide, beveiligde + een deftige lay out van dit forum bij de scripts.
Hopelijk kan je verder, en kan je misschien de lay out wat verder uitwerken.
Ik moet toegeven dat de lay out nogal meevalt in FireFox vergeleken met Internet Explorer, maar zeker niet goed genoeg om te gebruiken.
Ik wens je nog veel succes in het ontdekken van de wondere wereld genaamd PHP.
Heb je nog vragen? Stel deze dan op het forum.
|