Uno degli ambiti di utilizzo pratico più importanti per i Prepared statements è quello che prevede l’invio di parametri per le query tramite campi form compilabili dagli utenti o querystring presenti nella URL di una pagina web (e pertanto facilmente alterabili dall’esterno), in questo caso, infatti, gli input non vengono determinati a priori dallo sviluppatore e il loro contenuto rimane sconosciuto all’applicazione fino al momento dell’elaborazione, anche se potenziamente pericoloso in quanto utilizzabile per veicolare istruzioni malevole.
Un semplice esempio riguardante il caso proposto potrebbe essere il seguente dove viene impiegato un modulo contenente un solo campo di testo:
<form action="ps_pdo.php" method="POST">
Il cognome dell'autore di "Le mie prigioni"?:<br />
<input type="text" name="cognome"><br/>
<input type="submit" value="Invia">
</form>
Tale campo permette di inviare un parametro che verrà utilizzato nel file "ps_pdo.php", cioè quello destinato all’elaborazione dell’input il cui codice viene proposto di seguito, per la costruzione della query SELECT o, più propriamente, per la generazione (nel nostro caso "preparazione") del template da adottare per l’eventuale selezione dei record interessati dall’istruzione:
<?php
if( (isset($_POST['submit'])) || (isset($_POST['cognome'])) ){
/*
blocco dei parametri di connessione
*/
// nome di host
$host = "localhost";
// nome del database
$db = "nominativi";
// username dell'utente in connessione
$user = "mrwebmaster";
// password dell'utente
$password = "...";
/*
blocco try/catch di gestione delle eccezioni
*/
try {
// stringa di connessione al DBMS
$connessione = new PDO("mysql:host=$host;dbname=$db", $user, $password);
// imposto l'attributo per il report degli errori
$connessione->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// definizione delle variabili per la query
$contatto_cognome = $_POST['cognome'];
// preparazione della query SQL
$sql = $connessione->prepare("SELECT id FROM contatti WHERE cognome = :contatto_cognome");
// bind dei parametri
$sql->bindParam(':contatto_cognome', $contatto_cognome, PDO::PARAM_STR, 7);
// esecuzione del prepared statement
$sql->execute();
// conteggio dei record coinvolti dalla query
if($sql->rowCount() > 0){
// creazione di un'array contenente il risultato
$result = $sql->fetchAll();
// ciclo dei risultati
foreach($result as $row)
{
echo $row['id'] . "<br />";
}
}else{
echo "Nessun record corrispondente alla richiesta.";
}
// chiusura della connessione
$connessione = null;
}
catch(PDOException $e)
{
// notifica in caso di errore nel tentativo di connessione
echo $e->getMessage();
}
}else{
echo "Nessun parametro inviato dal form.";
}
?>
Nello specifico il file per l’elaborazione del parametro inviato attraverso il form contiene uno script al quale spetta innanzitutto il compito di verificare che l’input sia stato effettivamente inviato; superato questo controllo si potrà passare alla fase di connessione al DBMS e alla selezione del database.
Il parametro ricevuto ("$_POST[‘cognome’]") sarà quindi associato ad una variabile ("$contatto_cognome") che verrà utilizzata successivamente per il binding; fatto questo il metodo prepare() consentirà di creare il template della query, in essa l’input da passare alla clausola WHERE sarà sostituito dal placeholder "contatto_cognome" che farà da segnaposto in attesa del binding.
Il binding verrà effettuato tramite il metodo bindParam() al quale saranno passati come argomenti il placeholder del template, la variabile che contiene il parametro di input, la costante PDO::PARAM_STR che vincolerà il parametro ad un tipo di dato testuale e il valore "7" che indicherà la lunghezza massima della stringa di input in termini di caratteri.
Il metodo execute() si occuperà di eseguire il Prepared statement, ma la stampa dei dati eventualmente estratti tramite la SELECT avverrà soltanto in presenza di record coinvolti il cui conteggio sarà affidato al metodo rowCount(); nel caso in cui il numero di tali record dovesse essere superiore a "0" il metodo fetchAll() permetterà di accedere, tramite ciclo, ad un set di risultati iterabile da utilizzare per la stampa dei dati estratti, cioè, nel nostro caso, tutti gli "id" dei record che soddisfano la condizione introdotta con la clausola WHERE.
Con questo capitolo si conclude la parte della nostra guida dedicata a PDO. A partire dal prossimo capito affronteremo, invece, l’utilizzo dell’estensione MySQLi.