61 DBMS 5 – login e registrazione oop

Rielaboriamo le pagine delle lezioni precedenti di login e registrazione fatte con il metodo procedurale, questa volta usando le oop. È evidente che molti aspetti procedurali di programmazione, per motivi didattici, non sono stati affrontati. Per esempio nella buona programmazione, il programmatore avrebbe costruito un aspetto architetturale differente, realizzando le proprie funzioni con le proprie mysqli che poi sarebbero state richiamate, cioè avrebbe realizzato un sistema wrapper.

Partiamo con la costruzioni di una pagina chiamata login.php uguale a dbms_form1.php, ma che richiama la action ad una pagina che andremo a creare chiamata elogin_oop.php.

La prima parte è identica:

<?php
 session_start();

 $nl="<br />";

 //recupero credenziali da file ESTERNO alla cartella pubblica del sito
 $accessData=parse_ini_file('../../../confagtest.ini');
 
 //prima di tutto un po' di sicurezza ...
 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 //ok la pagina è stata davvero richiamata dalla form
 
 //recupero il contenuto della textbox email
 $email = $_POST['email'];
 
 //... e quello della textbox password
 $psw = $_POST['password'];

Il primo cambiamento si ha nello stabilire la connessione al database, istanziando un nuovo oggetto mysqli (new mysqli)

 $db = @new mysqli ("localhost",$accessData['username'],$accessData['password']);

i parametri passati al costruttore sono gli stessi di quelli passati col metodo procedurale di mysqli_connect (ricordo che spesso si passa anche come quarto parametro il nome del database). Aggiungendolo separatamente si ha maggiore controllo nella gestione dell’errore qualora non trovasse il database, rispetto agli errori di connessione.

La differenza della oop è nella logica, se con il metodo procedurale richiamavo diverse funzioni mysqli, con il metodo oop creo l’oggetto e uso i metodi e le proprietà contenuti nella sua classe, il tutto diventa più chiaro e distinguibile.

Andiamo quindi a selezionare il ns database con if che controlla se lo trova

if ( ! @$db->select_db($accessData['dbname']) )
 {
 echo "Non trovo il database...".$nl;
 echo $db->connect_error . $nl;
 echo $db->sqlstate . $nl;
 die; 
 }

notiamo che non devo più specificare la connessione come prima, quella ormai è presente nell’oggetto $db (ricordo che la chiocciola davanti alle chiamate dei metodi, inibiscono i warning, perché saremo noi a gestirceli).

Aggiungo l’errore  per la connessione con il metodo connect_error:

if( $db->connect_error )
{ //gestione errore
 echo $db->connect_errno .$nl;
 echo $db->connect_error . $nl;
 echo $db->sqlstate . $nl;
 echo "Connessione fallita";
 die; 
}

un errore comune parafrasando il metodo procedurale è quello di verificare $db se è true o false, ma l’oggetto è creato quindi è per forza true, dobbiamo verificare se il suo metodo connect_error è true, se si allora richiamo gli errori di connessione.

Ripeto uguale la generazione del comando SQL

$comandoSQL = "select iduser, psw from users where email ='" . mysqli_escape_string($db, $email) ."'";

inviamo il comando con l’oggetto $db e metodo query

 $risultatoRicercaEmail = @$db->query($comandoSQL);

se il metodo query fallisce, non è perché non è stata trovata la mail, ma semplicemente perché c’è un errore nella select, facilmente di sintassi. Se il metodo query ha successo viene creato un oggetto ($risultatoRicercaEmail). Questo oggetto potrebbe anche avere zero record, è al suo interno che andremo ad effettuare il confronto se la mail è stata trovata. Creo l’if del bottone accedi, della query e dell’estrazione tramite il metodo fetch_assoc dell’oggetto $risultatoRicercaEmail e confronto della mail che se presente la sua riga viene inserita nell’array $riga

 if (isset($_POST['btnAccedi']))
 {
  if ($risultatoRicercaEmail) //la query ha avuto successo
  {
  //3 elaborare il risultato
  if ($riga = $risultatoRicercaEmail->fetch_assoc() ) //mail trovata, confrontiamo psw
 {
 //echo "Trovata".$nl;
 $autenticato = ($psw === $riga['psw']);
 }
 else
 $autenticato = false;

chiudiamo la connessione al database con l’oggetto

 $db->close;

la parte del redirect è uguale

if($autenticato)
 {
 $_SESSION['iduser']=$riga['iduser'];
 header("Location: main.php");
 }
 else
 header("Location: login.php?errore=1");
 exit;
 }
 else //fallita mysqli_query
 {
 echo "Problemi con il server data base ...".$nl;
 echo mysqli_sqlstate( $conn ) . $nl;
 echo mysqli_errno( $conn ) . $nl;
 echo mysqli_error( $conn ) . $nl;
 die;
 }
 }

Simile anche la parte della nuova registrazione, ricordando di sostituire le funzioni mysqli con i metodi dell’oggetto $db

else
 {
 //BOTTONE NUOVO UTENTE
 if ($riga = $risultatoRicercaEmail->fetch_assoc() )
 {
 $db->close;
 header("Location: login.php?errore=2"); //email gia' presente
 exit;
 }

 //insert into users values (null, 'e@j.com','eee')
 $comandoSQL = "insert into users values (null,'".$email."','".$psw."')";
 $esito = $db->query($comandoSQL);

 if ($esito)
 {
 $_SESSION['iduser'] = mysqli_insert_id( $db );
 $db->close;
 header("Location: main.php");
 }
 else
 {
 $db->close;
 header("Location: login.php?errore=3"); //inserimento fallito
 }
 exit;
 }
}

codice login.php completo

 <?php
session_start();

$nl="<br />";

//recupero credenziali da file ESTERNO alla cartella pubblica del sito
$accessData=parse_ini_file('../../../confagtest.ini');

//prima di tutto un po' di sicurezza ...
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
 //ok la pagina è stata davvero richiamata dalla form

 //recupero il contenuto della textbox email
 $email = $_POST['email'];

 //... e quello della textbox password
 $psw = $_POST['password'];

 //1 stabilire una (o più) connessione/i con un server
 //NB: con @ si sopprimono i warning/errori del comando
 //$db = @mysqli_connect("localhost",$accessData['username'],$accessData['password']);

 $db = @new mysqli ("localhost",$accessData['username'],$accessData['password']);

 if( $db->connect_error )
 { //gestione errore
 echo $db->connect_errno .$nl;
 echo $db->connect_error . $nl;
 echo $db->sqlstate . $nl;
 echo "Connessione fallita";
 die;
 }

 //2 selezionamo database
 if ( ! @$db->select_db($accessData['dbname']) )
 {
 echo "Non trovo il database...".$nl;
 echo $db->connect_error . $nl;
 echo $db->sqlstate . $nl;
 die;
 }

 $comandoSQL = "select iduser, psw from users where email ='" . mysqli_escape_string($db, $email) ."'";

 //2 inviare il comando
 $risultatoRicercaEmail = @$db->query($comandoSQL);

 //quale bottone è stato premuto, 'accedi' o 'nuovo utente'?
 if (isset($_POST['btnAccedi']))
 {
 if ($risultatoRicercaEmail) //la query ha avuto successo
 {
 //3 elaborare il risultato
 if ($riga = $risultatoRicercaEmail->fetch_assoc() ) //mail trovata, confrontiamo psw
 {
 //echo "Trovata".$nl;
 $autenticato = ($psw === $riga['psw']);
 }
 else
 $autenticato = false;

 //4 chiudere connessione
 $db->close;
 //redirect
 if($autenticato)
 {
 $_SESSION['iduser']=$riga['iduser'];
 header("Location: main.php");
 }
 else
 header("Location: login.php?errore=1");
 exit;
 }
 else //fallita mysqli_query
 {
 echo "Problemi con il server data base ...".$nl;
 echo mysqli_sqlstate( $conn ) . $nl;
 echo mysqli_errno( $conn ) . $nl;
 echo mysqli_error( $conn ) . $nl;
 die;
 }
 }
 else
 {
 //BOTTONE NUOVO UTENTE
 if ($riga = $risultatoRicercaEmail->fetch_assoc() )
 {
 $db->close;
 header("Location: login.php?errore=2"); //email gia' presente
 exit;
 }

 //insert into users values (null, 'e@j.com','eee')
 $comandoSQL = "insert into users values (null,'".$email."','".$psw."')";
 $esito = $db->query($comandoSQL);

 if ($esito)
 {
 $_SESSION['iduser'] = mysqli_insert_id( $db );
 $db->close;
 header("Location: main.php");
 }
 else
 {
 $db->close;
 header("Location: login.php?errore=3"); //inserimento fallito
 }
 exit;
 }
}
else
{
 header("Location: login.php?errore=4"); //non autenticato
 exit;
}

?>