You've seen it at least once right? Guestbook is one of the most common thing
to find in a website. In this tutorial we'll create a guestbook using PHP and
MySQL.
I have split this tutorial into two section, each covering a specific feature
of the guestbook.
- Creating The Sign-Guestbook Form
This part will cover creating the database tables, the guestbook form and the
process of saving the entry to database
- Viewing The Entries
You want to see the guestbook entries of course. This section covers fetching
the entries from database and put int into an HTML table. You will also learn
to show the entries in multiple pages using MySQL paging.
<!--li> Guestbook Admin
This is the page where you can delete unwanted entries.</li-->
I think you should take a quick look what the finished guestbook look like.
Just click here
to see it.
Creating The Sign-Guestbook Form
We start by creating the table to store the data, guestbook.
There are six fields in the guestbook table:
1. |
id |
: |
the unique identifier for an entry in the guestbook |
2. |
name |
: |
the visitor's name |
3. |
email |
: |
visitor's email address |
4. |
url |
: |
visitor's website url, if she has one |
5. |
message |
: |
the message |
6. |
entry_date |
: |
when did this entry added |
I have put the SQL query needed to create the table in guestbook.txt.
Below is the HTML form code. It's pretty simple, we have text box for name,
email and url plus a textarea to hold the message. The submit button is attached
with a javascript function because we want to check the input values before
the page is submitted.
Example :guestbook.php
Source code :
guestbook.phps, guestbook.txt
<form method="post" name="guestform">
<table width="550" border="0" cellpadding="2"
cellspacing="1">
<tr>
<td width="100">Name *</td> <td>
<input name="txtName" type="text" size="30"
maxlength="30"></td>
</tr>
<tr>
<td width="100">Email</td>
<td>
<input name="txtEmail" type="text"
size="30" maxlength="50"></td>
</tr>
<tr>
<td width="100">Website URL</td>
<td>
<input name="txtUrl" type="text" value="http://"
size="30" maxlength="50"></td>
</tr>
<tr>
<td width="100">Message *</td> <td>
<textarea name="mtxMessage" cols="80"
rows="5"></textarea></td>
</tr>
<tr>
<td width="100"> </td>
<td>
<input name="btnSign" type="submit"
value="Sign Guestbook" onClick="return checkForm();"></td>
</tr>
</table>
</form>
Below is the javascript code to check the input form. The checkForm()
function is called when the "Sign Guestbook" button is clicked.
|
The mandatory fields are name and
message so if either is empty we pop an alert box to tell the visitor
to enter the name and message. Email is not a mandatory field so we only check
if in an email address is entered but we won't complain if there's none .
function checkForm()
{
// the variables below are assigned to each
// form input
var gname, gemail, gurl, gmessage;
with(window.document.guestform)
{
gname = txtName;
gemail = txtEmail;
gurl = txtUrl;
gmessage = mtxMessage;
}
// if name is empty alert the visitor
if(trim(gname.value) == '')
{
alert('Please enter your name');
gname.focus();
return false;
}
// alert the visitor if email is empty or
// if the format is not correct
else if(trim(gemail.value) != '' && !isEmail(trim(gemail.value)))
{
alert('Please enter a valid email address
or leave it blank');
gemail.focus();
return false;
}
// alert the visitor if message is empty
else if(trim(gmessage.value) == '')
{
alert('Please enter your message');
gmessage.focus();
return false;
}
else
{
// when all input are correct
// return true so the form will submit
return true;
}
}
/*
Strip whitespace from the beginning and end of a string
*/
function trim(str)
{
return str.replace(/^\s+|\s+$/g,'');
}
/*
Check if a string is in valid email format.
*/
function isEmail(str)
{
var regex = /^[-_.a-z0-9]+@(([-a-z0-9]+\.)+(ad|ae|aero|af|ag|
ai|al|am|an|ao|aq|ar|arpa|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|
bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|
ck|cl|cm|cn|co|com|coop|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|
ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gh|
gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|
il|in|info|int|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|
kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mil|mk|
ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|
ne|net|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|org|pa|pe|pf|pg|ph|pk|
pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|
si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|
tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|
vu|wf|ws|ye|yt|yu|za|zm|zw)|(([0-9][0-9]?|[0-1][0-9][0-9]|[2]
[0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2]
[0-4][0-9]|[2][5][0-5]))$/i;
return regex.test(str);
}
|
After the form is submitted our job turns to saving the input into the database.
In the code below I include config.php
and opendb.php which
contain the database configuration and the code needed to open a connection
to MySQL. It's a good practice to put these actions in separate file. That way
everytime you need to connect to MySQL you can include these files instead of
rewriting the code. Also you can change the database information from just one
file instead of changing it in every file that use MySQL. To see what the content
of config.php, opendb.php and closedb.php go to : Connecting
to MySQL database
<?php
include 'library/config.php';
include 'library/opendb.php';
if(isset($_POST['btnSign']))
{
include 'library/config.php';
include 'library/opendb.php';
$name = trim($_POST['txtName']);
$email = trim($_POST['txtEmail']);
$url = trim($_POST['txtUrl']);
$message = trim($_POST['mtxMessage']);
if(!get_magic_quotes_gpc())
{
$message = addslashes($message);
}
// if the visitor do not enter the url
// set $url to an empty string
if ($url == 'http://')
{
$url = '';
}
$query = "INSERT INTO guestbook (name,
email,
url,
message,
entry_date)
VALUES
('$name',
'$email',
'$url',
'$message',
current_date)";
mysql_query($query) or die('Error, query failed');
header('Location: ' . $_SERVER['REQUEST_URI']);
exit;
}
?>
The script check if the $_POST['btnSign'] variable
is set. If it is then the "Sign Guestbook" button must have been clicked
and now we can read name, email, url and message from the $_POST
global variable. After that we create an INSERT query string and execute the
query using mysql_query().
Sometimes a message can contain single quotes, we need to escape these single
quotes ( replacing it with \' ) otherwise MySQL will think that it's the end
of a string and the query will fail. We use the addslashes()
function to escape the string.
Unfortunately some web hosts set the magic_quotes_gpc
setting on. This will make values containing single-quotes in $_GET,
$_POST and $_COOKIE will
be automatically escaped. If we use addslashes()
when the string is already escaped the result would be a mess.
To check if magic_quotes_gpc is On use get_magic_quotes_gpc().
If it returns true then we don't have to call addslashes().
Ok, now affter all input is ready we can build the query string to enter the
name, email, url, message and entry date. Note that for the
entry_date field we use current_date. This
is not a PHP variable or function, it's a built in MySQL function that returns
( guess what? ) the current date.
You also see that I didn't explicitly insert the value of id
field. This is because id is set as auto_increment
so when we insert a new row into the table a new value for id
is automatically generated ( incremented for each new row).
After inserting the new guestbook entry the next thing we do is redirect
back to current page using header('Location: ' . $_SERVER['REQUEST_URI']);
Why?
The redirect is just to prevent double submission. Suppose we don't use
the redirect and the visitor hit the refresh button after signing up the guestbook
then the form will be submitted again.
Note : If you get this kind of error message
Warning: Cannot modify header information - headers
already sent by (output started at C:\webroot\guestbook\library\config.php:7)
in C:\webroot\guestbook\guestbook.php on line 43
this mean the redirect failed because you already sent something to the
browser. I got the error message above because i "accidentally"
have a space right after the closing tag ( ?> ) in config.php.
By removing this space the error is fixed.
This kind of errror is actually very common to see when your code is sending
headers and fixing it is easy like the example above. Just check the file
pointed by the error message and see if you accidentally sent ( print ) anyhing
to the browser.