Appunti sulla realizzazione di questo sito. BiccariCounter.php, un contatore di accessi unici

I contatori

Esistono molti siti che offrono un'analisi dei visitatori del nostro sito. Uno dei servizi gratuiti più famosi e potenti è Google Analytics che però è un po' pesante.

Se non avete bisogno di prodotti professionali basta anche un semplice script in PHP. Qui di seguito riporto lo script da me realizzato, BiccariCounter.php.

<?php
/*
*
* BiccariCounter.php
* ==================
*
* Autore:  Francesco Biccari
* Data:    2011-04-21
* Contact: biccari@altervista.org
* Version: 3.1
*
*
* PRESENTAZIONE
* BiccariCounter.php è una classe PHP per il conteggio delle visite
* uniche giornaliere di un sito, basato sui cookie. Gli accessi
* provenienti da persone che usano un browser che non supporta i
* cookie o dove i cookie sono stati disabilitati (casi molto rari)
* non saranno "unici" cioè anche un semplice refresh della pagina
* produrrà una visita in più.
* È possibile specificare una lista di motori di ricerca che saranno
* esclusi dal conteggio delle visite uniche. Il controllo è fatto
* attraverso l'user agent.
* Vengono automaticamente esclusi anche tutti gli accessi con user
* agent vuoto.
*
* LICENZA
* BiccariCounter.php è di pubblico dominio.
* 
* USO
*   Creare un file vuoto chiamato stats.txt dove si vuole purché PHP
*      sia in grado di scriverci dentro. (Sul provider Aruba, se si
*      usa l'hosting su macchine Windows l'unica possibilità di
*      accedere in scrittura al file stats.txt è metterlo nella
*      cartella public.)
*   Modificare il presente script specificando nella costante filename il
*      percorso assoluto del file stats.txt e copiare lo script così
*      modificato in una cartella qualsiasi del sito, usando un nome
*      qualsiasi (BiccariCounter.php è un suggerimento).
*      Nota: per scoprire il percorso assoluto di un file dovete
*            eseguire il codice PHP <?php echo getcwd(); ?> da una
*            pagina .php contenuta nella cartella di vostro interesse.
*            Il motivo è che i percorsi visibili dall'interprete PHP
*            sono diversi da quelli che vedete voi accedendo al vostro
*            spazio FTP.
*   Richiamare lo script in ogni pagina del proprio sito (per esempio 
*      tramite un include di php usando il percorso assoluto).
*      Subito dopo aver richiamato lo script istanziate un oggetto
*      della classe Counter. Per esempio:
*         <?php include('BiccariCounter.php'); $myCounter=new Counter(); ?>
*   Opzionale: richiamare il distruttore della classe alla fine di ogni
*      pagina. Per esempio:
*         <?php unset($myCounter); ?>
*
*   Per vedere il numero delle visite avete due possibilità:
*      1. aprite il file stats.txt e leggete il numero ivi contenuto;
*         apparentemente soluzione stupida ma evita il sovraccarico
*         nell'uso del file stats.txt nel caso il vostro sito abbia
*         molti accessi.
*      2. nel codice HTML eseguite il metodo getUniqueVisitors che non
*         fa altro che leggere il file stats.txt e restituire il suo
*         valore. Per esempio:
*         Le visite sono <?php echo $myCounter->getUniqueVisitors(); ?>
*         Usate questo metodo se volete che gli altri sappiano in tempo
*         reale quanti contatti unici ha avuto il vostro sito.
*
*
* OPZIONI AVANZATE
*   Se si cambia la costante logging a un valore maggiore di 0,
*   ogni volta che ci sarà un accesso unico (no presenza cookie) lo 
*   script registrerà alcune informazione di quella visita in un file
*   a piacimento che va specificato nella costante logfile.
*   Tale file va creato, con i permessi in scrittura, prima di abilitare
*   la funzione di logging.
*   La funzionalità di logging appesantisce il server e il caricamento
*   della pagina e va quindi usata solo per periodi di test e solo
*   in presenza di un numero di accessi medi giornalieri inferiori a 100.
*   Se volete potete aggiungere altri motori di ricerca o in generale
*   altri user agent a quelli da escludere. Basta aggiungerli all'array
*   botlist creato all'interno del metodo isrobot().
*
*
* NOTE
*   Questo script è stato realizzato in poche ore scopiazzando da codici
*   simili su internet e studiando un po' di PHP. Non ha alcun controllo
*   e gestione degli errori ed è un prodotto amatoriale. Non va usato su
*   siti web professionali.
*
*/
class Counter {

  // Costanti della classe
  
  // Unico parametro da modificare per far funzionare questo script
  const filename = '/membri/biccari/stats.txt';
  // Altri parametri avanzati
  const logging = 0;
  const logfile = '/membri/biccari/log.txt';
  
  
  // DA QUI IN POI NON VA MODIFICATO NULLA!
  
  // attributo della classe: l'user agent
  private $agent = '';
  private $robot = false;
  
  // Costruttore
  public function __construct() {
  
    $this->agent = $_SERVER['HTTP_USER_AGENT'];
    $this->robot = $this->isrobot();
    
    // Se la visita viene da un nuovo visitatore (cioè non ha un
    // cookie già presente) e se il visitatore non rientra nella
    // lista dei motori di ricerca () allora si incremente di 1
    // il valore riportato dentro il file stats.txt e si scrive
    // un cookie con scandenza di 24 ore
    if(!isset($_COOKIE['uvisits']) and !$this->robot) {
      $this->increment();
      setcookie('uvisits', true, time()+86400, '/');
      // the root path '/' is necessary in order to have a cookie
      // valid for all the website pages.
    }
    
    if(self::logging > 0 and !isset($_COOKIE['uvisits'])  and !$this->robot) {$this->writelog();}
  }
  
  // Distruttore
  public function __destruct() {}
  
  // Metodo per capire se il visitatore è un motore di ricerca
  private function isrobot() {
    $botlist = array('Googlebot','Yahoo! Slurp','bingbot','YandexBot','LinkChecker',
    'ia_archiver','Baiduspider','msnbot-media','Mail.Ru','Speedy Spider');
    foreach($botlist as $bot){
		  if((strpos($this->agent,$bot) !== false) or ($this->agent == ''))
		    return true;	// Is a bot
	  }
    return false; // Is not a bot
  }
  
  // Metodo per incrementare di 1 i visitatori unici
  private function increment() {
    $handle = fopen(self::filename, 'r+');
    flock($handle, LOCK_EX);
    $contents=file_get_contents(self::filename);
    $currentCount=(int)$contents;
    $currentCount++;
    fwrite($handle, "$currentCount");
    fclose($handle);
  }
  
  // Legge conteggi
  public function getUniqueVisitors() {
    $handle = fopen(self::filename, 'r');
    flock($handle, LOCK_EX);
    $contents=file_get_contents(self::filename);
    fclose($handle);
    return (int)$contents;
  }
  
  // Log
  private function writelog() {
    $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
    // $cookieset = isset($_COOKIE['uvisits']) ? 'yes' : 'no';
    $page = $_SERVER['REQUEST_URI'];
    $line = date('c') . ' ' . $ip  . ' ' . $this->agent . ' ' . $page;
    $handle = fopen(self::logfile, 'a');
    flock($handle, LOCK_EX);
    fwrite($handle, "$line\r\n");
    fclose($handle);
    return true;
  }
  
}
?>