Gli ultimi tutorial di sviluppo web
 

PHP Prepared Statements


istruzioni preparate sono molto utili contro iniezioni SQL.


Istruzioni preparate e parametri Bound

Un'istruzione preparata è una funzione utilizzata per eseguire gli stessi (or similar) istruzioni SQL ripetutamente con alta efficienza.

istruzioni preparate in pratica funzionano in questo modo:

  1. Preparare: un modello di istruzione SQL viene creato e inviato al database. Alcuni valori sono lasciati non specificato, chiamato parametri (labeled "?") . Esempio: INSERT INTO MyGuests VALUES(?, ?, ?)
  2. Il database analizza, compila ed esegue l'ottimizzazione delle query sul modello istruzione SQL, e memorizza il risultato senza eseguirlo
  3. Esecuzione: In un secondo momento, l'applicazione si lega i valori ai parametri, e il database esegue l'istruzione. L'applicazione può eseguire l'istruzione tutte le volte che si vuole con valori diversi

Rispetto ad eseguire direttamente istruzioni SQL, istruzioni preparate presentano due vantaggi principali:

  • Prepared statement riduce il tempo di analisi come la preparazione sulla query viene fatto solo una volta (although the statement is executed multiple times)
  • parametri legati minimizzare la larghezza di banda al server come è necessario inviare solo i parametri di volta in volta, e non l'intera query
  • istruzioni preparate sono molto utili contro le iniezioni SQL, perché i valori dei parametri, che vengono trasmessi in seguito utilizzando un protocollo diverso, non devono essere sfuggiti correttamente. Se il modello dichiarazione originale non deriva da ingresso esterno, SQL injection non può verificarsi.

Le dichiarazioni preparate in MySQLi

L'esempio seguente utilizza le istruzioni preparate e parametri associati a MySQLi:

Esempio (MySQLi with Prepared Statements)

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();

$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();

$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();

echo "New records created successfully";

$stmt->close();
$conn->close();
?>

linee di codice per spiegare dall'esempio precedente:

"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"

Nel nostro SQL, inseriamo un punto interrogativo (?) In cui vogliamo sostituire in un numero intero, stringa, un valore doppio o blob.

Poi, hanno uno sguardo al bind_param() la funzione:

$stmt->bind_param("sss", $firstname, $lastname, $email);

Questa funzione si lega i parametri per la query SQL e racconta il database quali sono i parametri. Il "sss" argomento sono elencati i tipi di dati che i parametri siano. Il carattere s dice mysql che il parametro è una stringa.

L'argomento può essere uno dei quattro tipi:

  • i - integer
  • d - doppia
  • s - string
  • b - BLOB

Dobbiamo avere uno di questi per ogni parametro.

Raccontando mysql che tipo di dati da aspettarsi, riduciamo al minimo il rischio di iniezioni SQL.

Nota: Se vogliamo inserire tutti i dati provenienti da fonti esterne (like user input) , è molto importante che i dati vengono sterilizzate e convalidato.


Istruzioni preparate a DOP

L'esempio seguente utilizza le istruzioni preparate e parametri associati a DOP:

Esempio (PDO with Prepared Statements)

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // prepare sql and bind parameters
    $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
    VALUES (:firstname, :lastname, :email)");
    $stmt->bindParam(':firstname', $firstname);
    $stmt->bindParam(':lastname', $lastname);
    $stmt->bindParam(':email', $email);

    // insert a row
    $firstname = "John";
    $lastname = "Doe";
    $email = "[email protected]";
    $stmt->execute();

    // insert another row
    $firstname = "Mary";
    $lastname = "Moe";
    $email = "[email protected]";
    $stmt->execute();

    // insert another row
    $firstname = "Julie";
    $lastname = "Dooley";
    $email = "[email protected]";
    $stmt->execute();

    echo "New records created successfully";
    }
catch(PDOException $e)
    {
    echo "Error: " . $e->getMessage();
    }
$conn = null;
?>