Skip to content

4 sentencias preparadas en php

@intelguasoft edited this page Jan 22, 2020 · 1 revision

Curso Master PHP

Preparando sentencias SQL

Una Sentencia Preparada, o Prepared Statement, es una característica de algunos sistemas de bases de datos que permite ejecutar la misma (o similar) sentencia SQL provocando una mejora en la seguridad y en el rendimiento de la aplicación.

Indice de contenido

  1. Cómo funcionan las Sentencias Preparadas
  2. Ventajas de las Sentencias Preparadas
  3. Sentencias Preparadas en MySQLi
  4. Sentencias Preparadas en PDO

1. Cómo funcionan las sentencias preparadas

  • Prepare. Primero una plantilla de la sentencia SQL se crea y se envía a la base de datos. Algunos valores se dejan sin especificar, llamados parámetros y representados por un interrogante "?":
INSERT INTO Clientes VALUES (?, ?, ?, ?);
  • Después, la base de datos analiza, compila y realiza la optimización de la consulta sobre la sentencia SQL, y guarda el resultado sin ejecutarlo.
  • Execute. Por último, la aplicación enlaza valores con los parámetros, y la base de datos ejecuta la sentencia. La aplicación puede entonces ejecutar la sentencia tantas veces como quiera con valores diferentes.

2. Ventajas de las Sentencias Preparadas

  • Las Sentencias Preparadas reducen en tiempo de análisis ya que la preparación de la consulta de realiza sólo una vez (aunque la sentencia se ejecute las veces necesarias).
  • Los parámetros enlazados minimizan el ancho de banda consumida del servidor ya que sólo necesitas enviar los parámetros cada vez, no la consulta entera.
  • Las Sentencias Preparadas son muy últiles frente a Inyecciones SQL, ya que los valores de los parámetros, que son transmitidos después usando un protocolo diferente, no necesitan ser escapados. Si la plantilla de la sentencia original no es derivada de un input externo, los ataques SQL Injection no pueden ocurrir.

3. Sentencias Preparadas en MySQLi

Vamos a ver un ejemplo de Sentencias Preparadas en PHP con MySQLi.

$server = "localhost";
$user = "usuario";
$password = "password";
$dbname = "ejemplo";
// Conectar
$db = new mysqli($server, $user, $password, $dbname);
// Comprobar conexión
if($db->connect_error){
    die("La conexión ha fallado, error número " . $db->connect_errno . ": " . $db->connect_error);
}

Ya tenemos la conexión a la base de datos, ahora podemos utilizarla en los archivos donde tengamos que hacer sentencias.

// Preparar
$stmt = $db->prepare("INSERT INTO Clientes (nombre, ciudad, contacto) VALUES (?, ?, ?)");
$stmt->bind_param('ssi', $nombre, $ciudad, $contacto);
// Establecer parámetros y ejecutar
$nombre = "Donald Trump";
$ciudad = "Madrid";
$contacto = 4124124;
$stmt->execute();
$nombre = "Hillary Clinton";
$ciudad = "Barcelona";
$contacto = 4665767;
$stmt->execute();
// Mensaje de éxito en la inserción
echo "Se han creado las entradas exitosamente";
// Cerrar conexiones
$stmt->close();
$db->close();

Incluimos un interrogante donde queremos sustituir un integer, un string, un double o un blob en la función prepare(). Después usamos la función bind_param():

$stmt->bind_param('ssi', $nombre, $ciudad, $contacto);

La función enlaza los parámentros con la consulta SQL y le dice a la base de datos que parámetros son. El argumento "ssi" especifica el tipo de dato que se espera que sea el parámetro. Pueden ser de cuatro tipos:

Letra Tipo de dato
i Integer
d double
s string
b blob

Se debe especificar uno por cada parámetro.

La función mysqli_stmt::bind_result() permite enlazar las columnas con variables para su uso posterior. No hace falta especificar el tipo de dato.

// Iniciamos sentencia preparada
if ($stmt = $mysqli->prepare("SELECT nombre, ciudad FROM Clientes")) {
    $stmt->execute();
    // Vinculamos variables a columnas
    $stmt->bind_result($nombre, $ciudad);
    // Obtenemos los valores
    while ($stmt->fetch()) {
        printf("%s %s\n", $nombre, $ciudad);
    }
    // Cerramos la sentencia preparada
    $stmt->close();
}

4. Sentencias Preparadas en PDO

Vamos a hacer el mismo ejemplo anterior pero con PDO.

$server = "localhost";
$user = "usuario";
$password = "password";
$dbname = "ejemplo";
try {
// Conectar
$db = new PDO("mysql:host=$server;dbname=$dbname", $user, $password);
// Establecer el nivel de errores a EXCEPTION
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
    echo "Error: " . $e->getMessage();
}

Una vez establecida la conexión, podemos usarla donde la necesitemos:

// Preparar
$stmt = $db->prepare("INSERT INTO Clientes (nombre, ciudad, contacto) VALUES (:nombre, :ciudad, :contacto)");
$stmt->bindParam(':nombre', $nombre);
$stmt->bindParam(':ciudad', $ciudad);
$stmt->bindParam(':contacto', $contacto);
// Establecer parámetros y ejecutar
$nombre = "Donald Trump";
$ciudad = "Madrid";
$contacto = 4124124;
$stmt->execute();
$nombre = "Hillary Clinton";
$ciudad = "Barcelona";
$contacto = 4665767;
$stmt->execute();
// Mensaje de éxito en la inserción
echo "Se han creado las entradas exitosamente";
// Cerrar conexiones
$db = null;

Los parámetros también pueden enlazarse sin utilizar bindParam(), directamente con un array en execute():

// Preparar
$stmt = $db->prepare("INSERT INTO Clientes (nombre, ciudad, contacto) VALUES (:nombre, :ciudad, :contacto)");
// Establecer parámetros y ejecutar
$nombre = "Donald Trump";
$ciudad = "Madrid";
$contacto = 4124124;
$stmt->execute(array(':nombre' => $nombre, ':ciudad' => $ciudad, ':contacto' => $contacto));
// Mensaje de éxito en la inserción
echo "Se han creado las entradas exitosamente";
// Cerrar conexiones
$db = null;

Hemos asignado los parámetros con nombre de variable, pero también se puede hacer con números:

$stmt = $db->prepare("INSERT INTO Clientes (nombre, ciudad, contacto) VALUES (?, ?, ?)");
$stmt->bindParam(1, $nombre);
$stmt->bindParam(2, $ciudad);
$stmt->bindParam(3, $contacto);

En caso de pasar los parámetros a través de un array con execute(), se haría de la misma forma que antes:

// Preparar
$stmt = $db->prepare("INSERT INTO Clientes (nombre, ciudad, contacto) VALUES (?, ?, ?)");
// Establecer parámetros y ejecutar
$nombre = "Donald Trump";
$ciudad = "Madrid";
$contacto = 4124124;
$stmt->execute(array($nombre, $ciudad, $contacto));
// Mensaje de éxito en la inserción
echo "Se han creado las entradas exitosamente";
// Cerrar conexiones
$db = null;

Sólo hemos empleado las sentencias preparadas para insertar datos, pero también se emplean para consultas y con otros métodos de enlazado como bindValue() o bindColumn().

Anterior Siguiente

Indice de contenidos

Básicos Sintaxis básica
Operadores
Operadores bit a bit
Variables
Estructuras de control
Constantes y constructores base
Espacio de nombres
Extensiones
Configuraciones
Variables al descubierto
Recolector de basuras
Rendimiento (Performance)
Funciones Funciones
Argumentos en funciones
Funciones variables
Valores por referencia en funciones
Funciones que devuelven algo
Ámbito de variables
Funciones anónimas y closure's
Cadenas y patrones Las comillas y las cadenas de caracteres
Heredoc y Nowdoc
Comparando cadenas de caracteres
Extracción en cadenas de caracteres
Análisis en cadenas de caracteres
Reemplazos en cadenas de caracteres
Formato de cadena de caracteres
Expresiones regulares (RegEx)
Codificación de caracteres
Codificación en cadenas de caracteres
Arreglos (Array's) Arreglos
Arreglos asociativos
Iterar arreglos
Funciones de arreglos
SPL Arreglos mediante objetos
Conversión de arreglos
Archivos (I/O) Manejo de archivos
Lectura de archivos
Escritura de archivos
Funciones del sistema de archivos
Socket's y archivos
Streams (?)
Seguridad Concepto y funcionamiento CGI
Configurando la seguridad
Seguridad en Sesiones
Ataques XSS
Ataques CSRF
Ataques SQLInjection
Ataques CodeInjection
Ataques EmailInjection
Filtrado de datos de entrada
Escape de datos de salida
Encriptación y contraseñas
Seguridad en el almacenamiento de datos
Seguridad en la subida de datos
SSL y OpenSSL
Base de datos Principios básicos SQL
Los joins en SQL
Principales funciones SQL
Preparando sentencias SQL
Transacciones en SQL
Algo de PDO
Programación Orientada a Objetos Instancias de clases
Modificadores y herencia de clases
Interfaces
Excepciones
Auto-carga (Autoload)
Reflexión (Reflection)
Determinación de tipos (Type hinting)
Constantes de clase
Enlace estático de ejecución (Late Static Binding)
Métodos mágicos
Librería estándar PHP (SPL)
Generadores (Generators)
Traits
Clases abstractas
Formatos de información Algo de XML
Algo de SimpleXML
Algo de XML Parser
Algo de PHP DOM
Algo de Web Services
Web Services con SOAP
Algo de REST
Algo de JSON
Formato de fecha y hora
Características web's Sesiones
Formularios
Métodos GET y POST
Cookies
Protocolo HTTP y sus headers
Autenticación HTTP
Códigos de estado HTTP
Referencias Referencias
Recopilación
Conclusión

Clone this wiki locally