Posts Tagged ‘PHP’

noviembre 11, 2009 0

Consultas parametrizadas en PHP. Parte III.

By in PHP

En el anterior artículo vimos como parametrizar una consulta SQL usando el cierre de interrogante. En este vamos a usar el símbolo de dos puntos (:) seguido del nombre del parámetro para indicar estos. Al igual que en la entrada anterior vamos a ver primero el código y después una explicación del mismo:

<?php

function escapar($valor)
{
  // Retornamos la cadena escapada. Está solo como ejemplo.
  return mysql_escape_string($valor);
}

function prepararParametro($param)
{

  if(is_string($param))
  {
    // Si el parámetro es una cadena retornamos el valor
    // de la cadena escapado entre ' '.
    return "'".escapar($param)."'";
  }
  else if(is_array($param))
  {
    // Si es un array devolvemos una lista de los parametros
    // separados por comas. Cada elemento del array es procesado
    // por esta función para que tenga el formato correcto.
    $retorno = '';
    foreach($param as $p)
    {
      // Cuando retorno es vacio ('') quiere decir que no
      // Tenemos que añadir la coma.
      if($retorno == '')
      {
        $retorno .= prepararParametro($p);
      }
      else
      {
        $retorno .= ','.prepararParametro($p);
      }
    }

    return $retorno;
  }
  else if($param == NULL)
  {
    // Si es NULL devolvemos la cadena 'NULL'
    return 'NULL';
  }
  else
  {
    // Devolvemos el parametro.
    return $param;
  }
}

function prepararConsulta($consulta, $parametros = array())
{
  // Recorremos los parametros
  foreach($parametros as $nombre => $parametro)
  {
    // Juntamos cada parte con el parametro correspondiente preparado.
    $consulta = str_replace(":".$nombre, prepararParametro($parametro), $consulta);
  }

  // Devolvemos la consulta preparada
  return $consulta;
}
?>

Volvemos a tener las funciones escapar y prepararParametro, que funcionan exactamente igual que en la versión del interrogante (?). La novedad viene ahora en la función prepararConsulta, que se ha simplificado bastante. Ahora lo que hacemos es recorrer el array de parámetros con un bucle foreach, almacenando en la variable $nombre el nombre del párametro y en la variable $parametro el valor de este. Luego con la función str_replace reemplazamos las apariciones de :nombre por el parámetro preparado. Bastante sencillo.

Ahora, cuando llamemos a la función prepararConsulta, tendremos que pasarle un array con los valores indexados mediante un literal. Por ejemplo:

$parametros = array('user_id' => 'manuel', 'user_password => 'password');
$consultaPreparada = prepararConsulta($consulta, $parametros);

De nuevo, como en el artículo anterior, la función es mejorable pero es una buena aproximación al problema de las consultas parametrizadas.

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Tags: , ,

septiembre 23, 2009 1

Consultas parametrizadas en PHP. Parte II.

By in PHP

Hoy vamos a hacer la parte que se encarga de parametrizar las consultas usando el cierre de interrogación (?) como indicador de parámetro. Lo primero que vamos a ver es el código y después una explicación del mismo.

<?php

function escapar($valor)
{
 // Retornamos la cadena escapada. Está solo como ejemplo.
 return mysql_escape_string($valor);
}

function prepararParametro($param)
{

 if(is_string($param))
 {
 // Si el parámetro es una cadena retornamos el valor
 // de la cadena escapado entre ' '.
 return "'".escapar($param)."'";
 }
 else if(is_array($param))
 {
 // Si es un array devolvemos una lista de los parametros
 // separados por comas. Cada elemento del array es procesado
 // por esta función para que tenga el formato correcto.
 $retorno = '';
 foreach($param as $p)
 {
 // Cuando retorno es vacio ('') quiere decir que no
 // Tenemos que añadir la coma.
 if($retorno == '')
 {
 $retorno .= prepararParametro($p);
 }
 else
 {
 $retorno .= ','.prepararParametro($p);
 }
 }

 return $retorno;
 }
 else if($param == NULL)
 {
 // Si es NULL devolvemos la cadena 'NULL'
 return 'NULL';
 }
 else
 {
 // Devolvemos el parametro.
 return $param;
 }
}
function prepararConsulta($consulta, $parametros = array())
{
 // Partimos la consulta por los simbolos de interrogacion
 $partes = explode("?", $consulta);

 $resultado = '';
 $num_parametros = count($parametros);

 // Recorremos los parametros
 for($i = 0; $i < $num_parametros; $i++)
 {
 // Juntamos cada parte con el parametro correspondiente preparado.
 $resultado .= $partes[$i].prepararParametro($parametros[$i]);
 }

 $num_partes = count($partes);
 // Si hay más partes que parametros quiere decir que hay una parte final que hay que concatenar
 if($num_partes > $num_parametros)
 {
 $resultado.= $partes[$num_partes -1];
 }

 // Devolvemos la consulta preparada
 return $resultado;
}
?>

En este código hemos definido tres funciones:

  • escapar: Simplemente llama a mysql_escape_string para escapar las cadenas.
  • prepararParametro: prepara los parámetros en función de su tipo de dato.
  • prepararConsulta: esta es la que se encarga de parametrizar la consulta.

La función prepararParametro va comprobando el tipo de dato del parámetro, si es cadena, array, null o ninguno de estos. Cuando es cadena devuelve el parámetro entre apóstrofos y después de haber llamado a escapar, para escapar caracteres especiales. Cuando es un array devuelve cada uno de los elementos de este, después de procesarlos, concatenados y separados por comas, algo útil para usar el operado IN. Si el valor del parámetro es NULL devuelve la cadena NULL. Si no es de ninguno de los tipos anteriores simplemente devuelve el parámetro tal cual, asumiendo que es un número.

La función prepararConsulta parte la consulta pasada por el caracter ?. Luego va concatenando una de estas partes con el correspondiente parámetro. Si al final hay más partes que parámetros concatena la última parte al final y devuelve la consulta con los parámetros sustituidos.

Hay que tener en cuenta que no se realizan comprobaciones como que el número de parámetros pasado sea igual al número de parámetros que aparecen en la consulta. También se podría mejorar de varias formas, pero esta es una buena primera aproximación al problema.

Al final el código, o al menos eso me parece a mí, es mucho más claro que la propia explicación de como funciona. Si hay algo que no entendéis lo podéis preguntar en los comentarios. Por su puesto cualquier mejora que se pueda hacer se agradece.

En el próximo artículo de la serie veremos como usar parámetros con la forma :nombre_parámetro.

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Tags: , ,

septiembre 15, 2009 1

Extendiendo helpers en CodeIgniter

By in CodeIgniter, PHP

Añadir nuevas funciones a los helpers que vienen en CodeIgniter es realmente sencillo. Lo primero que tenemos que hacer es crearnos un archivo con el siguiente formato de nombre “prefijo_nombre_helper.php” en el directorio helpers de nuestra aplicación. El prefijo será usualmente MY, aunque esto es configurable. Vamos a ver un ejemplo y vamos a extender el helper html. Para ello creamos un archivo llamado MY_html_helper.php cuyo código es el siguiente:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if( ! function_exists('link_tag_multiple'))
{
  function link_tag_multiple($links)
  {
     $link_result = array();
     if(is_array($links))
     {
       if(count($links) > 0)
       {
         foreach($links as $link)
         {
           $link_result[] = link_tag($link);
         }
       }
       else
       {
         return FALSE;
       }
     }
     else
     {
       return FALSE;
     }

     return $link_result;
  }
}

if( ! function_exists('script'))
{
  function script($src = '', $language = "JavaScript")
  {
    $CI = & get_instance();

    $script = '<script ';
    if(is_array($src))
    {
      $script .= 'language="'.$src['language'].'" src="';
      if(strpos($src['src'],"://") == FALSE)
      {
        $script .= $CI->config->slash_item('base_url').$src['src'];
      }
      else
      {
        $script .= $src['src'];
      }
    }
    else
    {
      $script .= 'language="'.$language.'" src="';
      if(strpos($src,"://") == FALSE)
      {
        $script .= $CI->config->slash_item('base_url').$src;
      }
      else
      {
        $script .= $src;
      }
    }

    $script .= '"></script>';

    return $script;

  }
}

if( ! function_exists('script_multiple'))
{
  function script_multiple($scripts)
  {
    $scripts_result = array();

    if(is_array($scripts))
    {
      if(count($scripts) > 0)
      {
        foreach($scripts as $script)
        {
          $scripts_result[] = script($script['src'], $script['language']);
        }
      }
      else
      {
        return FALSE;
      }
    }
    else
    {
      return FALSE;
    }

    return $scripts_result;
  }
}

Bien como se puede ver con la primera linea evitamos el acceso directo a este archivo. Despues definimos tres nuevas funciones, siempre que no existieran antes. Acabamos de extender nuestro helper. Ahora al cargarlo disponemos de estas tres nuevas funciones.

Si a alguien le intereas esas tres funciones las uso para añadir multiples CSS en una vista y para añadir scripts de JavaScript.

Fe de erratas:

En el código original la función script_multiple hace una llamada a la función script y los parámetros estaban intercambiados. Es decir, antes de la corrección se pasaba $script[‘language’] y $script[‘src’] cuando debería ser $script[‘src’] y $script[‘language’]. Esto ya está corregido en esta edición.

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Tags: ,

septiembre 10, 2009 0

Consultas parametrizadas en PHP. Parte I.

By in PHP

Cuando realizamos una consulta a una base de datos normalmente esta lleva algún parámetro por el que filtramos. Para ello lo que se suele hacer es algo parecido a lo siguiente:

$consulta = "SELECT nombre FROM usuarios WHERE login='".escapar($login)."'";
$resultado = ejecutarConsulta($consulta);

En ese trozo de código obtenemos el nombre de un usario sabiendo el login de este. Para ello creamos la consulta concatenando cadenas, escapamos el valor del login (con la hipotética función escapar) para prevenir ataques SQL injection y luego llamamos a una, hipotética de nuevo, función llamada ejecutarConsulta (por ejemplo mysql_query) que nos devolverá los datos de la consulta.

Lo que propongo es usar una función que nos genere la consulta a partir de una consulta parametrizada. El prototipo de esta función es el siguiente:

string prepararConsulta(string $consulta, array $parametros);

Esta función nos devolverá una cadena con la consulta ya preparada y los paáametros se los pasaremos como un array. Se podrá parametrizar la consulta de dos formas distintas, mediante parámetros sin nombre o con parámetros con nombre. Veamos las dos formas:

Parámetros sin nombre:

SELECT fields FROM table WHERE cond1=? AND cond2=? AND cond3=?

Parámetros sin nombre:

SELECT fields FROM table WHERE cond1=:val1 AND cond2=:val2 AND cond3=:val3

Si habeis usado ADODb os sonará esta forma de hacer consultas.

En la siguiente parte del artículo veremos como podemos implementar una primera versión de esta función.

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Tags: , ,

agosto 29, 2009 0

Backup2Mail: creando copias de seguridad de nuestras bases de datos

By in Herramientas, PHP

Una de las cosas que hay que hacer periódicamente con nuestras bases de datos es realizar copias de seguridad, lo que nos ahorrará más de un quebradero de cabeza en caso de desastre. Una buena idea es automatizar todo el proceso. Para WordPress existe el plugin WordPress Database Backup pero si nuestra web no está basada en WordPress tenemos un problema. Para solventarlo vamos a hacer uso de un script en PHP llamado Backup2Mail.

Backup2Mail

Lo primero que tenemos que hacer es descargarnos el script de su página. Configuramos el archivo index.php con los datos que queramos:

/***************************************************
	Database settings
****************************************************/
	$db_server = 'localhost'; // Database server, usually "localhost"
 	$db_name   = '';	  // Database name, leave empty for 'all databases'
	$db_user   = '';	  // Database username
	$db_pass   = '';	  // Database password

/***************************************************
	E-mail settings
****************************************************/
 	$website = 'yoursite.com';	// Your site's domain (without www. part)
	$send_to = 'mail@yoursite.com'; // backup file will be sent to?

Subimos el archivo index.php a una carpeta en nuestro servidor, por ejemplo una llamada backup2mail. Ya tenemos instalado Backup2Mail. Para ejecutar el script habrá que hacer la siguiente llamada:

php /home/your_account/backup2mail/index.php >/dev/null 2>&1

Para finalizar. si lo deseamos, podemos hacer uso de algún demonio tipo cron para hacer que esto se ejecute cada cierto tiempo.

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Tags: , , , ,