Diferencias entre las revisiones 2 y 7 (abarca 5 versiones)
Versión 2 con fecha 2016-09-13 17:26:18
Tamaño: 10182
Editor: FabioDuran
Comentario: Versión 1
Versión 7 con fecha 2016-09-13 19:07:08
Tamaño: 12929
Editor: FabioDuran
Comentario:
Los textos eliminados se marcan así. Los textos añadidos se marcan así.
Línea 2: Línea 2:
Línea 32: Línea 31:
?> 
}}}

Los problemas de esto:

La entrada de texto por parte del usuario es manipulada sin ningún tipo de parser, logrando que esto sea altamente vulnerable para un ataque por inyección de SQL o simplemente por error de tipeo el usuario logre datos no deseados. Lo que se debe realizar es siempre implementar una rutina que filtre lo que el usuario está escribiendo en los campos de entradas para completar el SQL, o bien usar de "prepared" para las sentencias escritas.

La función de mysql_query() o myqli_query() es usada de forma directa en el código. Esta muy bien que esto sea tratado para un tutorial, pero tengase en cuenta que es solo una referencia o demostración de como funciona o de como se podría realizar. Tratesé de pensar siempre en adquirir mejores hábitos para el desarrollo.

La conexión a la base de datos es creada de forma manual y lo que es peor con las credenciales en el mismo archivo en que ejecutarás la sentencia. Debería crearse algo que podamos manejar, primero de un modo centralizado, como por ejemplo en un fichero separado con tags identificables que permitan importar el fichero a nuestro script. Segundo ofusca un poco el modo, por ejemplo, si utilizas los ficheros en el /ROOT/ del sitio (visible por nosotros), intenta por lo menos dificultar el modo de exponer este tipo de credenciales. Nuevamente esto es solo a modo de tutorial.


¿Qué se puede hacer?

Primero que todo, el controlador que utilizo para MySQL es mysqli, y en PHP existen dos formas de como manipularlo, la primera es a través de un método procedimental (funciones) o la orientación a objetos. En cuanto a la sintaxis es prácticamente igual, pero cambia en la forma de como se hace la referencia hacia las funciones (modo independiente o en un objeto de mysqli).

Hace mucho tiempo yo utilizo unos script de Eran Galperin, que son licenciado MIT License. Pueden descargarse desde https://github.com/erangalp/database-tutorial

La forma de conexión:
?>
}}}

=== Los problemas  ===

La entrada de texto por parte del usuario es manipulada sin ningún tipo de parser, logrando que esto sea altamente vulnerable para un ataque por inyección de SQL o simplemente por error de tipeo el usuario logre datos no deseados. Entonces como regla es realizar siempre la implementación de una rutina que filtre lo que el usuario está escribiendo en los campos de entradas para completar el SQL, o bien usar de "prepared" o "escape" para las sentencias escritas.

Para el ejemplo anterior, la función de '''mysql_query()''' o '''myqli_query()''' es usada de forma directa en el código, y esta muy bien, pero esto es tratado para un tutorial, o sea es solo una referencia o demostración de como funciona o de como se podría implementar y no para usar tal cual.

En el caso lo que sucede es que la conexión a la base de datos es creada de forma manual y otro error que es común ver, las credenciales están en el mismo archivo en que ejecutarás la sentencia. Las buenas prácticas dicen que se debería crear algo que podamos manejar, primero de un modo centralizado como por ejemplo en un archivo separado con tags identificables que permitan importar el fichero a nuestro script php, y lo Segundo es ofuscar un poco el modo o el lugar, por ejemplo si utilizas los ficheros en el /ROOT/ del sitio (visible por nosotros), intenta por lo menos dificultar la exposición este tipo de credenciales. Nuevamente, el ejemplo encontrado esto es solo a modo de tutorial.

=== ¿Qué se puede hacer? ===

Primero que todo, el controlador que se puede utilizar para el manejo de MySQL es '''mysqli'''. En PHP existen dos formas de como manipularlo, la primera es a través de un método procedimental (funciones) y la segunda es la orientación a objetos. En cuanto a la sintaxis es prácticamente igual, pero cambia en la forma de como se referencia hacia las funciones (modo independiente o en un objeto de mysqli), por lo que ambas son válidas.

==== La forma de conexión: ====
Línea 62: Línea 59:
 
La explicación para este fragmento sería; para mysqli_connect se requieren 4 parámetros esenciales como mínimo para crear la conexion (el host, usuario, contraseñas y nombre de base de datos). Existen otros parámetros que dependerán de la implementación del servidor, pero para ello se puede ver el siguiente link http://www.php.net/manual/en/mysqli.construct.php

Lo siguiente es validar la conexión, está demás decir que existen varios tipos de fallos de conectividad, por lo que se puede realizar un log file, error page, etc. quedando a la creatividad del desarrollador. El mensaje por pantalla es una opción buena y válida, pero cuidado con lo que muestras, puede dar pistas a un atacante y crear una vulnerabilidad.

Para el fragmento de código entregado requiere pasar los parámetros de conexión. Como ya he mencionado anteriormente, no es una buena práctica mantener a los de acceso a la conexión de base de datos, especialmente si los archivos PHP están dentro del /ROOT del website. El por qué se resumen principalmente que ante cualquier fallo o instancia de anormalidad del servidor web pudiese mostrarlo como texto en pantalla revelando información sensible para nosotros.

A mí me gusta mantener los parámetros de la base de datos separado de los archivos php, esto me permite hacer referencia en cualquier momento para hacer cambios generales en mis aplicaciones PHP.

Creo un documento de texto que contenga lo siguiente:

La explicación para este fragmento sería; para '''mysqli_connect''' se requieren 4 parámetros esenciales como mínimo para crear la conexión (host, usuario, contraseñas, nombre de base de datos). Existen otros parámetros que dependerán de la implementación del servidor, pero para ello se puede ver el siguiente link: http://www.php.net/manual/en/mysqli.construct.php

Las siguientes lineas es validar la conexión, está demás decir que existen varios tipos de fallos de conectividad, siendo factible realizar un log file, error page, etc. quedando a la creatividad del desarrollador. El mensaje por pantalla es una opción buena y válida, pero cuidado con lo que muestras, puede dar pistas a un atacante y crear una vulnerabilidad.

Para el fragmento de código entregado requiere pasar los parámetros de conexión. Como ya se menciono anteriormente, no es una buena práctica mantener a los de acceso a la conexión de base de datos, especialmente si los archivos PHP están dentro del /ROOT/ del website. Es una buena opción mantener los parámetros de la base de datos separado de los archivos php, esto me permite hacer referencia en cualquier momento para hacer cambios generales en las aplicaciones.

Se crea un documento de texto que contenga lo siguiente:
Línea 79: Línea 75:
Línea 82: Línea 77:
Si se escoge, así como se proponen los scripts (https://github.com/erangalp/database-tutorial) una extensión .ini, la carga sería: La necesidad de mantener las credenciales separadas de los archivos php se resumen principalmente que ante cualquier fallo o instancia de anormalidad del servidor web, este pudiese revelar como texto en pantalla revelando las credenciales.
Línea 87: Línea 83:
$config = parse_ini_file('/ROOT/../config.ini');  $config = parse_ini_file('/ROOT/../config.ini');
Línea 99: Línea 95:
Todo lo anterior podemos ponerlo dentro de una clase (para trabajar en orientación a objetos) y dentro de esa clase declarar una función para establecer la conexión Todo lo anterior podemos ponerlo dentro de una clase (para trabajar en orientación a objetos) y dentro de esa clase también declarar una función para establecer la conexión
Línea 109: Línea 105:
     *       *
Línea 112: Línea 108:
    public function connect() {         public function connect() {
Línea 116: Línea 112:
            $config = parse_ini_file('/ROOT/../config.ini');              $config = parse_ini_file('/ROOT/../config.ini');
Línea 130: Línea 126:
Consultando a la base de datos MySQL:

Ahora que se tiene la conexión, podemos comenzar a utilizar el motor de base de datos. 
=== Consultando a la base de datos MySQL ===

Ahora que se tiene la conexión, podemos comenzar a utilizar el motor de base de datos.
Línea 135: Línea 131:
Línea 142: Línea 139:
?>  
}}}
Esto ahora se inserta en una función pública dejando de este modo:

{{{#!highlight php
<?php
    public function query($query) {
     // Connect to the database
     $connection = $this -> connect();

        // Query the database
        $result = $connection -> query($query);

        return $result;
?>
}}}

Se Puede modificar esto y declarar
una función pública como el siguiente ejemplo:

{{{#!highlight php
<?php
public function query($query) {
    // Connect to the database
    $connection = $this -> connect();

    // Query the database
    $result = $connection -> query($query);

    return $result;
Línea 157: Línea 155:

?>
}}}

El parámetro que recibe esta función es $query, que sería una sentencia SQL que se desea. Existe un pero, en el caso de que sea una sentencia SELECT que requiere la devolución de resultados, quizás sea mejor separar en funciones los query y generar una solo para esta.

{{{#!highlight php
<?php
    function db_select($query) {
     $rows = array();
        $result = db_query($query);

        // If query failed, return `false`
     if($result === false) {
            return false;
        }

        // If query was successful, retrieve all the rows into an array
        while ($row = mysqli_fetch_assoc($result)) {
            $rows[] = $row;
        }
        return $rows;
?>
}}}

El parámetro que recibe esta función es $query, que requiere ser una sentencia SQL. Existe un pero, en el caso de que sea una sentencia SELECT que requiere la devolución de resultados, quizás sea mejor separar en funciones los query y generar una solo para esta.

{{{#!highlight php
<?php
function db_select($query) {
    $rows = array();
    $result = db_query($query);

    // If query failed, return `false`
    if($result === false) {
        return false;
Línea 181: Línea 171:
?>
}}}

Cuando se utiliza mysqli_fetch_assoc, recibiremos columnas del objeto mysqli_result, que serán del tipo array, que a su vez estarán indexados con las columnas de la base de datos.
    // If query was successful, retrieve all the rows into an array
    while ($row = mysqli_fetch_assoc($result)) {
        $rows[] = $row;
    }
    return $rows;
}
?>
}}}

Cuando se utiliza '''mysqli_fetch_assoc''', recibiremos columnas del objeto '''mysqli_result''' que serán del tipo array, que a su vez estarán indexados con las columnas de la base de datos.

=== Datos de entrada ===
Línea 188: Línea 185:
Para esto mysqli tiene una función que nos ayuda mucho, mysqli_real_scape_string(). Esta función requiere de la conexión a la base de datos y los valores que queremos "limpiar". Para esto mysqli tiene una función que nos ayuda mucho, '''mysqli_real_scape_string()'''. Esta función requiere de la conexión a la base de datos y los valores que queremos "limpiar".
Línea 195: Línea 192:
        $connection = db_connect();
        return "'" . mysqli_real_escape_string($connection,$value) . "'";
}
?>
    $connection = db_connect();
    return "'" . mysqli_real_escape_string($connection,$value) . "'";
}
?>
}}}


=== Los script resultantes ===
'''db.php'''
{{{#!highlight php
<?php

/**
 * Database wrapper for a MySQL with PHP tutorial
 *
 * @copyright Eran Galperin
 * @license MIT License
 * @see http://www.binpress.com/tutorial/using-php-with-mysql-the-right-way/17
 */
class Db {
 // The database connection
 protected static $connection;
 
 /**
  * Connect to the database
  *
  * @return bool false on failure / mysqli MySQLi object instance on success
  */
 public function connect() {
  
  // Try and connect to the database
  if(!isset(self::$connection)) {
   // Load configuration as an array. Use the actual location of your configuration file
   // Put the configuration file outside of the document root
   $config = parse_ini_file('./config.ini');
   self::$connection = new mysqli('localhost',$config['username'],$config['password'],$config['dbname']);
  }
 
  // If connection was not successful, handle the error
  if(self::$connection === false) {
   // Handle error - notify administrator, log to a file, show an error screen, etc.
   return false;
  }
  return self::$connection;
 }
 
 /**
  * Query the database
  *
  * @param $query The query string
  * @return mixed The result of the mysqli::query() function
  */
 public function query($query) {
  // Connect to the database
  $connection = $this -> connect();
  
  // Query the database
  $result = $connection -> query($query);
  
  return $result;
 }
 
 /**
  * Fetch rows from the database (SELECT query)
  *
  * @param $query The query string
  * @return bool False on failure / array Database rows on success
  */
 public function select($query) {
  $rows = array();
  $result = $this -> query($query);
  if($result === false) {
   return false;
  }
  while ($row = $result -> fetch_assoc()) {
   $rows[] = $row;
  }
  return $rows;
 }
 
 /**
  * Fetch the last error from the database
  *
  * @return string Database error message
  */
 public function error() {
  $connection = $this -> connect();
  return $connection -> error;
 }
 
 /**
  * Quote and escape value for use in a database query
  *
  * @param string $value The value to be quoted and escaped
  * @return string The quoted and escaped string
  */
 public function quote($value) {
  $connection = $this -> connect();
  return "'" . $connection -> real_escape_string($value) . "'";
 }
}
Línea 206: Línea 300:
$name = db_quote($_POST['username']);
$email = db_quote($_POST['email']);

include('./db.php');
$db = new Db();

$name = $db -> db_quote($_POST['username']);
$email = $db -> db_quote($_POST['email']);
Línea 210: Línea 308:
$result = db_query("INSERT INTO `users` (`name`,`email`) VALUES (" . $name . "," . $email . ")");
?>
}}}
$result = db -> db_query("INSERT INTO `users` (`name`,`email`) VALUES (" . $name . "," . $email . ")");

$rows = $db -> db_select("SELECT * FROM `users`");

foreach($rows as $row) {
    echo "name: ". row['name'];
    echo "email: ". row['email'];
}

?>
}}}

Todo este documento se baso en unos script de Eran Galperin, licenciados con la MIT License. Pueden descargarse desde https://github.com/erangalp/database-tutorial

Buscando métodos para solventar el SQL-Inyection usando PHP y MySQL

Demás esta decir que PHP y MySQL son unos de las herramientas más utilizadas en el desarrollo web, para nosotros en la escuela de ICB (http://icb.utalca.cl), puede ser un problema que estamos intentando resolver, y acá detallo una primera aproximación para dar solución a este ya común problema de seguridad.

Uno de las cosas comunes que nos encontramos en la web es simplemente la forma en como funcionan las cosas, por más que vengan de sitios confiables como php.net, W3Schools o stackoverflow, debemos primero saber si funciona para el modo de aprendizaje y lo segundo (cosa que nunca hacemos) es fijarnos en lo horrible que puede estar el código. La palabra horrible no solo la describo por lo feo que puede estar el código expresado linea a linea, sino que tambien ahora también por lo comprometido en cuanto a seguridad puede estar.

El típico ejemplo que encontramos en W3Schools para la pregunta ¿Cómo usar PHP y MySQL? (How to PHP+MySQL) es el siguiente:

   1  <?php
   2 $servername = "localhost";
   3 $username = "username";
   4 $password = "password";
   5 $id = $POST["code"]
   6 
   7 // Create connection
   8 $conn = new mysqli($servername, $username, $password);
   9 // Check connection
  10 if ($conn->connect_error) {
  11     die("Connection failed: " . $conn->connect_error);
  12 }
  13 
  14 // Create database
  15 $sql = "SELECT * FROM table WHERE id='$id'";
  16 if ($conn->query($sql) === TRUE) {
  17     echo "Query successfully";
  18 } else {
  19     echo "Error creating database: " . $conn->error;
  20 }
  21 
  22 $conn->close();
  23 ?>

Los problemas

La entrada de texto por parte del usuario es manipulada sin ningún tipo de parser, logrando que esto sea altamente vulnerable para un ataque por inyección de SQL o simplemente por error de tipeo el usuario logre datos no deseados. Entonces como regla es realizar siempre la implementación de una rutina que filtre lo que el usuario está escribiendo en los campos de entradas para completar el SQL, o bien usar de "prepared" o "escape" para las sentencias escritas.

Para el ejemplo anterior, la función de mysql_query() o myqli_query() es usada de forma directa en el código, y esta muy bien, pero esto es tratado para un tutorial, o sea es solo una referencia o demostración de como funciona o de como se podría implementar y no para usar tal cual.

En el caso lo que sucede es que la conexión a la base de datos es creada de forma manual y otro error que es común ver, las credenciales están en el mismo archivo en que ejecutarás la sentencia. Las buenas prácticas dicen que se debería crear algo que podamos manejar, primero de un modo centralizado como por ejemplo en un archivo separado con tags identificables que permitan importar el fichero a nuestro script php, y lo Segundo es ofuscar un poco el modo o el lugar, por ejemplo si utilizas los ficheros en el /ROOT/ del sitio (visible por nosotros), intenta por lo menos dificultar la exposición este tipo de credenciales. Nuevamente, el ejemplo encontrado esto es solo a modo de tutorial.

¿Qué se puede hacer?

Primero que todo, el controlador que se puede utilizar para el manejo de MySQL es mysqli. En PHP existen dos formas de como manipularlo, la primera es a través de un método procedimental (funciones) y la segunda es la orientación a objetos. En cuanto a la sintaxis es prácticamente igual, pero cambia en la forma de como se referencia hacia las funciones (modo independiente o en un objeto de mysqli), por lo que ambas son válidas.

La forma de conexión:

   1 <?php
   2 // Try and connect to the database
   3 $connection = mysqli_connect($host,$username,$password,$dbname);
   4 
   5 // If connection was not successful, handle the error
   6 if($connection === false) {
   7 // Handle error - notify administrator, log to a file, show an error screen, etc.
   8 }
   9 ?>

La explicación para este fragmento sería; para mysqli_connect se requieren 4 parámetros esenciales como mínimo para crear la conexión (host, usuario, contraseñas, nombre de base de datos). Existen otros parámetros que dependerán de la implementación del servidor, pero para ello se puede ver el siguiente link: http://www.php.net/manual/en/mysqli.construct.php

Las siguientes lineas es validar la conexión, está demás decir que existen varios tipos de fallos de conectividad, siendo factible realizar un log file, error page, etc. quedando a la creatividad del desarrollador. El mensaje por pantalla es una opción buena y válida, pero cuidado con lo que muestras, puede dar pistas a un atacante y crear una vulnerabilidad.

Para el fragmento de código entregado requiere pasar los parámetros de conexión. Como ya se menciono anteriormente, no es una buena práctica mantener a los de acceso a la conexión de base de datos, especialmente si los archivos PHP están dentro del /ROOT/ del website. Es una buena opción mantener los parámetros de la base de datos separado de los archivos php, esto me permite hacer referencia en cualquier momento para hacer cambios generales en las aplicaciones.

Se crea un documento de texto que contenga lo siguiente:

[database]
username = root
password = 1234
dbname = mydb
host = localhost

La extensión del fichero pasa un poco a ser irrelevante, pero generalmente uso las extensiones ini, rc o txt

La necesidad de mantener las credenciales separadas de los archivos php se resumen principalmente que ante cualquier fallo o instancia de anormalidad del servidor web, este pudiese revelar como texto en pantalla revelando las credenciales.

   1 <?php
   2 // Load configuration as an array. Use the actual location of your configuration file
   3 $config = parse_ini_file('/ROOT/../config.ini');
   4 
   5 // Try and connect to the database
   6 $connection = mysqli_connect($config['host'],$config['username'],$config['password'],$config['dbname']);
   7 
   8 // If connection was not successful, handle the error
   9 if($connection === false) {
  10     // Handle error - notify administrator, log to a file, show an error screen, etc.
  11 }
  12 ?>

Todo lo anterior podemos ponerlo dentro de una clase (para trabajar en orientación a objetos) y dentro de esa clase también declarar una función para establecer la conexión

   1 <?php
   2 class Db {
   3     // The database connection
   4     protected static $connection;
   5 
   6     /**
   7      * Connect to the database
   8      *
   9      * @return bool false on failure / mysqli MySQLi object instance on success
  10      */
  11     public function connect() {
  12         // Try and connect to the database
  13         if(!isset(self::$connection)) {
  14             // Load configuration as an array. Use the actual location of your configuration file
  15             $config = parse_ini_file('/ROOT/../config.ini');
  16             self::$connection = new mysqli('localhost',$config['username'],$config['password'],$config['dbname']);
  17         }
  18 
  19         // If connection was not successful, handle the error
  20         if(self::$connection === false) {
  21             // Handle error - notify administrator, log to a file, show an error screen, etc.
  22             return false;
  23         }
  24         return self::$connection;
  25     }
  26 ?>

Consultando a la base de datos MySQL

Ahora que se tiene la conexión, podemos comenzar a utilizar el motor de base de datos.

Según los tutoriales de php.net y W3Schools la forma de establecer una consulta es del siguiente modo:

   1 <?php
   2 // Connect to the database
   3 $connection = db_connect();
   4 
   5 // Query the database
   6 $result = mysqli_query($connection,$query);
   7 ?>

Se Puede modificar esto y declarar una función pública como el siguiente ejemplo:

   1 <?php
   2 public function query($query) {
   3     // Connect to the database
   4     $connection = $this -> connect();
   5 
   6     // Query the database
   7     $result = $connection -> query($query);
   8 
   9     return $result;
  10     }
  11 ?>

El parámetro que recibe esta función es $query, que requiere ser una sentencia SQL. Existe un pero, en el caso de que sea una sentencia SELECT que requiere la devolución de resultados, quizás sea mejor separar en funciones los query y generar una solo para esta.

   1 <?php
   2 function db_select($query) {
   3     $rows = array();
   4     $result = db_query($query);
   5 
   6     // If query failed, return `false`
   7     if($result === false) {
   8         return false;
   9     }
  10 
  11     // If query was successful, retrieve all the rows into an array
  12     while ($row = mysqli_fetch_assoc($result)) {
  13         $rows[] = $row;
  14     }
  15     return $rows;
  16 }
  17 ?>

Cuando se utiliza mysqli_fetch_assoc, recibiremos columnas del objeto mysqli_result que serán del tipo array, que a su vez estarán indexados con las columnas de la base de datos.

Datos de entrada

Por último debemos generar un parser que sea dinámico para las entradas de los datos para los usuarios. El fin de este es importantisimo, puesto a que esta función sustituirá los valores de la variables declaradas para la entrada de datos cuando estos sean desconocidos. Hay algunos caracteres que usados por ejemplo entre comillas logran retornar valores o bien permite que se rompa nuestra consulta, creando una vulnerabilidad (ataque de inyección SQL).

Para esto mysqli tiene una función que nos ayuda mucho, mysqli_real_scape_string(). Esta función requiere de la conexión a la base de datos y los valores que queremos "limpiar".

La forma sería:

   1 <?php
   2 function db_quote($value) {
   3     $connection = db_connect();
   4     return "'" . mysqli_real_escape_string($connection,$value) . "'";
   5 }
   6 ?>

Los script resultantes

db.php

   1 <?php 
   2 
   3 /**
   4  * Database wrapper for a MySQL with PHP tutorial
   5  * 
   6  * @copyright Eran Galperin
   7  * @license MIT License
   8  * @see http://www.binpress.com/tutorial/using-php-with-mysql-the-right-way/17
   9  */
  10 class Db {
  11         // The database connection
  12         protected static $connection;
  13         
  14         /**
  15          * Connect to the database
  16          * 
  17          * @return bool false on failure / mysqli MySQLi object instance on success
  18          */
  19         public function connect() {
  20                 
  21                 // Try and connect to the database
  22                 if(!isset(self::$connection)) {
  23                         // Load configuration as an array. Use the actual location of your configuration file
  24                         // Put the configuration file outside of the document root
  25                         $config = parse_ini_file('./config.ini'); 
  26                         self::$connection = new mysqli('localhost',$config['username'],$config['password'],$config['dbname']);
  27                 }
  28         
  29                 // If connection was not successful, handle the error
  30                 if(self::$connection === false) {
  31                         // Handle error - notify administrator, log to a file, show an error screen, etc.
  32                         return false;
  33                 }
  34                 return self::$connection;
  35         }
  36         
  37         /**
  38          * Query the database
  39          *
  40          * @param $query The query string
  41          * @return mixed The result of the mysqli::query() function
  42          */
  43         public function query($query) {
  44                 // Connect to the database
  45                 $connection = $this -> connect();
  46                 
  47                 // Query the database
  48                 $result = $connection -> query($query);
  49                 
  50                 return $result;
  51         }
  52         
  53         /**
  54          * Fetch rows from the database (SELECT query)
  55          *
  56          * @param $query The query string
  57          * @return bool False on failure / array Database rows on success
  58          */
  59         public function select($query) {
  60                 $rows = array();
  61                 $result = $this -> query($query);
  62                 if($result === false) {
  63                         return false;
  64                 }
  65                 while ($row = $result -> fetch_assoc()) {
  66                         $rows[] = $row;
  67                 }
  68                 return $rows;
  69         }
  70         
  71         /**
  72          * Fetch the last error from the database
  73          * 
  74          * @return string Database error message
  75          */
  76         public function error() {
  77                 $connection = $this -> connect();
  78                 return $connection -> error;
  79         }
  80         
  81         /**
  82          * Quote and escape value for use in a database query
  83          *
  84          * @param string $value The value to be quoted and escaped
  85          * @return string The quoted and escaped string
  86          */
  87         public function quote($value) {
  88                 $connection = $this -> connect();
  89                 return "'" . $connection -> real_escape_string($value) . "'";
  90         }
  91 }

Y una forma de uso para eso:

   1 <?php
   2 // Quote and escape form submitted values
   3 
   4 include('./db.php');
   5 $db = new Db();  
   6 
   7 $name = $db -> db_quote($_POST['username']);
   8 $email = $db -> db_quote($_POST['email']);
   9 
  10 // Insert the values into the database
  11 $result = db -> db_query("INSERT INTO `users` (`name`,`email`) VALUES (" . $name . "," . $email . ")");
  12 
  13 $rows = $db -> db_select("SELECT * FROM `users`");
  14 
  15 foreach($rows as $row) {
  16     echo "name: ". row['name'];
  17     echo "email: ". row['email'];
  18 }
  19 
  20 ?>

Todo este documento se baso en unos script de Eran Galperin, licenciados con la MIT License. Pueden descargarse desde https://github.com/erangalp/database-tutorial

php/mysql (última edición 2016-09-13 19:26:00 efectuada por FabioDuran)