PHP Prepared Statements and Data Binding

PHP Prepared Statements and Data Binding

pdo-php

La maggior parte dei database oggi supportano il concetto di prepared statements ma che cosa sono, ne avete mai visto uno? Dicono abbia la coda lunga ed un occhio solo… 🙄
In realtà è uno strumento avanzato e molto più sicuro per eseguire query in “modalità protetta” mettendosi così al riparo da minacce come SQL Injection. Sul sito ufficiale scrivono “They can be thought of as a kind of compiled template for the SQL that an application wants to run, that can be customized using variable parameters”, più chiaro di così!

I principali vantaggi sono due:

  1. Utilizzando prepared statement l’applicazione evita di ripetere il ciclo di analisi, compilazione e ottimizzazione della query e ciò si traduce in un minor utilizzo di risorse e quindi maggiore velocità.
  2. Se un’applicazione utilizza esclusivamente prepared statement, lo sviluppatore può essere certo che nessuna SQL injection si verificherà.

I prepared statements sono talmente utili ed importanti al punto da essere l’unica caratteristica che PDO emulerà anche per i drivers che non li supportano e questo garantisce all’applicazione il medesimo paradigma di acceso ai dati in maniera del tutto indipendente dal motore di database che si è scelto di utilizzare.

A questo punto basta con le chiacchiere e passiamo a vedere un pò di codice, nell’esempio precedente abbiamo visto come eseguire una query passando direttamente al metodo query() la stringa sql


<?php
include dirname(__FILE__).'/connection.php';

  $connection = new Connection();
  $db = $connection->getConnection();
  // Preparo la query passando i parametri nella query stessa es. matricola = 2
  $sql = " SELECT * FROM Employee WHERE matricola = 2 ";
  // Eseguo la query che mi restituirà come risultato un PDOStatement object
  $resultSet = $db->query($sql);
  print_r($resultSet->fetchObject());
?>

Come detto poc’anzi, questo modo di accedere al db è molto pericoloso in quanto esposto ad attacchi di tipo SQL Injection. Per prevenire ciò modificheremo il codice come segue utilizzando i appunto prepared statements


<?php
include dirname(__FILE__).'/connection.php';

  $connection = new Connection();
  $db = $connection->getConnection();
  // Preparo lo statement
  $stmt = $db->prepare('SELECT * FROM Employee WHERE matricola = ?');
  // Eseguo la query sostituendo il ? con i valori dell'array
  $stmt->execute(array(2));
?>

PDO è in grado di capire il tipo di dato da utilizzare grazie a quello associato al corrispondente valore contenuto nell’array oppure nel caso in cui l’array dovesse contenere valori associati non corrispondendi a tipi di dato previsti dalla query il risultato sarà semplicemente un insuccesso della query ma in ogni caso il nostro database non sarà esposto a pericoli derivanti da attacchi di tipo SQL injections.
I punti interrogativi possono essere sostituiti utilizzando un altro sistema per il binding dei dati basato su stringhe, molto più semplicemente in termini di righe di codice avremo la seguente situazione


<?php
include dirname(__FILE__).'/connection.php';

  $connection = new Connection();
  $db = $connection->getConnection();
  // Preparo lo statement
  $stmt = $db->prepare('SELECT * FROM Employee WHERE matricola = :matricola AND tipo = :ufficio');
  // Eseguo la query sostituendo i valori
  $stmt->execute(array(':matricola'=>2, ':ufficio'=>'amministrativo'));
?>

Anche in questo caso il meccanismo è il medesimo ma sostituiamo i ? con dei nomi che facilitano l’individuazione dei parametri associati.
Per finire è da notare il metodo messo a disposizione da PDO bindParam() che consente di specificare una variabile o un valore come parametro per una query prima della sua esecuzione


<?php
include dirname(__FILE__).'/connection.php';

  $connection = new Connection();
  $db = $connection->getConnection();
  $stmt = $db->prepare ("SELECT * FROM Employee WHERE matricola = :matricola AND tipo = :ufficio");
  $stmt -> bindParam(':matricola', $_POST['matricola'], PDO::PARAM_INT);
  $stmt -> bindParam(':ufficio', $_POST['ufficio'], PDO::PARAM_STR, 12);
  $stmt -> execute();
?>

A questo punto non vi resta che provare per prendere dimistichezza con questo strumento tanto potente e tanto utile quanto semplice nel suo utilizzo.
Alla prossima.


WP to LinkedIn Auto Publish Powered By : XYZScripts.com