Page Hit Counter
[Previous] [Main] [Next]

 
The example below implements a complete page hit counter system for any number of documents. A simple text file is used to store document URL's and their respective hit counts as integers.  
 
To use the application, add a server-side-include statement such as the one below to an HTML document. When executed, the application will update the hit counter for the document and output the current value to the browser.  
 
To change the appearance of the counter, simply modify the main() routine to use whatever formatting objects are desired.  
 
<HTML>  
<HEAD></HEAD>  
<BODY>  
 
<!-- The following line executes the html++ app and inserts the counter value -->  
<!--#exec cmd="/home/biz/dcmicro/www/cgi-bin/hitcount"-->  
 
</BODY>  
</HTML>  
 
 
//  
//  Page hit counter application (hitcount.cpp)  
//  
#include <unistd.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <dcmicro/htmlpp/htmlpp.h>  
 
//  Adjust the location of the data file for your system  
#define LOGFILE  "/home/biz/dcmicro/hitcount.dat"  
 
//  Update the hit counter in 'file' for the specified  
//  url, returning it's counter value.  
long UpdateLog  
(  
   const String& file,  //  data file containing hits  
   const String& url    //  URL to update  
)  
{  
   CNVList  list ;  
   FILE *   f ;  
   char     buffer[300] ;  // increase as necessary  
   String   s ;  
   String   name ;  
   String   value ;  
   long     count = 0 ;  
 
   //  Open the data file for reading and writing  
   //  Note that the file must exist and be writable.  
   //  On Unix systems, do a 'touch' command followed  
   //  by the appropriate 'chmod' to prepare the file.  
   //  On extremely busy systems, a database should  
   //  probably be used to store the data for better  
   //  multiuser response.  
 
   for ( int tries = 5 ; tries > 0 ; tries-- )  
   {  
      f = fopen( (char *) String(file), "r+t" ) ;  
      if ( f )  
         break ;  //  success - exit the loop  
 
      //  delay before trying again (Unix-specific)  
      sleep( 1 ) ;  
   }  
 
   //  If the file was successfully opened  
   if ( f )  
   {  
      //  Position at start of file  
      fseek( f, 0, SEEK_SET ) ;  
      //  Read in all lines  
      while ( fgets( buffer, sizeof(buffer), f ) != NULL )  
      {  
         s = buffer ;  
         s.RTrim( '\n' ) ;  
 
         //  The URL is the name; the count is the value.  
         name = s.GetNextToken() ;  
         value = s ; // the remainder of the string   
 
         //  Add the pair to the list  
         list.Value( name, value ) ;  
      }  
 
      //  Obtain the count value, if any, for  
      //  the specified url  
      count = list.Value( url ).AsLong() ;  
      //  Update the counter in memory  
      list.Value( url, ++count ) ;  
 
      //  Re-write the log file with the new counter  
      fseek( f, 0, SEEK_SET ) ;  
      Boolean good_data = list.Enumerate( name, value, TRUE ) ;  
      while ( good_data )  
      {  
         //  Output the document URL with it's count  
         fprintf( f, "%s %s\n",   
                  (char *) name,   
                  (char *) value ) ;  
         good_data = list.Enumerate( name, value ) ;  
      }  
 
      fclose( f ) ;  
   }  
 
   //  Return the count value for the specified url  
   return count ;  
}  
 
 
int main( void )  
{  
   htmlCgi        server( cin ) ;  
   htmlContainer  result ;  
   long           count ;  
 
   //  The htmlCgi member variable 'Script_Name' contains  
   //  the name of the URL requested by the browser.  
   count = UpdateLog( LOGFILE, server.Script_Name ) ;  
 
   //  Format the counter value using a large red font  
   result << ( htmlFont( "Verdana, Arial", +6, COLOR_RED )  
                  << htmlBold( count ) ) ;  
 
   //  Output the result  
   server << result ;  
   return 0 ;  
}  
 
To compile the application, use a makefile or a project file with your compiler. On Unix systems, it's often convenient to invoke the compiler from a command-line as below (GNU C++ on BSDI Unix):  
 
g++ hitcount.cpp /usr/local/dcmicro/htmlpp/lib/libhtmlpp.a  
     -I/usr/local/dcmicro/htmlpp/include -o hitcount  
 


©1998 DC Micro Development. All rights reserved.
No portion of this document may be c opied or reproduced without expressed written consent.
html++ is a trademark of DC Micro Development.