Ciao a tutti,
inauguro questa sezione pubblicando una classe per la gestione delle visite
La classe può essere implementata con la ricerca per data o con la geolocalizzazione per esempio
Manca completamente una gestione degli errori
La classe cmq è abbastanza commentata non dovreste avere difficoltà, al massimo chiedete pure
Ho preparato un esempio funzionante (spero) online a questo indirizzo, la stessa pagina registrerà la visita e mostrerà la tabella statistiche
Iniziamo, occorrono tre tabelle
- agent
memorizziamo gli user agent degli utenti per rispoarmiare spazio sul database
- pagine
per lo stesso motivo cui sopra memorizziamo i nomi delle pagine. Ho gia inserito una pagina di test
- visite
verranno memorizzati tutti i dati necessari della visita ricevuta.
Passiamo alla classe. Vi ricordo che non è completa e che probabilmente la aggiornerò piu avanti seguendo i vostri consigli
Per far funzionare la paginazione è necessaria una piccola funzione javascript che reimposta i valori della pagina e dei record da visualizzare
Per registrare correttamente la visita bisogna inserire nella tabella pagine il nome della pagina soggetta alla registrazione delle visite e richiamare il metodo salva_visita(id) passandogli l'id
Per visualizzare la tabella delle statistiche è sufficiente richiamare in una pagina il metodo tabella_visite()
Per l'esempio online ho usato il seguente codice css
Che altro aggiungere? :byebye:
inauguro questa sezione pubblicando una classe per la gestione delle visite
La classe può essere implementata con la ricerca per data o con la geolocalizzazione per esempio
Manca completamente una gestione degli errori
La classe cmq è abbastanza commentata non dovreste avere difficoltà, al massimo chiedete pure
Ho preparato un esempio funzionante (spero) online a questo indirizzo, la stessa pagina registrerà la visita e mostrerà la tabella statistiche
Iniziamo, occorrono tre tabelle
- agent
memorizziamo gli user agent degli utenti per rispoarmiare spazio sul database
Codice:
CREATE TABLE IF NOT EXISTS `agent` (
`idAgent` int(11) NOT NULL AUTO_INCREMENT,
`agent` varchar(255) NOT NULL,
PRIMARY KEY (`idAgent`),
KEY `agent` (`agent`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
per lo stesso motivo cui sopra memorizziamo i nomi delle pagine. Ho gia inserito una pagina di test
Codice:
CREATE TABLE IF NOT EXISTS `pagine` (
`idPagina` int(11) NOT NULL AUTO_INCREMENT,
`nome` varchar(155) NOT NULL,
PRIMARY KEY (`idPagina`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `pagine` (`idPagina`, `nome`) VALUES
(1, 'Pagina di test');
verranno memorizzati tutti i dati necessari della visita ricevuta.
Codice:
CREATE TABLE IF NOT EXISTS `visite` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(155) NOT NULL,
`idAgent` int(11) NOT NULL,
`data` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`lingua` varchar(2) NOT NULL,
`referer` varchar(255) NOT NULL,
`idPagina` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `data` (`data`),
KEY `idPagina` (`idPagina`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
PHP:
<?php
/**
* 03 settembre 2013
* @criric
* licenza free
* fatene quello che volete, tenete conto che la classe non è completa
*/
class Visite {
// oggetto mysqli
var $sql;
// date per la ricerca
var $dal;
var $al;
/**
* Nel costruttore istanzio la classe per la connessione al database
* Setto le proprietà per il periodo di ricerca
* Non ancora implementato ma prevede date ricevute tramite POST
*/
public function __construct() {
// istanzio la classe per la connessione al database
$this->sql = new mysqli("localhost", "root", "", "database");
// Setto le proprietà per il periodo di ricerca
$this->dal = date("Y-m-") . "01";
// se settata la data in POST
if (isset($_POST['dal'])) {
$this->dal = $_POST['dal'];
}
$this->al = date("Y-m-d");
// se settata la data in POST
if (isset($_POST['al'])) {
$this->al = $_POST['al'];
}
}
/**
* sfrutto il distruttore per chiudere la connessione al db
*/
public function __destruct() {
$this->sql->close();
}
/**
* Questo metodo registra la visita nella tabella visite
* Prende come parametro l'id della pagina
* Non implementata la gestione degli errori
* @param type $idPagina
* @return type boolean
*/
public function salva_visita($idPagina) {
// recupero il link da dove è arrivato il visitatore
$referer = (isset($_SERVER["HTTP_REFERER"])) ? $_SERVER["HTTP_REFERER"] : "n/d";
// richiamo il metodo per l'agent
$idAgent = $this->id_agent();
// query di inserimento
$query = "INSERT INTO visite
SET ip = '" . $_SERVER["REMOTE_ADDR"] . "',
idAgent = '" . $idAgent . "',
lingua = '" . substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2) . "',
referer = '" . $referer . "',
idPagina = '" . $idPagina . "'";
// eseguo
if (!$this->sql->query($query)) {
// da implementare la gestione degli errori
$error = $this->sql->error;
return false;
}
// tutto ok
return true;
}
/**
* Per risparmiare spazio sul db
* questo metodo verifica se l'agent del visitatore è gia memorizzato nella tabella agent
* Restituisce l'id corrispondente
* @return type int
*/
private function id_agent() {
// cerco l'agent nella tabella agent
$query = "SELECT idAgent FROM agent WHERE agent = '" . $_SERVER["HTTP_USER_AGENT"] . "'";
// eseguo la query
$result = $this->sql->query($query);
// se trovo un risultato
if ($result && $result->num_rows > 0) {
$row = $result->fetch_row();
// restituisco l'id corrispondente
return $row[0];
}
// altrimenti inserisco in tabella il nuovo agent
$query = "INSERT INTO agent SET agent = '" . $_SERVER["HTTP_USER_AGENT"] . "'";
if ($this->sql->query($query)) {
// restituisco l'id corrispondente
return $this->sql->insert_id;
}
// qualcosa è andato storto : da implementare uina gestione per gli errori
return false;
}
/**
* Questo metodo restituisce il numero di record per la ricerca passata nei parametri
* Usa le proprieta per il periodo di ricerca
* @param type $pagina boolean
* @param type $uniche boolean se true raggruppa per ip
* @return type int
*/
public function conta_visite($pagina = false, $uniche = false) {
$query = "SELECT id
FROM visite
WHERE data BETWEEN '" . $this->dal . "' AND DATE_ADD('" . $this->al . "', INTERVAL 1 DAY)";
if ($pagina) {
$query .= " && idPagina = '" . $pagina . "'";
}
if ($uniche) {
$query .= " GROUP BY ip";
}
$result = $this->sql->query($query);
if ($result) {
return $result->num_rows;
}
// qualcosa è andato storto : da implementare uina gestione per gli errori
return false;
}
/**
* Potrebbe essere necessario nascondere parte dell'ip
* questo metodo nasconde le ultime due parti dell'ip passato come parametro
* @param type $ip
* @return string
*
*/
private function nascondi_ip($ip) {
$ex = explode(".", $ip);
$return = $ex[0] . "." . $ex[1] . ".";
for ($i = 0; $i < strlen($ex[2]); $i++) {
$return .= "*";
}
$return .= ".";
for ($i = 0; $i < strlen($ex[3]); $i++) {
$return .= "*";
}
return $return;
}
/**
* Questo metodo stampa la tabella delle visite
* Usa le proprieta per il periodo di ricerca
* Usa i dati ricevuti in post per filtrare la ricerca
* Implementata la paginazione
* @param type $pagina
*/
public function tabella_visite() {
// imposto l'id pagina a false per visualizzare tutti i record
// non implementata la ricerca per altre pagine
$idPagina = false;
// verifico se è settata una pagina in particolare
if (isset($_POST['id_pag'])) {
$idPagina = (int) $_POST['id_pag'];
// se id pagina è arrivato in forma corretta
if ((int) $_POST['id_pag'] > 0) {
// setto l'id pagina per la ricerca
$idPagina = (int) $_POST['id_pag'];
}
}
// imposto la prima pagina da visualizzare
$num_pag = 1;
// verifico che sia settata la pagina da visualizzare
if (isset($_POST['num_pag'])) {
$num_pag = (int) $_POST['num_pag'];
// se la pagina è arrivata in forma corretta
if ((int) $_POST['num_pag'] > 0) {
// setto la prima pagina
$num_pag = (int) $_POST['num_pag'];
}
}
// imposto il limite di risultati per pagina
$limite_pag = 10;
// verifico se settato il limite per pagina
if (isset($_POST['limit'])) {
// se il limite è arrivato in forma corretta
if ((int) $_POST['limit'] > 0) {
// reimposto il limite di risultati per pagina
$limite_pag = (int) $_POST['limit'];
}
}
// imposto il limite minimo da usare nella query
if ($num_pag <= 1) {
$limite_min = 0;
} else {
$limite_min = ($num_pag - 1) * $limite_pag;
}
// imposto il limite massimo sul quale finirà la ricerca
$limite_max = $limite_min + $limite_pag;
// recupero il numero totale di visite
$totali = $this->conta_visite($pagina);
// recupero il numero di visite uniche
$uniche = $this->conta_visite($pagina, true);
// se il limite massimo supera i record totali lo fermo al numero di record totali
if ($totali <= $limite_max) {
$limite_max = $totali;
}
// recupero il numero di pagine totali
$pagine = ceil($totali / $limite_pag);
// query di ricerca
$query = "SELECT V.lingua, V.ip, A.agent, V.referer,
IF(P.nome IS NULL, 'n/d', P.nome) as nomePagina,
DATE_FORMAT(V.data, '%d/%m/%Y %H:%i:%s') as data
FROM visite V
LEFT JOIN pagine P USING(idPagina)
JOIN agent A USING(idAgent)
WHERE data BETWEEN '" . $this->dal . "' AND DATE_ADD('" . $this->al . "', INTERVAL 1 DAY)";
if ($idPagina) {
$query .= " && pagina = '" . $idPagina . "'";
}
$query .= " ORDER BY data DESC LIMIT $limite_min, $limite_pag";
// eseguo
$result = $this->sql->query($query);
echo "<form method='post' action='" . $_SERVER['PHP_SELF'] . "' > ";
echo "<table>";
echo "<thead>";
echo "<tr class='filtri'>";
echo "<td colspan='7'>";
echo "Report visite dal " . $this->format_data_it($this->dal) . " al " . $this->format_data_it($this->al);
echo "<input type='hidden' name='num_pag' value='1'/>";
echo "</td>";
echo "</tr>";
// se la query ha prodotto dei riultati
if ($result->num_rows > 0) {
echo "<tr><td colspan='7'>";
echo "<span class='fleft'>";
echo "Totale visite : $totali Uniche : " . $uniche;
echo "</span>";
echo "<span class='fright'>";
echo "Record per pagina <select name='limit' onchange='this.form.submit()'>";
for ($i = 5; $i <= 50; $i+=5) {
echo "<option value='$i' ";
if ($i == $limite_pag)
echo " selected='selected'";
echo ">$i</option>";
}
echo "</select>";
echo "</span>";
echo "</td></tr>";
echo "<tr>";
echo "<th>Data</th>";
echo "<th>Pagina</th>";
echo "<th>Sistema operativo</th>";
echo "<th>Browser</th>";
echo "<th>Lingua</th>";
echo "<th>Ip</th>";
echo "<th>Referer</th>";
echo "</tr>";
echo "</thead>";
echo "<tbody>";
$i = 0;
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$alternate = ($i % 2 == 0) ? "class='alternate'" : "";
echo "<tr $alternate>";
echo "<td>" . $row["data"] . "</td>";
echo "<td>" . $row["nomePagina"] . "</td>";
echo "<td>" . $this->sistema_operativo($row["agent"]) . "</td>";
echo "<td>" . $this->browser($row["agent"]) . "</td>";
echo "<td class='center'>" . $row["lingua"] . "</td>";
echo "<td>" . $this->nascondi_ip($row["ip"]) . "</td>";
echo "<td class='center info' title='" . $row["referer"] . "'> ? </td>";
echo "</tr>";
$i++;
}
echo "<tr>";
echo "<td colspan='7' class='infopag'>";
if ($num_pag <= 1) {
$click = "onclick='return false'";
} else {
$click = "onclick='ImpostaPagina(" . ($num_pag - 1) . "," . $limite_pag . ")'";
}
echo "<span onclick='ImpostaPagina(1," . $limite_pag . ")' title='prima' class='navpag'><<</span>";
echo "<span title='precedente' class='navpag' $click><</span>";
echo "<span class='navinfo'>Pagina $num_pag / $pagine</span>";
if ($num_pag >= $pagine) {
$click = "onclick='return false'";
} else {
$click = "onclick='ImpostaPagina(" . ($num_pag + 1) . "," . $limite_pag . ")'";
}
echo "<span title='sucessiva' class='navpag' $click>></span>";
echo "<span onclick='ImpostaPagina(" . $pagine . "," . $limite_pag . ")' title='ultima' class='navpag'>>></span>";
echo "</td>";
echo "</tr>";
echo "</tbody>";
// altrimenti
} else {
// nessun riultato
echo "<tr><td colspan='7'>Nessun record trovato</td></tr>";
}
echo "</table>";
echo "</form>";
}
/**
* Restituisce la data formattata in italiano
* @param stringa $data yyyy-mm-dd hh:ii:ss
* @param int $ora 1 o 0 mostra o meno l'ora
* @return stringa
*/
private function format_data_it($data, $ora = 1) {
$split = explode(" ", $data);
$d = explode("-", $split[0]);
$d = array_reverse($d);
if ($ora == 1) {
return implode("/", $d) . " " . $split[1];
} else {
return implode("/", $d);
}
}
/**
* Estrae dall'agent il sistema operativo
* è possibile inserire nell'array i sistemi mancanti seguendo la stessa loogica
* @param type $agent
* @return type
*/
private function sistema_operativo($agent) {
$so = array(
'Windows NT 6.2' => 'Windows 8',
'Windows NT 6.1' => 'Windows 7',
'Windows NT 6.0' => 'Windows vista',
'Windows NT 5.1' => 'Windows XP',
'Windows NT 5.0' => 'Windows 2000',
'Windows NT 4.90' => 'Windows ME',
'Win95' => 'Windows 95',
'Win98' => 'Windows 98',
'Windows NT 5.2' => 'Windows NET',
'WinNT4.0' => 'Windows NT',
'Mac|PPC' => 'Mac',
'Linux' => 'Linux',
'FreeBSD' => 'FreeBSD',
'SunOS' => 'SunOS',
'Irix' => 'Irix',
'BeOS' => 'BeOS',
'OS/2' => 'OS/2',
'AIX' => 'AIX'
);
foreach ($so as $chiave => $valore) {
if (strstr($agent, $chiave)) {
return $valore;
}
}
return 'n/d';
}
/**
* Estrae dall'agent il browser
* è possibile inserire nell'array i browser mancanti seguendo la stessa loogica
* @param type $agent
* @return type
*/
private function browser($agent) {
$browser = array(
"Internet Explorer 9" => "MSIE 9",
"Internet Explorer 8" => "MSIE 8",
"Internet Explorer 7" => "MSIE 7",
"Internet Explorer 6" => "MSIE 6",
"Internet Explorer" => "MSIE",
"Chrome" => "Chrome",
"Mozilla Firefox 23" => "Firefox/23",
"Mozilla Firefox 20" => "Firefox/20",
"Mozilla Firefox 8" => "Firefox/8",
"Mozilla Firefox 7" => "Firefox/7",
"Mozilla Firefox 6" => "Firefox/6",
"Mozilla Firefox 5" => "Firefox/5",
"Mozilla Firefox 4" => "Firefox/4",
"Mozilla Firefox 3" => "Firefox/3",
"Mozilla Firefox" => "Firefox",
"Lynx" => "Lynx",
"Opera 10" => "Opera/10",
"Opera 9" => "Opera/9",
"Opera" => "Opera",
"Konqueror" => "Konqueror",
"Safari" => "Safari",
"GoogleBot" => "Googlebot",
"BingBot" => "bingbot",
"W3C" => "W3C"
);
foreach ($browser as $chiave => $valore) {
if (strstr($agent, "$valore")) {
return $chiave;
}
}
return "n/d";
}
}
?>
HTML:
<script type="text/javascript">
function ImpostaPagina(pagina,limite){
document.forms[0].elements['limit'].value = limite;
document.forms[0].elements['num_pag'].value = pagina;
document.forms[0].submit();
}
</script>
PHP:
<?php
// includo il file che contiene la classe
include 'visite_class.php';
// istanzio la classe
$visite = new Visite();
// richiamo il metodo passandogli l'id della pagina
$visite->salva_visita(1);
?>
PHP:
<?php
// includo il file che contiene la classe
include 'visite_class.php';
// istanzio la classe
$visite = new Visite();
// stampo la tabella visite
$visite->tabella_visite();
?>
Codice:
html body {
text-align: center;
font-family: Tahoma;
font-size: 13px;
color:#456;
}
a {
color:#456;
}
table {
border-collapse: collapse;
margin:auto;
box-shadow: 10px 10px 5px #888;
}
table th {
text-align: left;
background-color: #4A4A4A;
color: #FFFFFF;
font-weight: bold;
padding: 10px;
}
table td {
border: 1px solid #D2D2D2;
padding: 8px 10px 8px 10px;
}
table tr.alternate {
background-color: #ECECEC;
}
.center {
text-align: center;
}
.left {
text-align: left;
}
table td.infopag {
text-align: center;
border: none;
padding: 10px;
}
span.navpag {
border: 1px solid #D2D2D2;
border-radius: 4px;
padding:2px 6px 2px 6px;
text-decoration: none;
letter-spacing: -3px;
cursor:pointer;
margin: 0 1px 0 1px;
}
span.navinfo {
margin: 0 8px 0 8px;
}
.info {
cursor: help;
font-weight: bold;
}
.fright {
float: right;
}
.fleft {
float: left;
}
.filtri {
font-weight: bold;
}
Ultima modifica: