Accessible Guestbook Script With SPAM Protection

Diese Seite auf Deutsch lesen.

Version

Current version: V4.1 (2016/11/14) - gb_v4.1.zip (181 KB)

News

The Script has been tested successfully under PHP 7.0.

The code is written in object-oriented style. See the example file gb.php for more information. Furthermore you can set a timezone for the script since PHP requires a timezone setting (this is the case since PHP5) which might not be set in all PHP environments.

See change log for more information.

Features

Installation

Unzip the contents and upload all files and directories to your webspace.

The file /gb/scripts/gb-data.xml must be writable for the PHP process. The required file permissions need to be set via the FTP client software.

Integration

The script should be easy to integrate into an existing website. There are two sensible approaches to accomplish that:

  1. Simply use the enclosed gb.php script, which will output a complete HTML file to the browser. This script uses an HTML document (gb-template.html) as a template file, which can get customized completely.
  2. If your website is already script-driven anyways you might want to include the guestbook script from within an already existing script which generates the HTML output instead of using the HTML template file. Then you won't need the script gb.php. You need to include the "core script" gb.script.inc which simply generates a <div> element with all the guestbook-related stuff inside.
    Since version 4.0 the core script (gb.script.inc) no longer outputs anything but provides a class with which you can create an object which in turn provides the guestbook output. When you instantiate the object you can set an encoding with which the guestbook script's output will be created.

Everything can get styled using CSS. The basic code structure of the guestbook output looks like this:

<div id="guestbook">
<p class="menue"><a href="?gb_task=new_entry" class="new-entry">Sign guestbook</a> | entries 1 - 4 (von 4) | newer | older </p>
<dl>
    <dt><span>visitor</span> on 11/09/2008 at 12:15 o'clock</dt>
    <dd>My GB entry...</dd>
</dl>
</div>

The CSS file for the layout of this output is heavily commented, so customizing should be relatively easy - provided you do have some knowledge about CSS.

Admin Panel

Some of the most used functions can get configured inside the included admin panel which can be accessed using a URL parameter "gb_admin".

Let's say you want to access your admin panel and type "http://example.org/gb/gb.php?gb_admin" into your browser: a login form will appear where you can log into the admin panel.

You need to configure your guestbook via this admin panel first! Especially the login credentials must be set!

You can also configure which words you don't want to read in your guestbook. This feature requires some knowledge about so-called regular expressions - but if you don't know what that is you can simply enter all the words (one per line) and that's OK, too.

For the automatic e-mail notification you can set the very address the notification is supposed to be ent to. There also is a switch to turn this feature on or off independently.

The moderated mode can be enabled in the admin panel. Using this mode means that new entries won't get displayed until they have been explicitely been approved of by an administrator.

SPAM Protection

Since the user is forced to a first preview before the new entry gets accepted most automated entries get blocked because these "bots" simply don't understand this concept. This mechanism has been refined using sessions.

Demo

This website makes use of this very guestbook script. Try it out yourself if you'd like to send me some greetings: Sign my guestbook.

"Other Stuff"

Some first-aid hints if customization fails

You should be able to place the guestbook files (and directories) anywhere in your DocumentRoot, except for /cgi-bin/ or any sub-directory of it!

Most e-mails I received were about a problem with an error message which looked somewhat like this:

Warning: session_start(): Cannot send session cache limiter - headers already sent...

Now how can this get fixed? You'll need to know a little more about PHP's session mechanism in order to fix this problem.

Understanding the problem

PHP's session mechanism is a means to identify a visitor when he or she "comes back". Just imagine a user who has entered some stuff into the form in order to leave a message in the guestbook. The server needs to show this user at least a first preview before the message gets accepted. Now how is the server supposed to know which user has already had a preview (and now wants his or her entry to get accepted) or not? Therefore PHP starts a session. If the user's browser is set to accept cookies the session ID gets stored in a cookie. If the user's browser doesn't accept any cookies then the session ID gets appended to the URL string (the part with "PHPSESSID=aRftGh8s2Lxw9...").

Using cookies is part of the HTTP protocol. When the user's browser sends a request to the server it will include any possible cookie data in the header of its request. The same goes for the server in the response. If cookie data is to be sent back to the browser it must happen in the HTTP header. This means that no HTML data must be sent prior to any HTTP header data.

If a PHP script has already sent any HTML data to the browser then the server will have sent any HTTP header data before this data automatically. If a script then wants to send session-related data to the browser this is no longer possible, because the data stream has already begun and the header has already been sent. This is the reason for the above error message.

Solution

So how can the problem get fixed after all? If you use scripts that make use of sessions then you need to hold back all possible output to the browser until everything is really ready to go! There is the possibility to use PHP's output buffering or simply make sure that no data gets sent to the browser until your script is ready to do so.

In some cases data still gets sent to the browser before the script is supposed to do so. The reasons for this seem dubious because according to the script's logic nothing should have been sent so far. In these cases make sure that in all your PHP files the first characters are in fact the ones to start a PHP script ("<php?") without any whitespace characters (or even HTML code!) before that. If you use UTF-8 encoding (like this guestbook script does) also make sure that you leave out the BOM (byte order mark) because this gets sent to the browser before the script can start any buffering.

Examples how in some cases "HTML data" gets send to the browser so even beginners of writing PHP scripts should see the problem:

------script.php------
<html>
<?php
include "head_script.php";
?>
...
</html>
----------------------

Now an approach with a less obvious problem:

------script.php------
 
<?php
include "head_script.php";
include "body_script.php";
include "gb.script.inc"; // GB script
include "footer_script.php";
?>
----------------------

Mind the empty line at the beginning of the second example! This line break character already gets interpreted and treated like "HTML data"! Here the HTTP header gets sent to the browser before the following script can get processed. So when the GB script finally gets included it can't set any HTTP headers anymore because they have already been sent.

Was my script useful to you?

Of course I'm happy if my script is useful not only for myself but for others, too. I appreciate feedback in e-mails especially if it gives me new ideas or ideas for improvements. Please try to solve your problems with my script(s) on your own as hard as you can first before you send me an e-mail for help.