phpOpenCounter V2: Documentation

Introduction

Back in late 1999 when I started working on phpOpenCounter I just wanted to code a small counter for my homepage at http://gravedancer.rc5.de.

Then I saw that they had a display of how many visitors were currently on the site at chefkoch.de, so I asked their webmaster Alexander Meis how he did that feature.

Soon after I published the first public version of phpOpenCounter in early 2000 it grew more popular every day and I got a lot of response from people interested in new features, and so phpOpenCounter grew over the time.

When phpOpenCounter V2 came out in April 2000 I made the first step to take phpOpenCounter into a new direction. phpOpenCounter is now intended to become a complete, flexible site- and visitor-tracking solution.

Features

  • Small, efficiently coded in PHP

  • Data is gathered on-the-fly as the access to the site happens and stored efficiently into an SQL database, no logfile analysis is needed

  • Two different modes of operation: Full-Featured and "light" mode

  • Powerful API for data retrieval

Requirements

  • A Web-Server

  • Installed and running PHP environment

  • One of the following DBMS installed:
    • mSQL
    • MS SQL
    • MySQL
    • Oracle / OCI8
    • ODBC
    • PostgreSQL
    • Sybase


  • PHPLIB 7.2 (or higher) installed and configured for your DBMS, get it from http://phplib.netuse.de

    If you can't or don't want to install the whole PHPLIB package on your webserver, don't worry, you can still use phpOpenCounter, just see below for details.

Installation

  1. Copy phpOpenCounter.php to your webserver's document directory and edit the following lines at the top of it to fit your SQL environment:

    $this->db->Host = "localhost";
    $this->db->User = "root";
    $this->db->Password = "";
    $this->db->Database = "database";


  2. Create the following tables in your database:

    CREATE TABLE phpOpenCounter_accesslog (
      DATE datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
      USER_AGENT int(11),
      IP int(11),
      HOST int(11),
      REFERER int(11),
      DOCUMENT int(11),
      UNIQUE_VISIT enum('0','1') NOT NULL,
      KEY DATE (DATE)
    );

    CREATE TABLE phpOpenCounter_data (
      ID int(11) NOT NULL auto_increment,
      DATA varchar(255) NOT NULL,
      PRIMARY KEY (ID),
      UNIQUE DATA (DATA)
    );

    CREATE TABLE phpOpenCounter_userlog (
      DATECHECK int(11),
      DOCUMENT varchar(255) NOT NULL,
      IP varchar(15),
      ONLINE_SINCE datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
      SESSION_ID varchar(32) NOT NULL,
      PRIMARY KEY (SESSION_ID)
    );


  3. Add the following lines of code to every document of your site that you wish to be tracked by phpOpenCounter. Make sure to read the API documentation for phpOpenCounter below to adjust the constructor parameters to fit your requirements!

    include( "/path/to/phpOpenCounter.php" );
    $counter = new phpOpenCounter();


  4. If you haven't installed PHPLIB yet and do not want to do so, you can still use phpOpenCounter by including PHPLIB's database abstraction layer before getting an instance of the phpOpenCounter class.

    As MySQL seems to be the most popular database system used together with PHP we included PHPLIB's include file for this system in the distribution's "redist" folder.

    There are two ways of including for instance "db_MySQL.inc": Including it explicitly in every document that uses the phpOpenCounter or you set the following option in your php.ini:

    auto_prepend_file = /path/to/db_MySQL.inc

  5. If you intend to run phpOpenCounter on a system without the PHP4 session-managment functions available make sure that "sessions.php", which you'll find in this distribution's "redist" folder, is in your include path.

Upgrading from version 2.0.0 to 2.1.0

Since we changed the database scheme completely from phpOpenCounter 2.0.0 to 2.1.0 you need to convert your old tables in order to continue to use your old collected data.

In the "tools" folder of phpOpenCounter's distribution you'll find phpOpenCounterConv.php which you can use to convert your old tables to the new format, whereby you'll reduce the used disk storage to 1/20 of what it used to be with the old database scheme.

Simply specify your file containing the PHPLIB DB_Sql class according to your database, your host, user, password and the database and tablenames of the old counter.
You can specify a new Database and the prefix of the new created tables containing the new datastructure. There are some options too: "Verbose mode" sets a debugging mode, it lets you monitor the performed operations. If you want to keep your old data, simply set "delete database" and "delete tables" to "no". If you want to use the simple version of the counter you can set "full logging" to no, this will strip the old data down to the new simple logging mode, but will result in loss of collected userdata.

API Documentation

  • Constructor: phpOpenCounter( $start, $fullFeatured, $minutes, $allowMySQLHeap, $tableNamePrefix )

    • Normally it will suffice to create an instance of the phpOpenCounter class by using the standard constructor:

      $counter = new phpOpenCounter();

      This way the access to the document creating the class instance will be counted immediately.

    • You can prevent to count the access to the document creating the phpOpenCounter class instance from beeing counted immediately by setting the $start parameter to 0:

      $counter = new phpOpenCounter( 0 );

    • Per default phpOpenCounter operates in full-featured mode. If you want to use the light mode you need to set the constructor's $fullFeatured parameter to 0. The following example will count the access to the document creating the phpOpenCounter's class immediately in light mode:

      $counter = new phpOpenCounter( 1, 0 );

    • Per default the number of minutes for keeping session ids in the userlog table is set to 10. The following example will count the access to the document creating the phpOpenCounter's class immediately in full-featured mode and sets $minutes to 5:

      $counter = new phpOpenCounter( 1, 1, 5 );

    • If you're using MySQL you can set the phpOpenCounter's constructor's $allowMySQLHeap to 1 and leave out the creation of the userlog table during the installation in order to use a heap table for the userlog.

      HEAP tables are beeing held only in memory by MySQL. Therefore they can be accessed very fast and reduce hard-disk traffic further.

      The following example will count the access to the document creating the phpOpenCounter's class immediately in full-featured mode, sets $minutes to 10 and enables the use of MySQL heap tables:

      $counter = new phpOpenCounter( 1, 1, 10, 1 );

    • Per default the format for the table names is "phpOpenCounter" . { "_accesslog" | "_data" | "_userlog" }.

      The following example will count the access to the document creating the phpOpenCounter's class immediately in full-featured mode, sets $minutes to 10, disables the use of MySQL heap tables and sets the $tableNamePrefix to "test":

      $counter = new phpOpenCounter( 1, 1, 10, 0, "test" );


  • get( $data, $mode, $option )

    phpOpenCounter's get() function provides you with a very powerful means to access your collected data.
    Following is a list of possible calls to the get() function:

    1. get( "online" )

      Returns the number of visitors currently online

    2. get( "users_online" )

      Returns an array containing the userlog's table information for the visitors currently online:

      $array = $counter->get( "users_online" );

      $array[ "number" ] contains the number of users currently online
      $array[ 0 ] [] contains all the fields of your userlog's first row, for example: $array[ 0 ] [ DOCUMENT ] contains the document visitor 0 is currently on

    3. get( "hits", "mode", "option" )
      get( "visits", "mode", "option" )


      Returns the number of hits (or unique visits) to the tracked website where $mode and $option may have the following values. Please note, that both parameters are optional and that whereever its say "hits" in the given examples you may use "visits" instead to get the respectively unique visits:

      1. get( "hits" )
        get( "hits", "total" )

        Both calls to get() return the number of total hits to the site.

      2. get( "hits", "today" )
        get( "hits", "day", "0" )

        Both calls to get() return the number of hits to the site that occured during the current day.

        Please note the flexibility of the call pattern get( "hits", "date unit", "x" ), where x is the number of units to go back in time and the unit type given by the $mode argument which can be day, hour, month or year. You'll certainly get the idea behind the concept if you take a look at the following call patterns.

      3. get( "hits", "yesterday" )
        get( "hits", "day", "1" )

        Both calls to get() return the number of hits to the site that occured during the day before the current one.

      4. get( "hits", "thisHour" )
        get( "hits", "hour", "0" )

        Both calls to get() return the number of hits to the site that occured during the current hour.

      5. get( "hits", "previousHour" )
        get( "hits", "hour", "1" )

        Both calls to get() return the number of hits to the site that occured during the hour before the current one.

      6. get( "hits", "thisMonth" )
        get( "hits", "month", "0" )

        Both calls to get() return the number of hits to the site that occured during the current month.

      7. get( "hits", "previousMonth" )
        get( "hits", "month", "1" )

        Both calls to get() return the number of hits to the site that occured during the month before the current one.

      8. get( "hits", "thisYear" )
        get( "hits", "year", "0" )

        Both calls to get() return the number of hits to the site that occured during the current year.

      9. get( "hits", "previousYear" )
        get( "hits", "year", "1" )

        Both calls to get() return the number of hits to the site that occured during the year before the current one.

      10. get( "hits", "SQL COMPLIANT DATE" )

        You may also use the get() function with a specific date, defined by a SQL compliant datestring.

        For instance, $counter->get( "hits", "2000-05-14 08" ), will return the number of hits that occured on May, 14th 2000 between 8 AM and 9 AM.


    Please refer also to phpOpenCounterStatus.php in the "tools" folder to see the get function in action.

  • last( $mode, $limit )

    Returns an array containing the last $modes, max is $limit
    $mode can be one of the following: "document", "host", "ip", "referer", "user_agent".

    Usage
    $array[$x] contains the $x (0 is the last) value ("document", "host", "ip", "referer", "user_agent")

    Example
    $array = $counter->last("document");
    $array[0] contains for instance "/path/document";

  • top( $mode, $limit, $start, $end )

    Returns an array containing the top $mode, ranged by $start and $end, max is $limit
    $mode can be one of the following: "document", "host", "ip", "referer", "user_agent".

    Usage
    $array[$x][value] contains the $x (0 is the last) name of value ("document", "host", "ip", "referer", "user_agent")
    $array[$x][hits] contains the corresponding hits of value

    Example
    $array = $counter->top("document");
    $array[0][value] contains for instance "/path/document" and
    $array[0][hits] contains 2000;

"Full-Featured" or "Light" mode?

If you just want a plain, small counter you should use phpOpenCounter in the light mode by instantiating the phpOpenCounter class as follows:

$counter = new phpOpenCounter( $start, 0 );

Make sure to set $start to either 0 or 1 depending on whether or not you want to start counting directly when getting an instance of the class.

Session Managment with phpOpenCounter

Yes, you can use phpOpenCounter for session managment.

phpOpenCounter's API function get( users_online ) returns not only the userlog's fields that are defined per default (see SQL table definitions above for details), but also every additional field you may have added to the userlog table.

Imagine you have added a field called USER_ID to your userlog table. Imagine furthermore that you have a secured realm on your site and visitors have to enter a username and password to access it. You may now use a PHP script to verify the submitted data against your user database. If the given username / password combination was correct and the user has the authorization to enter that specific realm you set the visitor's userlog table entry to his user_id you retrieved from your user database.

Changelog

  • Version 2.1.0-pre1, released 14-May-2000

    • Removed old changelog entries, there have been too many changes since version 2.0.1 too mention.


  • Version 2.1.0, released 16-May-2000

    • The database scheme in the manual was wrong; corrected.

    • Removed inconsistencies in function definitions; phpOpenCounter should now run stable in an PHP3 environment.

    • There have been reports of errors with the PHP3 backport of PHP4's sessionmanagment we use to make phpOpenCounter runnable in an PHP3 environment. After moving the inclusion for "sessions.php" from "phpOpenCounter.php" to the outside (see "phpOpenCounterTest.php" for instance) it runs fine.

Copyright

Copyright (c) 2000 by Sebastian Bergmann.

This software and all associated files are released under the GNU Lesser Public License (LGPL), see license.txt for details.

Check http://sourceforge.net/project/?group_id=1716 for mailinglists, reporting bugs and all other related information to the phpOpenCounter project.

This software wouldn't have been possible without the help of the following people:

  • Alexander Meis, who first introduced me to the concept of the userlog table

  • Daniel Beulshausen, who helped developing the new API design for version 2.1.0 and contributed the last() and top() functions

  • Bart van Bragt, who said that phpOpenCounter's old database scheme was "everything but a charm" and put a lot of effort into changing that fact :-)