|
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
| |
|
| |
