Los últimos tutoriales de desarrollo web
 

PHP Sentencias preparadas


declaraciones preparadas son muy útiles contra las inyecciones SQL.


Instrucciones preparadas y parámetros Bound

Una declaración preparada es una función que se utiliza para ejecutar las mismas (or similar) sentencias SQL repetidamente con una alta eficiencia.

declaraciones preparadas básicamente funcionan de la siguiente:

  1. Prepare: Una plantilla de instrucción SQL se crea y se envía a la base de datos. Ciertos valores se dejan sin especificar, denominado parámetros (labeled "?") . Ejemplo: INSERT INTO MyGuests VALUES(?, ?, ?)
  2. La base de datos analiza, compila, y lleva a cabo la optimización de consultas en la plantilla instrucción SQL, y almacena el resultado sin ejecutarlo
  3. Ejecutar: En un momento posterior, la aplicación se une a los valores de los parámetros, y la base de datos ejecuta la sentencia. La aplicación puede ejecutar la instrucción tantas veces como se quiera con diferentes valores

En comparación con la ejecución de las sentencias SQL directamente, declaraciones preparadas tienen dos ventajas principales:

  • Declaraciones preparadas reduce el tiempo de análisis como la preparación de la consulta se realiza sólo una vez (although the statement is executed multiple times)
  • parámetros ligados minimizar el ancho de banda al servidor que necesite enviar sólo los parámetros cada vez, y no toda la consulta
  • declaraciones preparadas son muy útiles contra las inyecciones SQL, ya que los valores de los parámetros que se transmiten posteriormente utilizando un protocolo diferente, no tienen por qué ser escapados correctamente. Si la plantilla declaración original no se deriva de la entrada externa, no puede producirse la inyección de SQL.

Instrucciones preparadas en MySQLi

El ejemplo siguiente utiliza declaraciones preparadas y los parámetros de la envolvente en MySQLi:

Ejemplo (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();
?>

líneas de código para explicar el ejemplo anterior:

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

En nuestro SQL, insertamos un signo de interrogación (?) Donde queremos sustituir en un entero, cadena, valor doble o burbuja.

A continuación, echar un vistazo a la bind_param() función:

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

Esta función se une a los parámetros de la consulta SQL y le dice a la base de datos cuáles son los parámetros. El "sss" argumento enumera los tipos de datos que los parámetros son. El carácter s MySQL dice que el parámetro es una cadena.

El argumento puede ser una de cuatro tipos:

  • i - número entero
  • d - doble
  • s - string
  • b - BLOB

Debemos tener uno de estos para cada parámetro.

Al decirle a MySQL qué tipo de datos que pueden esperar, se minimiza el riesgo de inyecciones SQL.

Nota: Si queremos insertar datos de fuentes externas (like user input) , es muy importante que los datos es verificada y validada.


Instrucciones preparadas en PDO

El ejemplo siguiente utiliza declaraciones preparadas y los parámetros de la envolvente en PDO:

Ejemplo (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;
?>