Como escapar comillas, backslashes o caracteres especiales en SQL o PHP

Aprende a evitar errores al introducir textos en tu base de datos que pueden contener comillas o contrabarras con PHP o SQL.

bases de datos Programacion web

Suele ser un caso introducir caracteres especiales en SQL ¿verdad?, pero ¡no te preocupues! te he preparado este artículo especial sobre introducir caracteres raros en SQL, donde explico detalladamente cómo escapar cada posible caracter que se nos presente en el día a día.

Es muy frecuente olvidar escapar carácteres especiales cuando introducimos información en la base de datos sea cual sea la fuente. Si hablamos de programación backend con PHP, por ejemplo, esto sucede si no recordamos utilizar funciones específicas para ello antes de realizar un INSERT SQL, UPDATE SQL o SELECT SQL.

Las comillas, tanto simples como dobles, suelen ser el problema más común de los errores, seguido de cerca de la contrabarra o backslash cuando por ejemplo hablamos de introducir rutas de ficheros en la base de datos.

A continuación solucionaré los siguientes casos:

  1. Escapar carácteres especiales en consultas SQL.
    1. Escapar comillas simples.
    2. Escapar comillas dobles.
    3. Escapar contrabarras .
  2. Escapar carácteres para SQL con php.
    1. Introducir caracteres especiales con mysqli.
    2. Escapar caracteres especiales con la clase PDO.

 

 

Escapar carácteres especiales en SQL

Como he comentado anteriormente los carácteres especiales que suelen dar problemas a la hora de insertarlos son:

  • Comillas simples
  • Dobles comillas
  • Contrabarra o Backslash \

Escapar la comilla simple en SQL

El problema típico podría ser algo así:

UPDATE ciudad SET nombre = 'L'Origuilla' WHERE nombre LIKE 'Origuilla';

Esta comilla insertada entre la L y la O produciría un clamoroso error al ejecutar la consulta en MySQL o cualquier otro SGBD. Para escapar de forma manual la comilla simple, es decir, escribir un carácter justo antes símbolo de conflicto se puede realizar de 3 formas:

  1. Añadiendo una comilla simple justo antes de la comilla que escribimos, es decir, duplicar cada comilla simple. 
  2. Añadiendo una contrabarra delante de la comilla.
  3. Cambiando los delimitadores de la consulta, es decir, podemos escribir las variables de tipo texto entre comillas dobles.

Las tres soluciones posibles quedarían:

  1. UPDATE ciudad SET nombre = 'L''Origuilla' WHERE nombre LIKE 'Origuilla';
  2. UPDATE ciudad SET nombre = 'L\'Origuilla' WHERE nombre LIKE 'Origuilla';
  3. UPDATE ciudad SET nombre = "L'Origuilla" WHERE nombre LIKE 'Origuilla';

Escapar Dobles comillas en SQL

Aunque la costumbre de programar SQL es escribir los textos entre comillas, es común que si programas en otros lenguajes acabes delimitando los textos entre comillas dobles, esto redundará posiblemente en el siguiente problema:

UPDATE comentario SET texto = "No me refiero a tus "codigos" " WHERE id = 33;

Esta comilla doble insertada entre los delimitadores del mismo símbolo producirían un error. Para evitar este problema podemos escapar de forma manual las comillas dobles una vez más de 3 formas:

  1. Añadiendo una comilla doble justo antes de la comilla que escribimos, es decir, duplicar cada comilla doble. 
  2. Añadiendo una contrabarra delante de las comillas dobles.
  3. Cambiando los delimitadores de la consulta, es decir, podemos escribir las variables de tipo texto entre comillas simples.

Las tres soluciones posibles quedarían:

  • UPDATE comentario SET texto = "No me refiero a tus ""codigos"" " WHERE id = 33;
  • UPDATE comentario SET texto = "No me refiero a tus \"codigos\" " WHERE id = 33;
  • UPDATE comentario SET texto = 'No me refiero a tus "codigos" ' WHERE id = 33;

Escapar Contrabarra en SQL

Para escapar la contrabarra o backslash tan solo existe una forma: Duplicar la contrabarra. Así una consulta como la siguiente:
UPDATE usuario SET carpeta_personal = '\home\user' WHERE id = 33;

Se tendría que cambiar con doble backslash para ser correcta:

UPDATE usuario SET carpeta_personal = '\\home\\user' WHERE id = 33;

Escapar carácteres para SQL con php

Si programas en php dispones de varias estratégias para solucionar el problema. Siempre deberemos haber realizado la conexión antes de utilizar cualquiera de las siguientes opciones:

Vamos a verlos uno a uno con ejemplos de uso.

Corregir carácteres especiales por procedimientos mysqli

Para la conexión a MySQL mediante procedimientos disponemos de la función mysqli_real_escape_string(). A esta función le pasamos una cadena, y nos devuelve una cadena resultado con los caracteres escapados dependiendo del rango de caracteres que acepta la conexión. Si creaste tu base de datos con, por ejemplo, configuración de caracteres inglesa nos escapará símbolos como la ñ, además de comillas simples y dobles o backslash (entre otros).

Hay que recordar que esta función depende completamente de una conexión a base de datos mediante procedimientos mysqli:

<?php
$conexion = mysqli_connect('localhost', 'root', 'root');
mysqli_select_db('test', $conexion); //selecciona la base de datos
$ciudad = "L'Origuilla";
$ciudad_escapada = mysqli_real_escape_string($conexion, $ciudad);
$query = "UPDATE ciudad SET nombre = '$ciudad_escapada' WHERE nombre LIKE 'Origuilla';
$resultado = mysqli_query($conexion, $query);
if($resultado == false){
    echo 'ERROR! CODIGO: ' . mysqli_errno($conexion) . ' mensaje:'  . mysqli_error($conexion);
}else{
    echo 'Ciudad actualizada!';
}
?>

mysqli_real_escape_string() escapa los caracteres especiales de una cadena para usarla en una sentencia SQL, tomando en cuenta el conjunto de caracteres actual de la conexión.

Escapar caracteres especiales con la clase mysqli

Si realizas tus conexiones a base de datos con la clase mysqli, podrás escapar los caracteres problemáticos mediante el método real_escape_string(). Este método requiere una conexión activa a MySQL para poder realizar su trabajo, en caso contrario, te devolverá una cadena vacía.

 

<?php
$objeto_mysqli = new mysqli('localhost', 'root', 'root', 'test');
$ciudad = "L'Origuilla";
$ciudad_escapada = $mysqli->real_escape_string($ciudad);
$query = "UPDATE ciudad SET nombre = '$ciudad_escapada' WHERE nombre LIKE 'Origuilla';
$resultado = $objeto_mysqli->query($query);
if($resultado != false){
   echo 'La ciudad se ha actualizado correctamente';
}
?>

El método real_escape_string() de la clase mysqli escapa los caracteres especiales de una cadena de texto tomando en cuenta el conjunto de caracteres establecido en la base de datos de la conexión con MySQL.

Introducir caracteres especiales con la clase PDO

La clase PDO permite, sin un uso extra de métodos, escapar los caracteres especiales de nuestras consultas. Con solo el hecho de preparar nuestras consultas antes de ejecutarlas, la clase PDO escapará las comillas, contrabarras, etc. Veamos a que me refiero con un ejemplo:

try{
     $objetoPDO = new PDO('mysql:host=localhost;dbname=Test, 'root', 'root');
}catch (PDOException $e) {
      echo "¡Error!: " . $e->getMessage();
      die();
}
$query = "SELECT * FROM usuario WHERE nickname LIKE :nombre;";
$pdoStat = $objetoPDO->prepare($query);
$pdoStat->bindValue(':nombre', "l'asdas'", PDO::PARAM_STR);

Cada vez que sustituyo una variable de PDO por un valor, el método bindValue() escapa los caracteres conflictivos e inserta la cadena resultante en su lugar correspondiente en la consulta, contruyendo así una consulta correcta y que comprende el conjunto de caracteres de la base de datos a la que se está conectado con PDO.  

Introducir caracteres especiales con PDO forma 2

Hay una segunda forma de introducir caracteres especiales mediante conexiones PDO, usando el método quote(). Este método, normalmente innecesario si realizamos nuestras consultas mediante el uso de bindValue o bindParam tras un prepare() de la consulta, nos permite escapar los caracteres conflictivos (comillas simples, dobles, backslash, etc) y obtener las cadenas de texto "traducidas". Como siempre en Sr codigo fuente, veamoslo con un ejemplo de código:

Imaginemos que voy a buscar usuarios por el nombre introducido en un formulario de method="GET":

 

<?php
$objetoPDO = new PDO('mysql:host=localhost;dbname=Test, 'root', 'root');
$nombre = $objetoPDO->quote($_GET['nombre']);
$query = "SELECT * FROM usuario WHERE nickname LIKE $nombre";
$pdoStat = $objetoPDO->prepare($query);
$result = $pdoStat->execute();
?>

En este ejemplo, de diferente forma al anterior en el que utilizaba prepare() y bindValue(), pero con el mismo resultado, he escapado los caracteres especiales que pueda contener el nombre introducido en el formulario, y he montado la consulta, obteniendo una ejecución sin problemas de la consulta y además evitando SQL Injection.

Sobre el autor

Javier Gómez Redactor en Srcodigofuente.es

Javier Gómez

Ingeniero técnico en informática de gestión. Desarrollador web freelance y profesor de desarrollo web a partes iguales. Testarudo autodidacta, creativo, perfeccionista y alma libre.

Cargando comentarios

Utilizamos "cookies" para información estadística. Si continúas navegando aceptas su uso.