Step 1: prerequisites
The Guest book prerequisites are quite similar to the Mini-Chat ones.
- Being able to read in a MySQL table
- Being able to write in a MySQL table
- Being able to count the number of entries in a table
- Being able to use the forms properly
What you have learnt in the previous chapter on forms is
really important. Don't hesitate to refer to it, because combining forms and MySQL enables to create very powerful scripts!
Step 2: preparing your script
As usual,
never tackle a PHP script before having prepared it: you must think about its functioning if you don't want to find yourselves completely lost in your code.
First, you must ask yourselves what the practicalities of your Guest book will be.. What will the guest be able to do in it? He can leave his nickname and a message, he will be registered in a table like the others.
We can get started by creating this very table. We will call it "Guestbook", and it will be made of 3 fields:
- id: as usual, we create an id to number each field. In MySQL, this id has an INT type and I selected "Primary" like I told you to do for the id fields. Besides, I chose "auto increment" for every id number to appear automatically at each new entry.
- nickname: it is the guest's nickname. It is of type VARCHAR, and you mustn't forget to specify its "size" when you create the table. A 255 size seems enough to me (you don't have any 256 character nickname, do you?
- message: this is where you store the message left by the guest. This field is of type TEXT.
I suggest that we put the form on top of the page, and the list of messages below... This might definitely make you think of the Mini-Chat!
Here is a preview of what you might be able to make:
Once again, I concede it looks ugly. But design is very easy to create (a background colour, an image and that's it

).
The most important thing is to make this code work. Believe me, you will have the opportunity to embellish the styles afterwards
The procedure to register is the same as Mini-Chat's. In the interest of security, don't forget the htmlspecialchars and the mysql_real_escape_string (because we're going to use the variables in SQL queries).
Well, you might have noticed the main difference between the Mini-Chat and the Guest book: we don't want to display only the last 10 messages here, we want to display them ALL, which is a lot on the same page. So,
we will create pages automatically to display something like 20 messages per page for instance.
This might seem a bit vague: how can we create pages automatically on PHP? Well, you'll see that it might not be what you expected
- We retrieve the total number of messages ($totalOfMessages) with the MySQL query I taught you.
- We calculate the number of pages there will be. How? With a simple mathematical division!
$numberOfPages = $totalOfMessages / $numberOfMessagesPerPage;
Example: if we have 100 messages, and we want 20 messages per page => 100 / 20 = 5 pages! Quite simple, isn't it?
Obviously, you have to give a value to $numberOfMessagesPerPage. I'd put 20, but you can put whatever you want. The advantage is that if you want to change the number of messages per page later on, you'll just have to modify the variable's value!
But... But... If there are 102 messages for instance, 102 / 20 = 5.1 pages! We cannot have 5.1 pages. Therefore we will have to create a sixth page that will only contain 2 messages.
There is a PHP mathematical function that is going to be quite helpful:
ceil. It returns the higher integer: for 5.1, it will return 6! That's exactly what we need. So if we want to be sure of the number of pages to be created, we'd rather use the following instruction:
$numberOfPages = ceil ($totalOfMessages);
3. Now that we have the number of pages, we're going to write all the links to each of these pages (1 2 3 4 5 6...). Clicking on one of these numbers will direct to the corresponding page.
4. But to what page do these links point to? In fact, we will reopen the same page, but with a different parameter. We will add a ?page=4 for instance if we want to go to page 4. If the Guest book page is called "guestbook.php", the link to page 4 will be:
<a href="guestbook.php?page=4">4</a>
If I take the Guest book preview I showed you before as an example, here are the links to pages 1 and 3:
This is what we want to have.
I know it looks like you have to get through some terrible mathematical things to get there. But just tell yourselves that it is only a simple division. What might actually make you uncomfortable is that you are discovering the pages trick for the first time.
We won't create a different PHP file for each page (I'm not that crazy

). There will simply be a variable $_GET['page'] that will indicate which page we're on.
Remember to check if $_GET['page'] exists. If it's not the case, then the guest is uploading the Guest book for the first time: put him on page 1 (the most recent one).
OK, now I have retrieved the total number of messages and I have written the links to each of these pages with a loop. How do I do to display only the page messages?
Remember: $_GET['page'] is a variable containing the number of the page that the guest is reading. Just modify the SQL query, using LIMIT. And don't forget that we want to display the messages in decreasing order (the most recent first).
So we will have to think about the SQL query a little... I'm not giving you the answer, you ought to look for it by yourselves.
Just so that you know, I had to think it over for a good 5 minutes to figure it out... Surprise! Although I may look like one, I am not a robot: I have to think before I make my scripts work, just like you
And after that, you're almost done
Displaying the query's result in a loop is the only thing remaining. And you know how to do it. If everything works right, the page's messages will display!
Step 3: your turn!
Phew! I have dissected the whole problem for you. Now you know the basics of writing a script
Please take your time, we're not in a hurry.
Take care over the page system. Besides, it's the only thing that differs from the Mini-Chat practical.
Most important: don't give up too soon. It might be a good thing to go and have a nap when you're starting to feel the headache coming. Quite often, a bunch of ideas can flourish while awakening!
By the way, don't be afraid of creating other variables if necessary. It is sometimes a good means of simplifying a problem!
Step 4: correction
Shall we correct now?
Here is roughly what you had to do:
Code: PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<title>Guest book</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
form, .pages
{
text-align:center;
}
</style>
</head>
<body>
<form method="post" action="guestbook.php">
<p>You like my website? Leave me a message!</p>
<p>
Nickname: <input name="nickname" /><br />
Message :<br />
<textarea name="message" rows="8" cols="35"></textarea><br />
<input type="submit" value="Send" />
</p>
</form>
<p class="pages">
<?php
mysql_connect("localhost", "np", "password");
mysql_select_db("phptutorial");
// --------------- Step 1 -----------------
// We store the messages sent
// -----------------------------------------
if (isset($_POST['nickname']) AND isset($_POST['message']))
{
$nickname = mysql_real_escape_string(htmlspecialchars($_POST['nickname'])); // We use mysql_real_escape_string and htmlspecialchars for security interests
$message = mysql_real_escape_string(htmlspecialchars($_POST['message'])); // The same for the message
$message = nl2br($message); // As we are using a textarea, we have to replace the "Enter" key pressed by <br />
// At last we can save:o)
mysql_query("INSERT INTO guestbook VALUES('', '" . $nickname . "', '" . $message . "')");
}
// --------------- Step 2 -----------------
// We write the links to all pages
// -----------------------------------------
// We put the number of messages per page we want in a variable
$numberOfMessagesPerPage = 5; // Try to change this number to see :o)
// We retrieve the total number of messages
$return = mysql_query('SELECT COUNT(*) AS nb_messages FROM guestbook');
$data = mysql_fetch_array($return);$totalOfMessages = $data['nb_messages'];
// We calculate the number of pages to be created
$numberOfPages = ceil($totalOfMessages / $numberOfMessagesPerPage);
// Then we make a loop to write the links to each of the pages
echo 'Page : ';
for ($i = 1 ; $i <= $numberOfPages ; $i++)
{
echo '<a href="guestbook.php?page=' . $i . '">' . $i . '</a> ';
}
?>
</p>
<?php
// --------------- Step 3 ---------------
// Now, we're going to display the messages
// ---------------------------------------
if (isset($_GET['page']))
{
$page = $_GET['page']; // We retrieve the number of the page indicated in the address (guestbook.php?page=4)
}
else // The variable does not exist, it's the first time we are loading the page
{
$page = 1; // We're going on page 1 (by default)
}
// We calculate the number of the first message we take for the MySQL LIMIT
$firstMessageTodisplay = ($page - 1) * $numberOfMessagesPerPage;
$reply = mysql_query('SELECT * FROM guestbook ORDER BY id DESC LIMIT ' . $firstMessageTodisplay . ', ' . $numberOfMessagesPerPage);
while ($data = mysql_fetch_array($reply))
{
echo '<p><strong>' . $data['nickname'] . '</strong> wrote :<br />' . $data['message'] . '</p>';
}
mysql_close(); // Don't forget to close the connection to MySQL ;o)
?>
</body>
</html>
|
Please note: I disabled the addition of messages in this Guest book example on purpose to avoid jumbling everything up
So you can read the messages but you cannot add any. Make a local test of this script with WAMP, and you'll see that it works, of course
Obviously, I have absolutely no doubt that 90 % of you struggled to finish this script (or froze up somewhere).
I will never say it too much: do not panic, it's perfectly normal. The practical forces you to think, and the "correction" allows you to say: "OK, that was it indeed!".
This is what is really rewarding for you
How about getting some explanations about this code?
As you can see, it is clearly separated in 3 parts:
1.
Part 1: We store the messages sent: as usual, we check if the variables $_POST['nickname'] and $_POST['message'] exist. If they do, that means the guest just sent a message.
So we make a mysql_real_escape_string and a htmlspecialchars on each of these variables to avoid HTML appearing in your Guest book. We also use a nl2br for $_POST['message']: indeed, if the guest pressed the "Enter" key in the textarea, we have to use nl2br as I taught you to transform them into tags <br />
After that, you only have to send a query to MySQL so that it can save the message in the table.
2.
Part 2: We write the links to each of the pages: OK, now it's starting to get a bit awkward. I already went through this quite a lot, so I'm just going to remind you briefly what is happening.
1. We define a variable $numberOfMessagesPerPage. I chose 20 per page. The advantage of using a variable to remember the number of messages per page is obvious: if you decide to change the number of messages later on, you'll just have to change this line instead of the entire code.
2. We retrieve the total number of messages with a MySL query as we saw it in Part II. We put this number in $totalOfMessages
3. Then, we calculate the number of pages to be created with the division I told you about. I remind you that the ceil allows to have an integer number for your pages (instead of 5.2 pages

)
4. Finally, we have to make a loop to write down all the page numbers (and the corresponding links). I chose to make a for loop because I found it convenient in this case, but if you made a while that's OK too.
3.
Part 3: Now we're going to display the messages: there is a little difficulty remaining, and I did let you solve this one by yourselves (if not, I might as well give you the answer straight away

). We have 3 things to do:
1. We check if $_GET['page'] exists (with an isset). If that is the case, we place this page number in $page. If it is not, it's because the page's address is "Guestbook.php" (there is no page number indicated in the address). So we give $page the value 1.
2. Now that we have a good page number in $page, we must calculate something for the query. Indeed, we're going to make an ORDER BY id DESC LIMIT ?, ?
What shall we put into each of these question marks?
- The first question mark refers to the number of the first message to take (which has nothing to do with the id). I remind you that the first message bears the number 0. As we take the messages in decreasing order, we shall start by the last one. If we are on page 1, ($page - 1) * $numberOfMessagesPerPage will return (1-1) * 20 = 0 * 20 = 0. We will then take from message n°0 (the first one), and as we're on decreasing order, it corresponds to the very last message saved. So, on page 1, we will display the last message written in the Guest book first: exactly as we wanted!
- The second question mark is an easy one: the number of entries to retrieve in the table, i.e $numberOfMessagesPerPage since we only want to take the X messages of the page.
3. Phew, the worst is over. The only thing remaining is the SQL query to take only the messages needed, and make a loop to display the page message.
Well, yes, this script was a bit longer than the other ones, hence the interest of having cut it into several parts!
Take as much time as you need to understand properly how this paging system works. Believe me, it's worth it and you might need it for one of your future scripts
Step 5: improve this script!
We could do many more things on such a script. I'll suggest you a few guidelines to improve it, but I won't correct them for you (otherwise I won't see the end of it

).
I believe it's a good idea that you keep on thinking about the script's improvement by yourselves. My role here is merely to give you some ideas.
And don't forget that I'm not leaving you behind: if you freeze on an improvement, you can go and ask for help on the forum!
- Improve the design, the presentation I made is really a basic one. It's easy to do and only requires that you modify the HTML code.
- Display the total number of messages posted in your Guest book, it's convenient to see it written (very easy to make, if you don't manage it's not that bad
)
- Add a drop down box in your form. This field will enable the guest to choose a grade to mark your site (put the choices 0 1 2 3 ... 18 19 20).
Add a field "grade" of INT type to your table Guestbook (if you look up the PHPMyAdmin functions it is easy to add a field even when the table has been created).
Doing so, in addition to the guest's message, you display the grade he gave your site.
- Even better, work out the average of the grades that were given to your website, and display it on top (example: "Average grade: 14.6 / 20". I remind you that to find out what the average is, you have to do (grade1 + grade2 + grade3 + ...) / totalOfMessages
- If we want to be perfect regarding security, there's a little detail that I left out because I didn't want to complicate this script too much. Can you see the page number passed through the address with $_GET['page']? Well, if the guest modifies this page number manually, he can put anything even HTML code!
In this case, it's not so bad, the HTML code will not be displayed and it will just make the script bug. But to be "clean", we'd have to use the function intval on $_GET['page'] to transform this page number into a figure. Actually, we'd write the following line:
$page = intval($_GET['page']);
It won't kill you if you don't do it, but you must know that good PHP code writers do this kind of things. I can't blame you for not doing it, you didn't know this function 