AJAX Hit Counter

connecting to db hitcounter as user myhits ... 

Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /fs/mcclellan/pub/htdocs/home/burt/learning/Csc598.073/workbook/hitcounter/hitcounter_sub.php on line 27
Could not connect: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) connecting to db hitcounter as user myhits ...
Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /fs/mcclellan/pub/htdocs/home/burt/learning/Csc598.073/workbook/hitcounter/hitcounter_sub.php on line 27
Could not connect: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

This page accessed -1 times.

The PHP

The application uses three files:

The subroutine file has utility routines, and it is share by the main script and the ajax responder. Of course, there is a CSS and a Javascript file attached to the main web page.

The hitcounter file generates this page, it is the main entry point into the application. The file contains a great deal of HTML, so I've tried to move all the PHP into a separate file, hitcounter_sub. The Ajax responding script is in hitcounterajax. Since the subroutine file is shared between hitcounter and hitcounterajax, and it encapsulates all the true workings of the application, neither of the other two files is very long.

The PHP main script can be set to write its debugging output (echo statements) to the page. Things have been arranged so that all of that output occurs inside a div which can be marked display none or display block. This way the debugging will be hidden or visible. This poor man's debugging console can be interactively shown or hidden by having Javascript set this property.

The Ajax

The getHitCounterAjax javascript routine uses xhttprequest to query the current page count on the server, but calling the script hitcounterjava.php. The page is set to poll hitcounterjava every three seconds, at first by the onload event, and then driven by the completion of the previous xhttprequest. To make the ajax a little less dependent on the exact format of the return, I use a simple regular expression to capture an number inclosed between two underscores.

function getHitCounterAjax() {
    makeRequest("hitcounterajax.php") ;
}

function processAjaxReply( returnedtext ) {
   // alert(returnedtext) ; // DEBUG (super annoying!)
   var re = /_(\d+)_/ ;
   var n ;
   n = returnedtext.match(re)[1] ;
   document.getElementById('hitcount').textContent = n ;
   // sleep then call getHitCounterAjax again ..
   setTimeout("getHitCounterAjax()", 3000 ) ;
}


// code copied from http://developer.mozilla.org/en/docs/AJAX:Getting_Started

function makeRequest(url) {
   var httpRequest;

   if (window.XMLHttpRequest) { // Mozilla, Safari, ...
      httpRequest = new XMLHttpRequest();
      if (httpRequest.overrideMimeType) {
         httpRequest.overrideMimeType('text/xml');
         // See note below about this line
      }
    }
    else if (window.ActiveXObject) { // IE
       try {
          httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
       }
       catch (e) {
          try {
             httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
          }
          catch (e) {}
       }
   }

   if (!httpRequest) {
       alert('Giving up :( Cannot create an XMLHTTP instance');
       return false;
   }
   httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
   httpRequest.open('GET', url, true);
   httpRequest.send(null);
}

function alertContents(httpRequest) {
   if (httpRequest.readyState == 4) {
      if (httpRequest.status == 200) {
        processAjaxReply( httpRequest.responseText ) ;
        // alert(httpRequest.responseText);
      } else {
         alert('There was a problem with the request.');
      }
   }
}

The MySql

Here is the commands for creating the table and granting rights to the PHP user.


mysql> create database hitcounter ;
Query OK, 1 row affected (0.00 sec)

mysql> use hitcounter ;
Database changed

mysql> create table  hits (
    -> id int primary key not null auto_increment , 
    -> name varchar(12) unique, 
    -> hits int , 
    -> date timestamp
    -> ) ;
Query OK, 0 rows affected (0.08 sec)

mysql> describe hits ;
+-------+-------------+------+-----+-------------------+----------------+
| Field | Type        | Null | Key | Default           | Extra          |
+-------+-------------+------+-----+-------------------+----------------+
| id    | int(11)     |      | PRI | NULL              | auto_increment |
| name  | varchar(12) | YES  | MUL | NULL              |                |
| hits  | int(11)     | YES  |     | NULL              |                |
| date  | timestamp   | YES  |     | CURRENT_TIMESTAMP |                |
+-------+-------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)

mysql> insert into hits (name,hits) values ("mypage",0) ;
Query OK, 1 row affected (0.00 sec)

mysql> select * from hits ;
+----+--------+------+---------------------+
| id | name   | hits | date                |
+----+--------+------+---------------------+
|  1 | mypage |    0 | 2007-06-18 11:17:16 |
+----+--------+------+---------------------+
1 row in set (0.00 sec)

mysql> grant select, update on hitcounter.hits to 
    -> myhits@localhost identified by 'xxxxxxxx' ;
Query OK, 0 rows affected (0.00 sec)