16 Novembre 2014 13:27:48 · [Contatore Php AntiReload]
Postato da
Un buon pomeriggio a tutti! Qualche giorno fa mi sono riscritto il contatore php pensandolo stavolta in modo diverso... ho infatti introdotto un sistema che evita il conteggio delle visite in presenza di un reload (o refresh) della pagina o nel caso in cui venga cliccato un link sulla stessa pagina che carica la medesima pagina (esempio: $_SERVER['PHP_SELF']). In questo modo verranno conteggiate solo le visite che provengono da una pagina differente o da link che non provocano il reload della pagina. In definitiva se l'utente passa da una pagina all'altra (anche se tale operazione viene eseguita più volte) è comunque una visita mentre un reload non è una visita e se sono presenti link realizzati mediante uso di $_SERVER['PHP_SELF'], la visita viene scartata ovviamente perché non può, a mio modo di vedere, essere considerata una nuova visita. Il mio contatore inoltre conta più pagine contemporaneamente e non impone limiti di IP perché se ad esempio nella stessa famiglia due membri stanno visitando la medesima pagina sono due visite e non una come molti erroneamente potrebbero pensare. Infatti se avessi introdotto un meccanismo IP, il contatore si sarebbe aggiornato in caso di IP differente, col mio sistema invece vengono contate tutte le visite autentiche e utili. Il mio modo di vedere può essere più o meno condivisibile ma poiché si tratta di una mia creazione se lo usate dovete anche accettarne la filosofia   Innanzitutto create nella root del vostro sito web due cartelle: cnt e log. Nella cartella cnt mettete i due script che seguono ossia cnt.php e showcnt.php.

cnt.php

<?php
  ##############################################################################
  # Php Counter With Advanced Technology For The Prevention Of Reloading Pages #
  # Version: 1.4 - Date: 13.11.2014 - Created By Alessandro Marinuzzi [Alecos] #
  ##############################################################################
  function cnt($file) {
    session_start();
    global $pagecnt;
    $reloaded = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
    $thispage = basename($_SERVER['SCRIPT_FILENAME']);
    if (!isset($_SESSION['first_go'])) {
      $_SESSION['first_go'] = 1;
      $first_go = TRUE;
    } else {
      $first_go = FALSE;
    }
    if (!isset($_SESSION['thispage'])) {
      $_SESSION['thispage'] = $thispage;
    }
    if ($_SESSION['thispage'] != $thispage) {
      $_SESSION['thispage'] = $thispage;
      $new_page = TRUE;
    } else {
      $new_page = FALSE;
    }
    $pagecnt = rtrim(file_get_contents($file));
    if ((!$reloaded) && ($new_page == TRUE) || ($first_go == TRUE)) {
      $fd = fopen($file, 'w+');
      flock($fd, LOCK_EX);
      fwrite($fd, ++$pagecnt);
      flock($fd, LOCK_UN);
      fclose($fd);
    }
  }
?>

showcnt.php

<?php
  ##############################################################################
  # Show Counter Results - v.1.4 - 13.11.2014 By Alessandro Marinuzzi [Alecos] #
  ##############################################################################
  function gfxcnt($file) {
    global $number;
    $number = rtrim(file_get_contents($file));
    $lenght = strlen($number);
    $gfxcnt = "";
    for ($i = 0; $i < $lenght; $i++) {
      $gfxcnt .= $number[$i];
    }
    $gfxind = "<span class=\"counter\"><span class=\"number\">$gfxcnt</span></span>";
    echo $gfxind;
  }
?>

Poi in cima alla pagina che volete contare mettete questa riga php che deve essere la prima in assoluto poiché contiene session_start() che deve essere eseguito prima di qualsiasi altro output. Ipotizziamo che la vostra pagina si chiami ad esempio index.php.

<?php session_start(); include("cnt/cnt.php"); cnt("log/index.txt"); include("cnt/showcnt.php"); ?>

Poi nella stessa pagina index.php mettete ovunque vogliate la riga seguente. Servirà ad invocare la lettura del file che contiene le visite. Potete ripetere il procedimento per qualsiasi altra pagina vogliate monitorare (ricordatevi solo di usare un nome diverso di pagina... esempio: blog.php e blog.txt) in quanto si tratta di un contatore multipagina.

<?php gfxcnt("log/index.txt"); ?>

Ricordatevi delle cartelle cnt e log che se non presenti produrranno errori. La cartella log conterrà le visite. Ricordatevi che comunque sarebbe opportuno introdurre un sistema di lock esclusivo visto che in ambienti server shared, il filesystem (NFS) non permetterà alla funzione flock di eseguire il lock esclusivo correttamente. Io ho implementato un sistema di lock esclusivo che tiene conto della Race Condition ma che non ho intenzione di pubblicare poiché preferisco che ciascuno di voi trovi la soluzione più adatta. Non dimenticatevi di stilizzare il contatore usando il css sfruttando le classi css che il contatore mette a disposizione (counter e number). E' tutto!  




Copyright © 2002-2018, Alessandro Marinuzzi