Publishing System Settings Logout Login Register
How to create an Ajax/PHP Shoutbox
TutorialCommentsThe AuthorReport Tutorial
Tutorial Avatar
Rating
Add to Favorites
Posted on April 19th, 2007
1401 views
PHP Coding
In depth tutorial and compiled scripts can be located at http://amit.cn/mxbox/

[ Features ]

    When coding a shoutbox, what features come to mind?

  # Post to flatfile
  # Input Fields
  # Security / Flooding
  # Cookie Handling
  # Posts Updating
  # Integration into a website

    I will try my best to show you how to accomplish the former.



[ Flatfiles ]

    The first thing to decide when coding a shoutbox is what kind of database to use.
    For this article, I will be using a standard Flatfiles (text-file) database.

    Before you begin, you need to decide where is the database going to be located.
    I recommend using posts.txt as your file of choice, where shoutbox.php will be located in the same directory

    So before we begin coding any of the backend, we need to define a couple of variables.
    And chmod your $config['dbpath'] and $config['iplist'] to 666 or 777
    777 is a good choice, and is not a security hazard. The only way someone can edit a 777 chmodded file is if they are doing it locally
    There is much debate about this, but again, I recommend 777, you can chmod the files to 666; all other values may potentially work on your server.
    $config = array(); // we will store all our configuration settings in this array
    $config['date'] = date('l dS of F Y h:i:s A'); // current date and time
    $config['dbpath'] = 'posts.txt'; //you can edit this
    $config['html'] = 0; // to allow HTML posting, change this to 1
    $config['server'] = htmlentities($_SERVER['PHP_SELF']); // the path to this file
    $config['ip'] = $_SERVER['REMOTE_ADDR']; // their ip address for logging
    $config['iplist'] = 'iplist.txt'; // flood-protection file, ips located in the file will be banned for 60 seconds
    $config['delimiter'] = ':MXBOXMXBOX:'; // change this whatever you see fit
    Now that we know what we will allow our web-visitors, we can start on the actual backend code.



[ Input Fields ]

    We need to decide what we are going to allow our visitors to enter. We don't want them to post malicious code, or something that could be not to our desires.
    This is also a good opportunity to define what fields are necessary in the form. Should we allow them to enter URLs, emails, or other forms of contact?
    For this I will focus on five fields. We need them to enter their name, so we can identify them. Not only that, but set a cookie so when they come back, the form will remember their previous entry.
    We need a textarea element for the actual message they are going to send us, and the contact methods are optional.
    Contact methods include a trackback uri, an email address, or perhaps an aim screenname.

    We have to use "get" as the form method if we want to use ajax, to minimize bandwidth usage.
    Since the shoutbox will be dynamic, there need not be an action for the form.
    We will be using "onsubmit" in the form, so when a user submits their message, the variables will be sent via javascript as a uri.
    $form = '
    <form method="get" action="" onsubmit="ajax(' . "'$config['server']?submit=Submit&name=' + document.getElementById('name').value + '&url=' + document.getElementById('url').value + '&email=' + document.getElementById('email').value + '&message=' + document.getElementById('message').value, 'post'" . ')">
    <table>
    <tr><td>Name:</td><td><input id="name" name="name" type="text" value="' . $nc . '" /></td></tr>
    <tr><td>URL:</td><td><input id="url" name="url" type="text" value="http://" /></td></tr>
    <tr><td>Email:</td><td><input id="email" name="email" type="text" value="Required" onclick="this.value=' . "''" . '" /></td></tr>
    <tr><td>Message:</td><td><textarea name="message" id="message"></textarea></td></tr>
    <tr><td>&nbsp;</td><td><input name="submit" value="Submit" type="submit" /></td></tr>
    </table>
    </form>
    ';
    Now that we have our form, we don't look at it twice. Ironically, we won't be using it until the last bit of code is complete.
    With that in mind, let's continue. Look at the name and id elements in the form above. These are the variables we will need in our backend.
    $mx = array(); // everything they post will be held in this array
    $mx['name'] = $_GET['name']; // the name they send
    $mx['url'] = $_GET['url']; // the url they send
    $mx['email'] = $_GET['email']; // the email they send
    $mx['message'] = $_GET['message']; // the message they send
    $mx['submit'] = $_GET['submit']; // if they press submit



[ Security / Flooding ]

    We're already on the backend, now wasn't that easy?
    We don't want the user sending messages too fast, and we don't want them flaming other users.
    The shoutbox is going to do a goodjob preventing intrusions as well, and removing HTML is a pretty good idea.
    function clean($clean){
    $clean = stripslashes($clean); // prevents them from entering slashes to obfuscate xss
    $clean = strip_tags($clean); // removes all HTML from posting
    $clean = htmlentities($clean); // just incase strip_tags didnt do its job
    $clean = str_replace('"', '&quot;', $clean); // trick filtering
    $clean = str_replace("'", '&quot;', $clean); // trick filtering
    /* maybe htmlentities and strip_tags were overthrown on your server */
    $clean = str_replace('<', '', $clean); // html filtering
    $clean = str_replace('>', '', $clean); // html filtering
    $clean = str_replace('php', 'php', $clean);
    $clean = str_replace('scr', 'scr', $clean);
    $clean = str_replace('javascript', '', $clean); // clickable xss
    $clean = str_replace('http://', '', $clean) // clickable xss;
    $clean = str_replace(':', ':', $clean); // clickable xss
    /* remove crlf */
    $clean = trim($clean,"x7f..xffx0..x1f");
    $clean = preg_replace ("/ss+/" , " " , $clean);
    $clean = preg_replace('/s+/', ' ', $clean);
    return $clean; // returns the value to the call
    }

    function url($url, $name){
    $url = '<a title="' . $config['date'] . '" href="http://' . $url . '">' . $name . '</a>'; // makes it a clickable hyper-link
    return $url; // returns the value for processing
    }

    if ($config['html'] == 0){
    clean($mx['name']);
    clean($mx['url']);
    clean($mx['email']);
    clean($mx['message']);
    }
    else{
    $mx['name'] = stripslashes($mx['name']);
    $mx['url'] = stripslashes($mx['url']);
    $mx['email'] = stripslashes($mx['email']);
    $mx['message'] = stripslashes($mx['message']);
    }

    if (strlen($config['url']) > 1 && $config['url'] !== 'http://'){
    $mx['name'] = url($config['url'], $mx['name']);
    }
    else{
    $mx['name'] = '<a href="javascript:void(0)" title="' . $config['date'] . '">' . $mx['name'] . '</a>';
    }
    Now that we have Security/PHP/XSS covered, we can move on to flooding.
    Mostly all shoutboxs I have come across can not handle flooding. Someone can use proxies to hit a get or a post, it doesn't matter what method the script uses.
    To prevent flooding, you're going to have to keep IPs logged for sometime, then make the IPs vanish dynamically (60 seconds is good). For this part of the tutorial, we're going to have to refer to our config array. We need to make the iplist.txt file according to what we named it.
    For this tutorial, I will use the standard iplist.txt, but using your config array at the top, you can make it whatever you want for added security.
    We're only going to save what they send us, so make sure your delimiter is a secret.
    if ($mx['submit'] == 'Submit'){
    if (file_exists($config['iplist'])){
    $floodlist = file_get_contents($config['iplist']);
    }
    else{
    $floodlist = '';
    }
    if (file_exists($config['dbpath']) && !eregi($config['ip'], $floodlist){
    $old = file_get_contents($config['dbpath']); // get all the old posts
    $newpost = $mx['name'] . $config['delimiter'] . $mx['email'] . $config['delimiter'] . $mx['message']; // what we save to the server
    $amit = fopen($config['dbpath'], 'w+') or die('Error Posting');
    fwrite($amit, $newpost . "n" . $old);
    fclose($amit);

    $flood = fopen($config['iplist'], 'a+') or die('Error IP');
    fwrite($flood, $config['ip']);
    fclose($flood);

    setcookie('user', $mx['name']); // cookies

    echo 'Your post was successful!<script>ajax(' . "'$config['server']?noform=1', 'tag'" . ');</script>'; // update entries
    }
    else{
    echo 'You must wait 60 seconds to post again!';
    }
    }
    else{
    echo '<div style="overflow:auto;height:200px;width:100%" id="tag">';
    if (file_exists($config['dbpath'])){
    $entries = file($config['dbpath']);
    }
    else{
    $entries = array('No posts yet', 'test2', 'test3');
    }
    $count = count($entries);
    for($counter = 0; $counter < ($count + 1); $counter += 1){
    $var = explode($config['delimiter'], $entries[$counter]);
    echo '<div><b>' . $var[0] . '</b><br />' . nl2br($var[2]) . '</div>';
    }
    echo '</div>';
    }

    if ($_GET['noform'] !== '1'){
    echo $form;
    }



[ Misc ]

    We need headers and footers. Our headers will go at the very top of the code.
    $cookie = $_COOKIE['user'];
    if (isset($cookie)){
    $nc = htmlentities($cookie);
    }

    $xip = date("H:i:s", filectime($config['iplist']));
    $timenow = date("H:i:s");
    $one = explode(':', $xip);
    $two = explode(':', $timenow);
    if($one[0] == $two[0])
    {
    if($one[1] !== $two[1])
    {
    // erase the ip
    $fc = fopen( $config['iplist'] ,'w' ) ;
    fputs( $fc , 'k update') ;
    fclose( $fc ) ;
    }
    }
    else
    {
    // erase the ip
    $fc = fopen( $config['iplist'] ,'w' ) ;
    fputs( $fc , 'well its a diff hour') ;
    fclose( $fc ) ;
    }
    $nc is being used in the form.
    To include the script into your page, all the files must be in the same directory as the file you're including it into.
    So suppose your hosting path is amit/public_html, your path would be /
    PHP:
    include('mxbox.php');
Dig this tutorial?
Thank the author by sending him a few P2L credits!

Send
Amit

Amit Technologies
View Full Profile Add as Friend Send PM
Pixel2Life Home Advanced Search Search Tutorial Index Publish Tutorials Community Forums Web Hosting P2L On Facebook P2L On Twitter P2L Feeds Tutorial Index Publish Tutorials Community Forums Web Hosting P2L On Facebook P2L On Twitter P2L Feeds Pixel2life Homepage Submit a Tutorial Publish a Tutorial Join our Forums P2L Marketplace Advertise on P2L P2L Website Hosting Help and FAQ Topsites Link Exchange P2L RSS Feeds P2L Sitemap Contact Us Privacy Statement Legal P2L Facebook Fanpage Follow us on Twitter P2L Studios Portal P2L Website Hosting Back to Top