If you have been online long enough and use the web frequently you most likely have run into web forums by now. They have been around for a very long time. Usenet Groups are possibly the closest resemblance to web forums and they have been around long before the world wide web. Web forums, sometimes also referred to as Bulletin Boards (BBs), are an essential tool of online web-based communication amongst online communities, both small and large.
The general idea is based on the concept of a centralized server that stores and displays messages from various users. If you’ve ever wondered how they work or how you could build your very own web forum from scratch this tutorial attempts to explain some of the fundamental underlying concepts. You will need a MySQL database to be able to store the messages – or whatever DBMS you prefer – along with a Server-Side-Scripting language such as PHP in order to process and handle requests from the various users of the forum.
Forums are actually rather simple in design. They work on a somewhat hierarchical system. The messages on forums are normally threaded, meaning they fit into neat little categories and span inwards. The messages are called posts. Every time a user submits a post to the forum it must be associated with some specific thread. The thread is a type of category that belongs to the forum. Most web forums will have multiple forums on the same web site, usually closely related in subject.
So in order to build our forum we will first need to design a database. For the purpose of demonstration in this tutorial we will use MySQL. We’ll call our MySQL database _forum and use the MyISAM engine, as this provides a very fast means of sending and retrieving multiple queries at once. The MyISAM storage engine is not a transactional storage engine. It provides table-level locking, which means it can slow down significantly if too many people are attempting to write to the database at once. However, for the purpose of an online web forum this should more than suffice. Given that the majority of forum users are reading rather than contributing to the forum and that the expected impact should not exceed a few hundred concurrent connections for even a large forum (this could potentially support hundreds of thousands of users).
The database will require four basic tables to become a fully functioning forum database:
- The Forums Table – Stores information about all the forums available to the web site
- The Threads Table – Stores all the information about threads associated to the forums available in the forums table
- The Posts Table – Stores all the messages posted to each of the threads in our forums
- The Users Table – Stores the information about the registered users of the forum
The bulkiest of these tables will probably be the Posts Table, since it is likely to handle – potentially – millions of records over a very long period of time. Here is a simple MySQL structure of the aforementioned tables to give you an idea.
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -- -- Database: `_forum` -- -- -------------------------------------------------------- -- -- Table structure for table `forums` -- CREATE TABLE IF NOT EXISTS `forums` ( `id` int(12) NOT NULL AUTO_INCREMENT, `user` int(12) NOT NULL, `title` varchar(256) NOT NULL, `desc` varchar(256) NOT NULL, PRIMARY KEY (`id`), KEY `user` (`user`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; -- -------------------------------------------------------- -- -- Table structure for table `threads` -- CREATE TABLE IF NOT EXISTS `threads` ( `id` int(12) NOT NULL AUTO_INCREMENT, `user` int(12) NOT NULL, `forum` int(12) NOT NULL, `title` varchar(256) NOT NULL, `desc` varchar(256) NOT NULL, PRIMARY KEY (`id`), KEY `user` (`user`), KEY `forum` (`forum`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; -- -------------------------------------------------------- -- -- Table structure for table `posts` -- CREATE TABLE IF NOT EXISTS `posts` ( `id` int(12) NOT NULL AUTO_INCREMENT, `user` int(12) NOT NULL, `thread` int(12) NOT NULL, `subject` varchar(256) DEFAULT NULL, `text` text NOT NULL, PRIMARY KEY (`id`), KEY `user` (`user`), KEY `thread` (`thread`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE IF NOT EXISTS `users` ( `id` int(12) NOT NULL AUTO_INCREMENT, `name` varchar(12) NOT NULL, `pass` varchar(256) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
As you can see every forum, thread, and post are each assigned a unique ID number in their respective tables. That number is sequential so it is set to auto-increment. Every time a new forum, thread, or post is added it is assigned the very next number in the sequence. These IDs are also indexed to allow us easier look ups in the database queries.
Now lets write some simple script to test out the functionality of our database. For the purpose of this tutorial we will use PHP. The script below demonstrates the most basic way to read from the database and output the data in the same traditional fashion that most web forums work. We start by listing all the forums on the front page. Each forum provides a link that leads to viewing all the threads within said forum. Now since each thread will also provide a link to view all the posts associated with this thread we are beginning to see how more and more data ties together in a web forum and this can make it a little more complicated down the road if the integrity of our data structure does not remain intact.
<?php
/*
# Lets just assume this entire script is stored in a file named forum.php
# Whenever forum.php is called without GET arguments it will list all of the forums available in the database. Because it outputs the HTML with the proper GET arguments included in the links for each forum/thread all the user has to do is simply click on a link and the data is generated for them automagically. That's pretty much how a forum works.
#
# Of course if you want to try this script you will need to set these variables to your database name, user, and password.
*/
$db = 'urdbname';
$dbuser = 'urdbuser';
$dbpass = 'urdbpass';
$dbhost = 'localhost';
$link = mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($db, $link);
// List Forums
function GetForums() {
global $link;
$result = mysql_query("SELECT COUNT(*) FROM forums", $link);
$forums = mysql_fetch_row($result);
$result = mysql_query("SELECT COUNT(*) FROM users", $link);
$users = mysql_fetch_row($result);
$put = "There are " . $forums[0] . " forum(s) and " . $users[0] . " user(s) in the database.";
for ($i = 0; $i < $forums[0]; $i ++) {
$data = mysql_fetch_row(mysql_query("SELECT * FROM forums LIMIT ".$i.",1", $link));
$put .= "<p><a href='?f=".$data[0]."'>" . $data[2] . "</a> - <i>" . $data[3] . "</i></p>";
}
return $put;
}
// List Threads
function GetThreads($var) {
global $link;
$forumnum = $var;
$result = mysql_query("SELECT COUNT(*) FROM threads WHERE forum = '".$forumnum."'", $link);
$threads = mysql_fetch_row($result);
$result_test = mysql_num_rows(mysql_query("SELECT * FROM forums WHERE id = '".$forumnum."'", $link));
if (!$result_test) { echo "This forum does not exist in the database..."; exit; }
$forum = mysql_fetch_assoc(mysql_query("SELECT * FROM forums WHERE id = '".$forumnum."'", $link));
$put = "There are ".$threads[0]." threads in the '".$forum['title']."' forum.";
for ($i = 0; $i < $threads[0]; $i ++) {
$data = mysql_fetch_row(mysql_query("SELECT * FROM threads WHERE forum = '".$forum['id']."' LIMIT ".$i.",1", $link));
$put .= "<p><a href='?t=".$data[0]."'>" . $data[3] . "</a> - <i>" . $data[4] . "</i></p>";
}
return $put;
}
// List Posts
function GetPosts($var) {
global $link;
$threadnum = $var;
$result = mysql_query("SELECT COUNT(*) FROM posts WHERE thread = '".$threadnum."'", $link);
$posts = mysql_fetch_row($result);
$result_test = mysql_num_rows(mysql_query("SELECT * FROM threads WHERE id = '".$threadnum."'", $link));
if (!$result_test) { echo "This thread does not exist in the database..."; exit; }
$thread = mysql_fetch_assoc(mysql_query("SELECT * FROM threads WHERE id = '".$threadnum."'", $link));
$put = "There are ".$posts[0]." posts in the '".$thread['title']."' thread.";
for ($i = 0; $i < $posts[0]; $i ++) {
$data = mysql_fetch_row(mysql_query("SELECT * FROM posts WHERE thread = '".$thread['id']."' LIMIT ".$i.",1", $link));
$put .= "<p>" . htmlspecialchars($data[4]) . "</p>";
}
return $put;
}
if ($_GET['f']) $ui = GetThreads($_GET['f']); elseif ($_GET['t']) $ui = GetPosts($_GET['t']); else $ui = GetForums();
echo $ui;
mysql_close($link);
?>
This code will merely show you how to read and display data from the database. Now all we need is a way for users to add their posts to the threads. We can accomplish this by using an HTML form. The elements of the HTML form we will need are very basic. A textarea is used to capture the users message and a submit button is used to send the request to the script. Here is some very basic HTML code to write a form to your script.
<form id="form1" name="form1" method="post" action=""> <label> <textarea name="text"></textarea> </label> <label> <input type="submit" name="Submit" value="Submit" /> </label> </form>
Next the script needs to handle the request through $_POST and add the post to the database. The example below is a simplistic approach to using post data from the form.
$msg = $_POST['textarea'];
$msg = mysql_real_escape_string($msg); // Minimalistic method for preventing html/script injection
$result = mysql_query("INSERT INTO posts (thread, text) VALUES ('".$var."', '".$msg."')", $link);
Of course you will need to make sure your code has some basic error handling methods as well as best security practices to prevent nuances like mysql injections or html/script injections as these examples are meant for demonstration and educational purposes only. So in a nut shell that is how web forums work and, as outlined in this tutorial, you now have the fundamental building blocks of a web forum. You would need to include some method of maintaining user sessions, for example by storing login information such as usernames and passwords in the users table of the database. This will allow you to keep track of who has posted what messages and the threads they start. Also it might be a good idea to add a time column to the forums, threads, and posts tables in order to keep a record of when each record was added to the database. Other suggestions may include adding a paging system that will divide forums/threads/posts in to pages so as not to have the user load hundreds of posts or threads in one page. This will also reduce the overhead on your mysql server. Such methods are not described here in detail. Rather they are left for a more conclusive technical documentation or implementation. The purpose of this tutorial was to merely introduce the basic concepts of web forums using MySQL and PHP.
win says:
I happen to land to this site and it is a properly written read, a little on the short side, but a fairly sufficient one.
I very much adore the layout too, it is very easy to navigate.
online games says:
I like the layout and navigation of the blog, easy on the eyes and nicely put together.
a lot of other sites are just way too stuffed with advertisements
sheriframadan.com says:
Tank you. Greetings from the Speedy DNS.
billige autoversicherung says:
last few days our group held a similar discussion about this subject and you point out something we haven’t covered yet, thanks.
- Kris
Fuscowscuse says:
I found lots of valuable information in this forum
Greetings to all
computer technician says:
this post is very usefull thx!