Salve a tutti,
Tempo fa mi è capitato di dover realizzare un semplice meccanismo per potere loggare alcune operazione eseguite dagli utenti che navigavano sul mio sito; tale script si poggia su un database mysql per lo storage dei dati e utilizza solo qualche funzione php molto scarna. Riportiamo ora i passi da seguire:

Prima di tutto creiamo un nuovo file php e chiamiamolo ad esempio supporto.php: in esso metteremo la definizione di tutte le funzioni php che utilizzeremo in questo articolo,più precisamente:

Connection(…) : per connettersi al database del sito. Prende come argomento una stringa per identificare il database.
MyLog(…) : per salvare le informazioni sul log. Prende come argomento una descrizione generica dell’azione che l’utente sta compiendo e una stringa che verrà utilizzata come chiave per fare ricerche o selezioni.
ReadAllLog(): legge tutti i Log presenti sulla tabella
ReadLog(…): ritorna solo i Log che appartegono ad una particolare chiave

<?php

function Connection($switch_value){

switch($switch_value)

{

case 0:

$database_name=”database”;

$user_mysql=”user”;

$password_mysql=”pass”;

$server_mysql=”X.X.X.X”;

break;

}

$connection=mysql_connect($server_mysql,$user_mysql,$password_mysql) or die(“Nessuna connessione al Server Mysql “.mysql_error());

$section_db=mysql_select_db($database_name, $connection)or die(“Nessun database selezionato “.mysql_error());

}

function MyLog($description_log,$operation_log)

{

$query=”INSERT INTO `log` (

`log` ,

`description` ,

`operation` ,

`ip_user` ,

`time_operation`

)

VALUES (

NULL , ‘”.$description_log.”‘, ‘”.$operation_log.”‘, ‘”.$_SERVER[‘REMOTE_ADDR’].”‘,

CURRENT_TIMESTAMP);”;

mysql_query($query) or die(“query log fallita”.mysql_error());

}

function ReadAllLog()

{

$query=”SELECT * FROM  `log` “;

$data=mysql_query($query) or die(“query lettura log fallita”.mysql_error());

return $data;

}

function ReadLog($type)

{

$query=”SELECT * FROM  `log` WHERE `operation`='”.$type.”‘  “;

$data=mysql_query($query) or die(“query lettura log fallita”.mysql_error());

return $data;

}

?>

La funzione Connection è stata costruita con uno switch: in tale modo è possibile connettersi con diversi database cambiando solo l’argomento alla chiamata.Per aggiungere il collegamento ad un altro db, ci basterà aggiungere una nuova coppia case-break e inserire la definizione dei quattro valori ( nome server, user e password dell’utente mysql e IP del server Mysql). Nel caso avessimo solo un database, è sufficiente cancellare lo switch e scrivere direttamente i valori delle variabili dentro le funzioni mysql_connect e mysql_select_db.

La funzione MyLog non fa altro che costruire la richiesta SQL utilizzando i due argomenti ( descrizione e operazione) e alcune variabili predefinite come L’IP dell’utente ($_SERVER[‘REMOTE_ADDR’]). Successivamente prova ad inserire tale informazioni sul database ( nel caso fallisca, stampa un messaggio d’errore ed il motivo di tale problema). Le altre due funzioni invece sono per recuperare i vari Log( 1 Log= 1 riga della tabella) e non faranno altro che ritornare il risultato della nostra richiesta di lettura.

Il prossimo obiettivo è creare la tabella per salvare i dati sul nostro database:per fare ciò, potrete importarla direttamente tramite il file log.sql che troverete sul solito repository Lab oppure eseguendo direttamente il codice SQL sotto riportato sul vostro server Mysql. Per la gestione del database io vi consiglio il tool PhpMyAdmin , che semplifica notevolmente le operazioni di gestione della base dati tra cui l’importazione :

CREATE TABLE IF NOT EXISTS `log` (
`log` int(15) NOT NULL auto_increment,
`description` text NOT NULL,
`operation` varchar(100) NOT NULL,
`ip_user` varchar(30) NOT NULL,
`time_operation` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY  (`log`)
)  ;

Fatto questo, possiamo passare direttamente alla pagina di esempio; creiamo una pagina ( ex: test_log.php) ed inseriamo il seguente codice:

<?php

include(“supporto.php”);

Connection(0);

MyLog(“Sono dentro la pagina di test.php”,”NO_ERROR”);

?>

Con queste tre righe abbiamo realizzato il nostro primo log:  per salvare le informazioni ci basterà includere il file supporto.php e abilitare la connessione al db.Sarà poi la funzione MyLog ad interrogare il database. Vostro compito sarà quello di “posizionare” la funzione MyLog nelle porzioni di codice che considerate rilevanti e definire correttamente gli argomenti di tale funzione: ad esempio il secondo argomento, nel nostro esempio valorizzato a “NO_ERROR”, servirà più che altro per attaccare un ‘etichetta ad un sottoinsieme di questi dati di log. In tale modo possiamo ad esempio far segnalare  all’amministratore delle operazioni non idonee eseguite da utenti malevoli o riportare errori bloccanti nel codice oppure anche valutare l’utenza media del proprio sito.

Vediamo un esempio completo: costruiamo ora un semplice esercizio dove il nostro amministratore  può  controllare tutti i login eseguiti sul proprio sito e memorizzare eventuali ingressi malevoli. Per lo script del login ci poggiamo a quello già realizzato precedentemente in questo articolo.

-La pagina per loggarsi rimane la medesima dell’esempio (login.php)

-Il codice della pagina che elabora le informazioni per il login cambia leggermente ( login3.php)

<?php

session_start();

include(“supporto.php”);

Connection(0);

$utenti[0][“user”]=”user1″;

$utenti[0][“pass”]=”pass1″;

$utenti[1][“user”]=”user2″;

$utenti[1][“pass”]=”pass2″;

$utenti[2][“user”]=”user3″;

$utenti[2][“pass”]=”pass3″;

$page_to=”./page.php”;

$isLogged=false;

if(isset($_POST[‘user’]) && isset($_POST[‘pass’]))

{

for($i=0;$i<count($utenti);$i++)   {

if( $_POST[‘user’]==$utenti[$i][“user”] && $_POST[‘pass’]==$utenti[$i][“pass”] )

{

$isLogged=true;

}

}

if($isLogged)

{

$_SESSION[‘isLogged’]=”true”;

MyLog(“utente “.$_POST[‘user’].” ha loggato sul sito correttamente”,”LOGIN_OK”);

header(“Location:”.$page_to);

}

else

{

if(isset($_POST[‘user’]))

MyLog(“utente “.$_POST[‘user’].” ha tentato di loggare sul sito con esito negativo”,”LOGIN_ERROR”);

else

MyLog(“utente sconosciuto ha tentato diloggare sul sito con esito negativo”,”LOGIN_ERROR”);

header(“Location:login.php?error_login=1”);

}

}

else {

header(“Location:login.php?error_login=1”);

}

?>

Infine manca la pagina base, quella che ospiterà il meccanismo base per leggere il log( viene ripreso il codice della pagina page.php)

<?php

session_start();

if(!isset($_SESSION[‘isLogged’]))

{

header(“Location:login.php?error_login=1″);

}

else {

if($_SESSION[‘isLogged’]!=”true”)

{

header(“Location:login.php?error_login=1″);

}

}

?>

<html>

<head>

</head>

<body>

<div>

Utente Loggato!

</div>

<form method=”post”>

<select id=”type” name=”type”>

<option value=”LOGIN_ERROR”> Login Sbagliati</option>

<option value=”LOGIN_OK”>Login Corretti</option>

</select>

<input type=”submit” name=”search” value=”Search” />

</form>

<?php

include(“supporto.php”);

Connection(0);

if(!isset($_POST[“search”]))

$log=ReadAllLog();

else

{

$log=ReadLog($_POST[“type”]);

}

echo “<table><tr><td>ID</td><td>descrizione</td><td>operation</td><td>IP</td><td>Time Operation</td></tr>”;

while($box=mysql_fetch_array($log) )

{

echo “<tr><td>”.$box[“log”].”</td><td>”.$box[“description”].”</td><td>”.$box[“operation”].”</td><td>”.$box[“ip_user”].”</td><td>”.$box[“time_operation”].”</td></tr>”;

}

echo “</table>”;

?>

</body>

</html>

Il Meccanismo non è molto difficile: abbiamo una select box con dentro inseriti i valori delle etichette al momento supportate ( consiglio di prelevare direttamente i valori delle etichette dal db per essere più dinamici) ed un pulsante per azionare la ricerca. Nel caso il bottone non venisse cliccato ( il che accade la prima volta che entriamo in pagina), lo script chiama ReadAllLog() e mostrerà all’utente loggato tutti i Log attualmente salvati dentro una tabella HTML. Al contrario, se viene selezionato una label e cliccato il relativo pulsante, al refresh successivo verranno mostrati solo i Log che appartengono al dato sottoinsieme.
Se ora noi creassimo il nostro personale set di etichette ed inserissimo un controllo più rigido del login ( sarebbe meglio che il log lo vedesse solo l’amministratore), ecco che avremmo fra le mani un meccanismo per il tracking delle operazioni semplice e predisposto ad ogni tipo di modifica.
Il codice di questi script sarà consultabile e scaricabile presso il repository Lab.
Grazie per l’attenzione,

Andrea