Shoutbox with PHP

Create a Basic Shoutbox with PHP and SQL

In this tutorial, we will be creating a basic ‘Shoutbox’ system with PHP. Aimed at beginners to PHP development, this allows you to get your feet wet working with databases before moving on to some of the more advanced PHP tutorials here at NETTUTS.

Introduction

This tutorial will guide you through the process of creating a basic “shoutbox” with PHP, using a MySQL database to store the shouts – and then make it look nice with some CSS. The tutorial is aimed at designers who are confident with HTML & CSS, but want to try their hand at developing with PHP.

Following the tutorial, you should hopefully have a good understanding of the basics of using PHP to communicate with a database to send, request and receive information. We will also be including the use of Gravatars in our Shoutbox, adding that little extra oomph!

For those who haven’t, I recommend you read our PHP From Scratch series in order to understand exactly what PHP is, and get a look at some of the basic syntax and how we use variables.

The sources files are also commented for those who would prefer to learn that way.

Step 1 – Getting Started

Database

Before starting, you should already have a database setup on your web server. Make sure you have the following details at hand:

  • Hostname (eg. localhost)
  • Database name
  • Username for database
  • Password

In the database, you will need to create a table named shouts with five fields:

  • id
  • name
  • email
  • post
  • ipaddress

To create this, run the following SQL code. You will normally run this from the SQL tab in phpMyAdmin.

CREATE TABLE `shouts` (
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  `email` VARCHAR(60) NOT NULL,
  `post` TEXT NOT NULL,
  `ipaddress` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`)
);

You should receive a “Your SQL query has been executed successfully” message

The Files

We will need three files created for this project:

  • index.php
  • style.css
  • db.php

You will also need a folder with our required images. Grab this from the source files.

Database Connection Details

The db.php file will be used to store our database details. Open it and insert the following code:

<?php
$host = 'localhost'; //usually localhost
$username = 'root'; //your username assigned to your database
$password = 'password'; //your password assigned to your user & database
$database = 'shoutbox'; //your database name
?>

Step 2 – Interaction

Start your index.php file with the following code, it just begins our document and places a few sections to style later.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Shoutbox for NETTUTS by Dan Harper
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div id="container">

  <h1>Shoutbox
  <h5><a href="http://www.danharper.me" title="Dan Harper">Dan Harper </a> : <a href="http://www.nettuts.com" title="NETTUTS - Spoonfed Coding Skills">NETTUTS</a></h5>

  <div id="boxtop" />
  <div id="content">

Establishing a Connection

Before we can do anything with a database, we need to connect to it. Insert the following after the previous code. It is explained below.

<?php
$self = $_SERVER['PHP_SELF']; //the $self variable equals this file
$ipaddress = ("$_SERVER[REMOTE_ADDR]"); //the $ipaddress var equals users IP
include ('db.php'); // for db details

$connect = mysql_connect($host,$username,$password) or die('

Unable to connect to the database server at this time.

'); mysql_select_db($database,$connect) or die('

Unable to connect to the database at this time.

');

The first two lines use a built-in PHP function to get the name of this file, and the other line to get the visitors IP address. We will use the two variables later in the tutorial.

We then include our db.php file so we can retrieve the database details you filled in. Alternatively, you could paste everything from db.php here, but it’s good practice to separate the details.

$connect stores a function to use our database details in order to establish a connection with the database server. If it can’t connect, it will display an error message and stop the rest of the page loading with die().

Finally, we connect to our database.

Has anything been submitted?

The next thing we will do is check whether someone has submitted a shout using the form (which we will include shortly). We check the documents POST to see if something has been submitted from a form.

if(isset($_POST['send'])) {
    if(empty($_POST['name']) || empty($_POST['email']) || empty($_POST['post'])) {
        echo('

You did not fill in a required field.

'); } else {

We start with our if() which checks our POST to see if an item named ‘send’ has been submitted. If it has we use the empty() function to make sure the ‘name’, ‘email’ and ‘post’ fields were filled in. If they weren’t, we display an error.

Otherwise, we continue:

$name = htmlspecialchars(mysql_real_escape_string($_POST['name'])); 
$email = htmlspecialchars(mysql_real_escape_string($_POST['email'])); 
$post = htmlspecialchars(mysql_real_escape_string($_POST['post']));

$sql = "INSERT INTO shouts SET name='$name', email='$email', post='$post', ipaddress='$ipaddress';";

    if (@mysql_query($sql)) {
        echo('

Thanks for shouting!

'); } else { echo('

There was an unexpected error when submitting your shout.

'); } } }

On the first three lines, we run each of our fields (name, email and post) through the htmlspecialchars() and mysql_real_escape_string() functions and place them into their own variables.

htmlspecialchars() is a function designed to prevent users from submitting HTML code. If we didn’t do this, someone could put any HTML into our database which would then be executed to other users. This is especially bad if someone submitted javascript code that would transfer visitors to a malicious website!

mysql_real_escape_string() is a similar function. Except this one stops the user from submitting any sort of SQL code to the server. If we didn’t do this, someone could execute code to steal, edit or erase our database!

Using our new details, we create a SQL query to insert the submitted shout into the database. In the if() tags, we execute the SQL Query. If the query was successfully executed, and the shout added to the database, we display a “Thanks for shouting!” message; otherwise we display an error.

Retrieving the Shouts

We will now retrieve the 8 latest shouts from our database to display them to the user.

$query = "SELECT * FROM `shouts` ORDER BY `id` DESC LIMIT 8;";
    
$result = @mysql_query("$query") or die('

There was an unexpected error grabbing shouts from the database.

'); ?>

    On the first line, we create a new SQL query to "Retrieve all fields from the 'shouts' table, order them descending by the 'ID'; but only give us the latest 8".

    On the second line we execute the query and store it in $result. We now:

    while ($row = mysql_fetch_array($result)) {
    
        $ename = stripslashes($row['name']);
        $eemail = stripslashes($row['email']);
        $epost = stripslashes($row['post']);
        
        $grav_url = "http://www.gravatar.com/avatar.php?gravatar_id=".md5(strtolower($eemail))."&size=70"; 
        
        echo('
  • Gravatar

    '.$ename.'

    '.$epost.'

  • '); } ?>

The first line says "While there are still rows (results) inside $result, display them as follows:".

stripslashes() removes any slashes which mysql_real_escape_string() may have inserted into submissions.

$grav_url creates our Gravatar from each users email address.

We then output (echo) each shout in a specific manner. Basically displaying the Gravatar, Name and Shout in a list we can easily style later.

The Form

The final step for this page is to include a form to the bottom of the page which users can submit posts through.

<form action="<?php $self ?>" method="post">
<h2>Shout! </h2>
<div class="fname">

Note that we reference the $self variable to tell the form where to send it's results; and we also send via the POST method. Below the form we close off any HTML tags we opened.

Styling

Try it out! You've finished all the PHP code, and you should be able to add a new shout and see the 8 latest ones.

However, there's one problem. It looks UGLY! Lets sort that out with some CSS :) With this not being a CSS tutorial, I won't go over any of the styling, but everything's pretty basic.

* {
margin: 0;
padding: 0;
}

body {
background: #323f66 top center url("images/back.png") no-repeat;
color: #ffffff;
font-family: Helvetica, Arial, Verdana, sans-serif;
}

h1 {
font-size: 3.5em;
letter-spacing: -1px;
background: url("images/shoutbox.png") no-repeat;
width: 303px;
margin: 0 auto;
text-indent: -9999em;
color: #33ccff;
}

h2 {
font-size: 2em;
letter-spacing: -1px;
background: url("images/shout.png") no-repeat;
width: 119px;
text-indent: -9999em;
color: #33ccff;
clear: both;
margin: 15px 0;
}

h5 a:link, h5 a:visited {
color: #ffffff;
text-decoration: none;
}

h5 a:hover, h5 a:active, h5 a:focus {
border-bottom: 1px solid #fff;
}

p {
font-size: 0.9em;
line-height: 1.3em;
font-family: Lucida Sans Unicode, Helvetica, Arial, Verdana, sans-serif;
}

p.error {
background-color: #603131;
border: 1px solid #5c2d2d;
width: 260px;
padding: 10px;
margin-bottom: 15px;
}

p.success {
background-color: #313d60;
border: 1px solid #2d395c;
width: 260px;
padding: 10px;
margin-bottom: 15px;
}

#container {
width: 664px;
margin: 20px auto;
text-align: center;
}

	#boxtop {
	margin: 30px auto 0px;
	background: url("images/top.png") no-repeat;
	width: 663px;
	height: 23px;
	}

	
	#boxbot {
	margin: 0px auto 30px;
	background: url("images/bot.png") no-repeat;
	width: 664px;
	height: 25px;
	}

	#content {
	margin: 0 auto;
	width: 664px;
	text-align: left;
	background: url("images/bg.png") repeat-y;
	padding: 15px 35px;
	}
	
    #content ul {
    margin-left: 0;
    margin-bottom: 15px;
    }
    
    #content ul li {
    list-style: none;
    clear: both;
    padding-top: 30px;
    }
    
        #content ul li:first-child {
        padding-top:0;
        }
    
    .meta {
    width: 85px;
    text-align: left;
    float: left;
    min-height: 110px;
    font-weight: bold;
    }
    
        .meta img {
        padding: 5px;
        background-color: #313d60;
        }
        
        .meta p {
        font-size: 0.8em;
        }
    
    .shout {
    width: 500px;
    float: left;
    margin-left: 15px;
    min-height: 110px;
    padding-top: 5px;
    }
    
    form {
    clear: both;
    margin-top: 135px !important;
    }
    
        .fname, .femail {
        width: 222px;
        float: left;
        }
        
        form p {
        font-weight: bold;
        margin-bottom: 3px;
        }
        
        form textarea {
        width: 365px;
        overflow: hidden; /* removes vertical scrollbar in IE */
        }
    
        form input, form textarea {
        background-color: #313d60;
        border: 1px solid #2d395c;
        color: #ffffff;
        padding: 5px;
        font-family: Lucida Sans Unicode, Helvetica, Arial, Verdana, sans-serif;
        margin-bottom: 10px;
        }

Conclusion

So there you have it! A great-looking, fully functional Shoutbox! You may have wondered what the point of creating a Shoutbox is, and well, you're right, there is no point. But what this does do is help give you some vital basic understanding of using PHP to work with a database, allowing you to move on to much more advanced guides here at NETTUTS.

Heck, you could even reuse this code to create yourself an incredibly basic blog! Not much point to it, but it's fun.

Dan Harper is danharper on Themeforest
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.marceldoornbos.com/2008/10/part-1-how-to-display-wordpress-posts-on-your-php-site/ Marcel Doornbos

    :| If I found this tutorial 3 weeks earlier I wouldn’t have to create it myself :O Now I have created it myself. But than a similar code is included in WordPress. I also created a Tutorial. But ok Thank you very much for making this. :)

    Regards.

    Marcel Doornbos

  • http://www.believeindesign.net Chris

    Anyone knows how I can get php to print “Says:” after each name?

    heres the code:
    “echo(”.$ename.”.$epost.”);”

    I want it to display “$ename (Chris) Says:”

    Thanks:)

  • http://www.marceldoornbos.com/2008/10/part-1-how-to-display-wordpress-posts-on-your-php-site/ Marcel Doornbos

    @ Chris:

    In this part:

    echo(‘
    ‘.$ename.”.$epost.”);

    Change: ‘.$ename.’

    Into: “‘.$ename.’ Says:”

    I think this is what you mean.

    Regards,

    Marcel Doornbos

    • http://www.designbulk.com Manny M

      There were quite a few errors in here which made it much more complicated for a beginner such as myself o.O

  • Pingback: How to Create an Object-Oriented Blog Using PHP

  • http://www.believeindesign.net Chris

    Thank you Marcel for your quick answer and yes, that is what I’m looking for… but I just keep getting Parse Error. here is the whole codeline:

    echo
    (‘(li> (div class=”date”>’ .$date . ‘(/div>
    (div class=”meta”>’ “‘.$ename.’Says:” ‘(/div>
    (div class=”shout”>’. $epost .’(/div>(/li>’);

    I Changed the “<” to “(” so that it wouldn’t disappear like in the previous post:)

  • sean

    in the demo the comment box doesn’t go into auto scroll when you exceed the char limit. Is there a way around that? thanks ^^

  • Pingback: Under Repair

  • ideung

    How to add ip address and to save in database???

  • Ben Reid

    Awesome post!

    I know when I started the whole SQL & PHP route it seemed very confusing but you managed to explain the key elements from defining the database details, connecting, posting and retrieving.

    The code is very clean, unlike post tutorials I’ve seen for SQL

    Nice work!

  • grrrrrr8

    cool stuff

  • collone

    these are some of the most simplest tutorials to follow THANKS

  • coolstuff

    awesome stuff

  • Jaakko

    I got this one working localy but not on www hmmm whats wrong with it

  • naresh

    it is very good for beginers.
    thank u

  • DRT
  • http://timskaggs.net Skaggs

    Thanks the tut! I put in on my site: http://thesausagemustdie.com/

  • http://svendbenno.dk svend

    Nice design you made for the shoutbox :D

  • Bill

    Awesome tut !!!
    And like svend said: Nice design !!!

  • Zargam

    I dont understand why do i get this

    “Warning: mysql_connect() [function.mysql-connect]: Access denied for user ‘ “

  • kieran

    Great. Im still new to all this and i font it superub thumps up from me :)

    • jii

      WHat?

  • Danny

    I copied the code verbatim but get this…….

    Parse error: syntax error, unexpected ‘<’ in C:\Domains\horselink.co.uk\wwwroot\shout\index.php on line 46
    PHP Parse error: syntax error, unexpected ‘<’ in C:\Domains\horselink.co.uk\wwwroot\shout\index.php on line 46

  • http://tuts.cgbaran.com CgBaran Tuts

    Very useful thanks

  • momok

    good tut

  • Archer

    I found this very informative. I am just learning this php and Javascript and have found all the code very hard to understand without someone explaining it. You do a very nice job.

  • http://www.nettutes.com praful

    Very informative and useful article

  • http://skjaz.freehostia.com jaz

    I made those three files, but now how do I insert the actual shoutbox on my webpage? Seeing is how the index.php isnt an html I cant use that as a webpage. Help please.

  • Polly

    awesome! Thank you!
    But yeah, there’s a chunk of commentary in the code… must’ve gotten there by accident or some such… And there is a bracket missing somewhere or something…
    But when all is fixed it works perfectly!

    jaz – it doesnt matter that its not html. php supports html or something… anyway, webpages in php are pretty common..

    p.s.: Is Dan Harper really 17?…

  • http://www.mydestiny.net robert

    its not working

    On the first line, we create a new SQL query to “Retrieve all fields from the ‘shouts’ table, order them descending by the ‘ID’; but only give us the latest 8″.

    On the second line we execute the query and store it in $result. We now:

    while ($row = mysql_fetch_array($result)) {

    $ename = stripslashes($row['name']);
    $eemail = stripslashes($row['email']);
    $epost = stripslashes($row['post']);

    $grav_url = “http://www.gravatar.com/avatar.php?gravatar_id=”.md5(strtolower($eemail)).”&size=70″;

    echo(‘
    * Gravatar

    ‘.$ename.’

    ‘.$epost.’
    ‘);

    }
    ?>

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion | Web Tutorials

  • Pingback: CodeIgniter to Ruby on Rails: A Conversion « Dan Harper

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion - Programming Blog

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion - Webreweries.com

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion | Ouech.net

  • Santhosh

    Wow it shoudl work

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion | KolayOnline

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion « Webby Tutos

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion | Webby Tutos

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion : Webby Tutos

  • Pingback: From CodeIgniter to Ruby on Rails: A Conversion- goSiaz

  • Pedro

    Please Help to add CAPTCHA or spam protection by ip.

  • http://link Faggot63

    This was Ireland’s second Contest victory. ,

  • David

    If you enter a shout and press F5 the shout would be shouted again any ideas how to stop this?

    • http://www.thispage.ru Matt

      You may try redirecting the browser to the url ending with random number like so:

      Redirecting like so won’t change the way your script works, but it will prevent your POST data to be sent multiple times in case a user refreshes the page (just because there’s no POST data sent to the redirected page!).
      Randomness in url also forces the browser to actually download the page instead of loading it from cache, where your post wasn’t saved yet.. But you can achieve without changing the url just by sending additional headers that disable cahing.

    • yozloy

      Found the same problem
      There should be some way to clear the _POST[] array, I tried the unset(_POST['send']), but it’s not work
      Anybody have better idea?

  • nancy

    cool

  • http://spotdex.com David Moreen

    This is just a great tutorial, I really enjoyed doing it. The shout box is basic but it gets me all excited. I’ve only been working with PHP for say 7 months, no where near intermediate, but I’m getting there. I think for my first project that I will do by myself will be a shout box, with lots more functionality.

    To add, I did learn some new things today, I got 3 new PHP built in functions in my brain, I’ll let them marinate. Thanks again.

  • Hareesh

    I want to make more than one shoutboxes in same site…..how is it possible??

  • hareesh

    how to make the link visible in shout….?
    like this http://www.google.com it should be shown in blue color with a link…

  • turt

    Is it possible to shift everything left, right now its all centered, i scowered the CSS file and al lthe PHP files, but i cant seem to move everything

    (i plan to use this in a website im developing, but the “Shout” in the design is an iframe, and i need it to be left >.<)

    Any help is great, thanks

  • raj shrestha

    Great! It works!!!!
    Thanx for the code

  • Dan

    Being a total NOOB at this, I got this one working like a charm, superb stuff.

    However, stiil would like to know how to embed this one into a standard webpage (like a widget) ?
    Thanks for advice and moral support :)

    Dan

    • Dan

      FOUND IT !! :

      “It would be a bad idea to directly plant this script into your page, as a long word would stretch your page sideways, I recommend to save it as shoutbox.php, and use this code to make an IFRAME in your page.

  • http://www.revathytoursandtravels.com Munnar

    Great tutorial. Thanks for sharing!!!