Simple PHP forum

This tutorial shows the techniques required to make a simple PHP forum. It consists of four pages, one for displaying the forums, one for the topics, one for the replies and finally a page to post new topcis / replies.

Database

Below are the database tables that are required for this code.
CREATE TABLE  `main` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `name` text NOT NULL,
  `lastposter` varchar(200) NOT NULL,
  `lastpostdate` int(11) NOT NULL,
  `topics` int(11) NOT NULL default '0',
  `replies` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`)
)

CREATE TABLE `replies` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `topicid` int(11) unsigned,
  `message` text NOT NULL,
  `subject` text NOT NULL,
  `poster` text NOT NULL,
  `date` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
)

CREATE TABLE  `topics` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `forumid` int(11) unsigned,
  `message` text NOT NULL,
  `subject` text NOT NULL,
  `poster` text NOT NULL,
  `date` int(11) NOT NULL,
  `lastposter` varchar(200) NOT NULL,
  `lastpostdate` int(11) NOT NULL,
  `replies` int(11) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
)

Displaying the forum list

This simple forum will consist of three elements. The first will be a list of forums, then each forum will have a list of topics and finally each topic will have a number of replies. We firstly need to set up the list of forums, these can be manually added to the database.
mysql_connect('localhost','user','password');
mysql_select_db('db');
$query1 = mysql_query('SELECT * FROM main ORDER BY id DESC'); 
This code connects to the database and selects the forums. We now need to display the information.
while ($output1 = mysql_fetch_assoc($query1))
This loop will get all the rows from the database and the loop will end when there are no rows left. Below is an example of getting the information from the database and printing it to the document. Note the link is to topics.php.
echo '<td><a href="topics.php?id='.$output1['id'].'">'.$output1['name'].'</a></td>';

Displaying topics

Now that the basic forums are set up we can list the topics for each one. The link from the main page sets an id variable that we can use to select the appropriate topics.
ob_start();
$id = (int) $_GET['id'];
if ($id < 1)
{
	header('Location: forum.php');
	exit();
}
ob_end_clean();
We start output buffering (ob_start()) to ensure that no headers are sent because if the topic id given is less than one, we will redirect the user to the main forum page.
mysql_connect('localhost','user','password');
mysql_select_db('db');
$output1 = mysql_fetch_assoc(mysql_query("SELECT name FROM main WHERE id = $id"));
echo $output1['name'];
Now that we have a topic id we can get all the topics that match that it. We firstly get the forum name associated with the id and print it out.
$query2 = mysql_query("SELECT * FROM topics WHERE forumid = '$id' ORDER BY id DESC");
$query3 = mysql_num_rows($query2);
Within the database table design for the topics there is a foreign key (called forumid) which links each topic to the id of the forum. Above the number of topics for the given forum is found. If there are no topics a message is displayed, otherwise the topics are printed out.
if ($query3 == 0)
	echo '<td colspan="5">No Topics</td>';
If there are no topics for this forum then we will inform the user. Otherwise a table is built with links to the replies for each topic. Note the link to replies.php. We will use mysql_fetch_assoc because we will refer to the fields in the array by name rather then by number.
while ($output2 = mysql_fetch_assoc($query2))
    echo '<td><a href="replies.php?id='.$output2['id'].'">'.$output2['subject'].'</a></td>';
if(empty($output2['lastposter']))
	echo '<td colspan="2">No replies</td>';
else {
    echo '<td>'.$output2['lastposter'].' @ '.date('d-m-y G:i', $output2['lastpostdate']).'</td>';
    echo '<td>'.$output2['replies'].'</td>';
}
We will keep track of the last poster for each forum and topic. If there are no posts a message is displayed otherwise the name and date of the last post is printed.
<form name="form1" id="form1" method="post" action="forumpost.php?type=topics&id=<? echo $id; ?>">
Finally on this page is the form that the user can use to post a new topic. It sends two pieces of information to the forum post page, the id of the topic and the type of post (in this case ‘topic’).

Displaying replies

This page is very similar to the topics page. It gets an id as an input which it uses to get all the replies. Each reply has a foreign key (topicid) which links to a particular topic and this is used to get all the relevant replies.
<form name="form1" id="form1" method="post" action="forumpost.php?type=replies&id=<? echo $id; ?>">
The form to post a reply is also very similar to the topics page, but the type is now set to ‘replies’ as this form can only post new replies for each topic.

Posting replies

Now that we have have set up the pages for the forum, topics and replies we need a page that will insert the new topics and replies into the database.
ob_start();
$id = (int) $_GET['id'];
$type = $_GET['type'];
if ($id < 1 || ($type != 'replies' && $type != 'topics'))
{
	header('Location: forum.php');
	exit();
}
ob_end_clean();
This code checks that the id is greater than one and that the type given is one of the two constants that we defined (topics or replies).
function clear($message)
{
	if(!get_magic_quotes_gpc())
		$message = addslashes($message);
	$message = strip_tags($message);
	$message = htmlentities($message);
	return trim($message);
}
We now define a function to check the user input for any HTML tags, and remove any quotes, so that the information can be put into the database.
if($type == 'topics')
{
	$query = mysql_fetch_assoc(mysql_query("SELECT topics FROM main WHERE id = '$id'"));
	$topics = $query['topics'] + 1;
	mysql_query("UPDATE main SET topics = '$topics', lastposter = '$poster',
              lastpostdate = '$date' WHERE id = '$id'");
	mysql_query("INSERT INTO topics (id , forumid , message , subject, poster, 
              date, lastposter, lastpostdate, replies)
              VALUES ('', '$id', '$message', '$subject','$poster', '$date', '', '', '0')");
	echo 'Topic Posted.<a href="topics.php?id='.$id.'">View Topic</a>';
If the type of post is a topic then we need to update multiple rows in the database. We firstly need to update the topics field of the forum to add one to the number of topics. We do this by using the id input to get the forum and the current number of topics. The topic count is incremented and the forum is updated (the current poster is also added as the latest poster and the last post date is updated). Finally the topic is added to the database.
else
{
	$query = mysql_fetch_assoc(mysql_query("SELECT replies, forumid FROM topics WHERE id = '$id'"));
	$replies = $query['replies'] + 1;
	$id2 =  $query['forumid'];
	mysql_query("UPDATE topics SET replies = '$replies', lastposter = '$poster',
              lastpostdate = '$date' WHERE id = '$id'");
	$query = mysql_fetch_array(mysql_query("SELECT replies FROM main WHERE id = '$id2'"));
	$replies = $query['replies'] + 1;
	mysql_query("UPDATE main SET replies = '$replies', lastposter = '$poster',
              lastpostdate = '$date' WHERE id = '$id2'");
	mysql_query("INSERT INTO replies (id , topicid, message, subject, poster, date)
              VALUES ('', '$id', '$message', '$subject','$poster', '$date')");
	echo 'Reply Posted.<a href="replies.php?id='.$id.'">View Reply</a>';
If the type of post is a reply then we need to do a similar database update but this time we need to add one to the number of replies. Using the id input we get the number of replies and the forum id from the related topic. We then update the number of replies and update the last poster and last post date fields to the current poster. Using the forum id we then also update the forum so that the last poster / last post date is updated and a total number of replies is kept. Finally the reply is added to the database.

Post a Comment

0 Comments