back to top

I Prepared Statements in MySQLi

Il funzionamento dei Prepared Statements è stato ampiamente descritto nella parte di questa trattazione dedicata all’utilizzo dell’estensione PDO di PHP; riassumendo quanto anticipato, è possibile dire che tali costrutti rappresentano una modalità per rendere più sicure e performanti le operazioni che prevedono un’interazione tra un’applicazione e una base di dati.

Dal punto di vista della sicurezza essi non consentono l’esecuzione diretta delle istruzioni basate sul linguaggio SQL, più propriamente i Prepared Statements "preparano" dei template ai quali passare i dati coinvolti; la separazione tra dati ed istruzioni impedirà quindi l’esecuzione di codice malevolo, come per esempio quello impiegato per le SQL Injections.

Relativamente alle prestazioni, le istruzioni parametrizzate funzionano sulla base di schemi, i già citati template, che potranno essere riutilizzati senza la necessità che vengano ridefiniti, ciò rappresenta un vantaggio sia per quanto riguarda l’ottimizzazione dei sorgenti che in riferimento ai tempi necessari per la sua stesura.

Per evitare noiose ripetizioni sarà possibile proporre un semplice esempio pratico di Prepared Statements in MySQLi; a tale scopo si potrà definire un form destinato ad inviare un parametro di input che dovrà essere raccolto ed elaborato da un’applicazione PHP:

<form action="ps_mysqli.php" method="POST"> 
Scegli un valore nel campo sottostante:<br /> 
<input type="number" name="identificatore" min="1" max="10" step="1" value="1"><br/> 
<input type="submit" value="Invia"> 
</form>

Il modulo creato sarà quindi associato alla seguente applicazione (contenuta nel file "ps_mysqli.php") che effettuerà un’estrazione dalla tabella "agenda" sulla base del parametro ricevuto:

<?php
/*
  uso dei prepared statements per l'estrazione di dati con MySQLi
*/
  
if(isset($_POST['submit']) || isset($_POST['identificatore'])){

  // inclusione del file di connessione
  include "connessione.php";  

  // preparazione della query per la selezione dei record
  $stmt = $connessione->prepare("SELECT nome, cognome FROM agenda WHERE id=?");

  // definizione della variabile per la sostituzione del placeholder
  $stmt->bind_param("i", $id);
  
  // valorizzazione della variabile per l'esecuzione   
  $id = $_POST['identificatore'];
  $stmt->execute();

  // estrazione dei risultati
  $result = $stmt->get_result();
  // conteggio dei record
  if ($result->num_rows > 0) {
  while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
    echo $row['nome'] ." ". $row['cognome'];
  }
  }else{
  echo "Nessun dato presente per l'Id selezionato.";
  }
  // chiusura dello statement
  $stmt->close();
  // chiusura della connessione
  $connessione->close();
}else{
  echo "Nessun parametro inviato dal form.";
}    
?>

Dopo aver incluso il file "config.php" per la connessione a MySQL e la selezione del database, si potrà passare alla fase per la realizzazione del template, come sarà possibile notare esso verrà introdotto dal metodo prepare() e presenterà una sintassi simile a quella di un’istruzione SQL:

"SELECT nome,cognome FROM agenda WHERE id=?"

A caratterizzare il template è però la presenza di un simbolo ("?") utilizzato al posto del parametro che dovrà essere passato alla clausola WHERE; tale simbolo prende il nome di placeholder o "segnaposto".

I Prepared Statement in MySQLi prevedono il binding dei parametri, ciò significa che il placeholder precedentemente introdotto verrà vincolato ad una variabile, passata al metodo bind_param(), della quale dovrà essere indicato il tipo di dato. Nel caso specifico del nostro esempio avremo come variabile $id ed essa verrà associata ad un tipo di dato numerico intero simboleggiato dal parametro "i":

$stmt->bind_param("i", $id);

in alternativa sarà possibile utilizzare:

  • "d": per variabili associate al tipo di dato double;
  • "s": per variabili con tipo di dato string;
  • "b": "blob", per dati in formato binario.

Una volta stabilita la variabile per il binding, quest’ultima sarà finalmente associabile al parametro inviato dal form ("$_POST[‘identificatore’]"), fatto questo il metodo execute() permetterà di eseguire la query preparata tramite il template mentre get_result() renderà disponibile il risultato di tale esecuzione.

Fatto questo sarà possibile utilizzare il metodo num_rows() per controllare il numero dei record coinvolti dalla query, se questo dovesse essere superiore a zero si potrà utilizzare il metodo fetch_array() all’interno di un ciclo che permetterà di iterare l’array contenente i risultati. Una volta stampati questi ultimi, il metodo close() consentirà di liberare le risorse occupate e di chiudere la connessione.

Pubblicitร 
Claudio Garau
Claudio Garau
Web developer, programmatore, Database Administrator, Linux Admin, docente e copywriter specializzato in contenuti sulle tecnologie orientate a Web, mobile, Cybersecurity e Digital Marketing per sviluppatori, PA e imprese.