PHP prepared statement (consulta parametrizada) con MySQLi

Si bien en el pasado ya vimos como hacer una consulta parametrizada en este blog de una forma primitiva (fue un artículo antiguo y a día de hoy no lo haría así ni lo recomiendo, por lo que quedaos con este) o haciendo uso de PDO, toca ahora ver cómo hacerlo con MySQLi.

¿Por qué usar MySQLi y no PDO? En fin, todo depende del caso. PDO nos permite abstraernos del SGBD, con sólo cambiar un parámetro en la creación nuestro código funcionará en Postgres, MySQL, Oracle… MySQLi, en cambio, sólo funciona con MySQL. En principio parece que no hay ningún motivo para usar MySQLi, pero si nos metemos en temas de rendimiento veremos que MySQLi va a penalizar menos el rendimiento de la página que PDO. Es decir, trabajando con MySQL nuestra web requerirá menos recursos usando MySQLi que PDO. Si por lo que sea estás con un proyecto que estás seguro de que no a tener que migrarse de SGBD, si sabes positivamente que se va a usar MySQL durante mucho tiempo, entonces MySQLi es tu opción.

Entonces ¿cómo hacemos una consulta parametrizada con MySQLi? Bueno, veamos como se hace una SELECT que recogería unos datos de la BD vinculados a un id del que disponemos en nuestro PHP?


$mysqli = new mysqli ("servidor", "usuario", "password", "nombre_base_de_datos"); //creamos el objeto MySQLi<code>
</code>

if($mysqli->connect_errno){ //comprobamos que no haya errores de conexión

die( 'La cagaste, esto no va'); //mensaje de error

}

if(!$prepared_st = $mysqli->prepare("SELECT * FROM tabla WHERE id = ?")){//creamos el statment y controlamos los errores

die("La cagaste again"); //mensaje de error

}

&nbsp;

//ahora toca vincular el parámetro id a la consulta

$id=5;

if(!$prepared_st->bind_param("i",$id)){ //vinculamos el parámetro

die("Fallito en la vinculación");

}

if(!$prepared_st->execute()){//ejecutamos la consulta

die("Fallo en la ejecución");

}

$resultado = $prepared_st->get_result(); //recogemos resultado

$prepared_st->close(); //cerramos el prepare

$mysqli->close(); //cerramos la conexión a la base de datos

Bueno, toca una pequeña explicación de bind_param: como veis en este caso recibe dos parámetros. El primer parámetro de bind param siempre es una cadena donde le pasamos una serie de letras que identificarán los tipos de datos que le vamos a proporcionar luego con las variables. Es decir, en el ejemplo le decimos primero que le va a llegar un entero, y luego pasamos la variable de ese entero. Si quisiéramos pasar un entero y una cadena (en se orden) el primer parámetro sería «is» y luego irían la variable entera y la variable cadena. El orden es fundamental.

Finalmente recogemos el resultado (para usar get_result() tienes que tener instalada la extensión mysqlnd, si no tendrás que usar bind_result()), que podemos convertir a array con las funciones fetch_array o fetch_assoc según convenga. En cualquier caso en la web de php.net tenéis más información con la que trabajar. Para el resto de operaciones CRUD la cosa va siendo similar: consulta, vinculamos parámetros, ejecutamos, recogemos resultado si procede.

Crear un botón Pin it para compartir en Pinterest desde tu web

Cierto es que Pinterest ha sacado un complemento para el navegador que agrega un botón Pin-it a tu Firefox o Chrome, pero con todo es recomendable agregar un botón de compartir en Pinterest a tu web. Puede que en España no sea todavía muy popular esta red social (y desconozco las estadísticas para América Latina)  pero para sitios de fotografía y moda se ha vuelto indispensable.

Como en todas las redes sociales, crear el botón es fácil (a ellos les interesa facilitarte el trabajo): Tan sólo tienes que irte al generador de widgets de Pinterest y crearlo desde allí.

Para el botón de Pin It verás que se te ofrecen 3 opciones: One Image, Any Image o Image Hover. La primera opción es para crear el botón sólo para una imagen concreta, de ahí el formulario donde se te pedirá el url de la imagen y que elijas donde ubicar un contador. Debes copiar tanto la notación HTML como el script que te da y ubicarlo donde te sea más cómodo.

Boton Pin it
Pin it!!!

La opcion Any Image te permitirá crear un botón para insertar cualquier imagen de la página en que esté ubiado en Pinterest (similar al que hay implementado a día de hoy en los productos de la web de la marca Mango, por ejemplo). Tienes que pegar un HTML en tu código para que genere el botón y un script.

Finalmente Image Hover hará que sobre cada imagen de la página en que ubiques el script aparezca un botón de compartir en Pinterest al sobrevolarla con el ratón. En este caso no habrá HTML y sólo tendrás que copiar el script.

Y así, de forma sencilla tienes el botón insertado en tu web. Para insertar el botón Pin It en un blog de Blogger podéis seguir esta guía.

Configurar servidor Apache para que nos muestre los errores de nuestro PHP

Un poco de sistemas y un poco de PHP mezclado en esta entrada, porque aunque sean tareas muy básicas no está demás comentarlas.

Lo primero es decir que esto NUNCA debe hacerse en un servidor de producción, JAMÁS. Es decir, esta configuración es una ayuda para el programador, por lo que lo recomendable es hacerlo en el servidor de desarrollo/local. Mostrar los errores en producción supondrá una debilidad en la seguridad de la página, así que recuerda: Sólo para desarrollo.

Apache Foundation

Una vez dicho esto, comentar también que si instaláis Apache en un servidor Linux, o si utilizáis XAMPP en Windows, por defecto vendrá con la detección de errores desconectada. En ese caso si tenéis un fallo se mostrará una página en blanco. Este es el comportamiento adecuado en producción, pero en vuestro equipo de desarrollo lo más cómodo es que os muestre el error y en qué línea se ha detectado.

Para cambiar la configuración tenéis que iros a buscar el archivo de configuración de PHP (php.ini), que en Ubuntu por defecto está en etc/php5/apache2/php.ini y en XAMPP podéis acceder a él desde el panel de control principal. Si no lo encontráis basta con que hagáis una página que imprima la función phpinfo() y ahí veréis la ruta completa al archivo (aparece como Loaded Configuration File).

Una vez abierto el archivo con un editor de texto os vais a buscar la instrucción display_errors, que estará por defecto en Off y la cambiáis por On. Vamos que quedará display_errors = On y, tras esto, guardáis los cambios en el archivo. Tras eso reiniciáis el servicio (en XAMPP desde el panel, en Ubuntu con sudo/etc/init.d/apache2 restart) y ya debería estar cantándoos los errores. En todo caso, ejecutad un script con algún fallo que sepáis dónde está (tipo dejaros fuera una coma en la primera fila o un paréntesis sin abrir) para ver que todo funciona correctamente.

Con esto habréis configurado ya vuestro servidor para que detecte los errores, lo que será una enorme ayuda a la hora de desarrollar páginas PHP.

Interlineado en CSS

Una entrada simple y básica de CSS ¿Quieres modificar el interlineado de un texto en tu web? Es muy simple.

El interlineado es la separación existente entre las líneas de un mismo texto. Por defecto en html se aplica un interlineado sencillo, pero podéis usar css para cambiarlo. La propiedad que debéis usar es line-height, tal cual así:


line-height: 1.3em;

Como siempre podéis definir las medidas del ancho de línea en diversas unidades: píxeles, centímetros, em, un porcentaje. Si queréis que mantenga la proporción respecto al texto lo más recomendable es usar em, si queréis un tamaño fijo px y para diseños fluídos porcentaje.

Colorzilla: Complemento productivo para desarrolladores

¿Te ha pasado alguna vez de ver en una web y decir «Ese es el color que quiero para mi cabecera»? Bueno, Colorzilla te permite integrar en tu navegador (Chrome o Firefox) una serie de herramientas relacionadas con el tema de la elección/búsqueda de colores que puede facilitar tu trabajo como desarrollador.

En principio lo que yo buscaba era un simple Eyedropper para mi navegador, es decir, una aplicación que me permitiera conocer el código RGB de un color que esté saliendo en mi pantalla. Esta es la función principal de Colorzilla, pero no la única ni la más potente. También nos dota de un selector de color (Colorpicker) y un navegador de paletas que agilizan bastante el trabajo (combínalo, por ejemplo, con Firebug y piensa en la velocidad de poder probar todo eso en el navegador) y que además nos deja salvar colores y paletas como «favoritos».

Pero las dos herramientas más interesantes, y más potentes, creo que son el generador de degradados, que te permite modificar varias plantillas y te da el código CSS pensado para mantener la compatibilidad con navegadores obsoletos, y el Web Page DOM Color Analizer. Este último se tira un ratito analizando una página y finalmente te da todos los colores que se han usado en la misma, informándote sobre qué elementos usan cada uno. Esto te ayudará a hacerte una idea al respecto del diseño del sitio.

Resumiendo, un complemento ligero que puede ser muy útil y productivo a la hora de trabajar desarrollando un front-end.

Notación Húngara: Una convención de .NET y Delphi

Como muchos sabéis, porque lo he comentado por aquí alguna vez, las prácticas del ciclo de FP las hice en una empresa que trabajaba en .NET y allí tuve mi primera experiencia con la llamada Notación Húngara. Esta fue creada por el programador húngaro Charles Simonyi, famoso por haber sido el padre de Bravo (el primer editor WYSIWYG) y uno de los responsables de Micosoft Office.

Aunque en Delphi no acabó de tener éxito, la notación húngara sí ha sido muy utilizada dentro de los desarrollos de la propia Microsoft. Dicha notación consiste en añadir antes del nombre de las variables uno o varios caracteres que indican su tipo. Esta técnica era muy útil hace años, si bien en la actualidad tiene muchos detractores, dado que actualmente es sencillo conocer el tipo de una variable sin tener que leerla en su declaración, por lo que se considera que esta notación sólo añade complejidad a la hora de programar.

Los prefijos a usar más habituales son:

  • a: Array
  • b: Booleano
  • by: Byte
  • c: Caracter de un byte
  • d: Tipo numérico de alta precisión (double o float)
  • dw: Tipo numérico de alta precisión
  • e: Evento o enumeración
  • f: Puede ser función o flags
  • fn: Función
  • g: Tipo delegado
  • h: Puede ser Hashtable o Handle
  • hdc: Handle a un contexto de dispositivo
  • hwnd: Handle a un contexto de ventana
  • i: Entero
  • ID: Identificador
  • l: Entero largo, de 32 bits. También puede ser ‘lock’, para definir objetos de control tipo candado
  • lbl: Objeto label
  • lp: Puntero a entero de 32 bits
  • lpfn: Puntero a una función que devuelve un entero largo
  • lpsz: Puntero a una función que devuelve una cadena terminada en cero
  • n: Entero de 16 bits o tipo enumerado
  • o: Objeto
  • p: Puntero
  • pt: Coordenadas empaquetas en un entero de 32 bits
  • rgb: Valor de color rgb empaquetado en un entero de 32 bits
  • s: Cadena de texto
  • sz: Cadena de texto terminada en cero
  • t: Variable tipo struct
  • txt: Caja de texto
  • v: Variable
  • w: Entero de 16 bits
  • x: Coordenada x.
  • y: Byte. También puede ser una coordenada y.

Otra de las cosas que se achaca a esta nomenclatura es la inexistencia de un estándar claro, lo que puede llevar a confusiones a la hora del mantenimiento del código.

El patrón Registry (y su aplicación en PHP)

Volvemos a los patrones de diseño tras un par de artículos de otra índole, y lo hacemos con Registry. La idea de este patrón es que nos permita utilizar los objetos y variables registrados en cualquier nivel de la aplicación sin necesidad de duplicarlos. Es decir, en la práctica nos permitiría usar cualquier objeto como si fuera un Singleton.

La idea de este patrón es crear una clase que tenga un array donde guardar los objetos registrados y una serie de métodos: uno que añada los objetos al array, otro que compruebe su existencia para evitar duplicaciones, otro que devuelva el objeto pasándole su clave, uno que borre el objeto recibiendo la clave y finalmente uno que limpie el array de la clase.

Pasado a código, PHP como siempre, la estructura sería la siguiente:

    <?php      
    class Registry  
    {  
        /** 
         * Registra variables y objetos         
         */  
        static private $registry = array();  
      
        /** 
         * Método que añade objetos
         * Recibe el objeto (por referencia) y la clave
         * Devuelve un booleano para confirmar si se ha insertado
         * o si en cambio estaba duplicado.
         */  
        static public function add($key, &$elemento)  
        {  
            if (!self::exists($key)) {  
                self::$registry[$key] = $elemento;  
                return true;  
            } else {  
                return false;  
            }  
        }  
      
        /** 
         * Función que comprueba la existencia de una clave.
         * Devuelve un booleano confirmando si existe o no.
         */  
        static public function exists($key)  
        {  
            return array_key_exists($key, self::$registry);  
        }  
      
        /** 
         * Función que devuelve un item dada la clave          
         */  
        static public function get($key)  
        {  
            if (self::exists($key)) {  
                return self::$registry[$key];  
            } else {  
                return null;  
            }  
        }  
      
        /** 
         * Elimina una entrada recibiendo su clave y devuelve confirmación.
         * Si la clave no existe devuelve false.
         */  
        static public function remove($name)  
        {  
            if (self::exists($name)) {  
                unset(self::$registry[$name]);
                return true;  
            } else {
                return false;
            }  
            
        }  
      
        /** 
         * Limpia el registro totalmente.         
         */  
        static public function clear()  
        {  
            self::$registry = array();  
        }  
    }  
    ?>  

El ejemplo es una estructura muy básica, puedes ampliarlo con filtros varios, control de errores y demás, pero la idea del esqueleto de este tipo de clase.

Ale, a disfrutarlo.

Patrón MVC y PHP

Cierto es que este mes he estado poco activo en cuestiones bloggeras, pero ya me tenéis de vuelta con el tema de los patrones de Diseño, en este caso con el popular MVC (Model/View/Controller o Modelo/Vista/Controlador).

La idea del patrón MVC es separar en tres capas los datos (model), la interfaz de usuario (view) y la lógica de negocio (controller). Esto permite una mayor reutilización de componentes, facilita la modificaciones del aspecto del programa/web sin tener que tocar el funcionamiento y simplifica el mantenimiento. Funciona de forma «triangular», es decir, cada capa envía información a una y la reciba de la otra.

El modelo sería la representación de la información y se encargaría de gestionar el acceso, adición y modificación de los mismos (operaciones CRUD). A nivel de interacción con los otros componentes enviaría a la vista los datos que tienen que ser mostrados y recibiría desde el controlador las peticiones de acceso y manipulación.

La vista sería, como su nombre indica, lo que se ve en pantalla. Además de mostrar los datos al usuario le permite interactuar con ellos. La vista recibe del modelo los datos a mostrar y permite al usuario comunicarse con el controlador a través de sus objetos.

Finalmente el controlador, trabajaría como puente entre la vista y el modelo, recibiendo las peticiones del usuario a través de la primera, realizando las labores de transformación necesarias y realizando finalmente las peticiones al modelo.

Aunque el MVC nació originalmente (allá por los años 70) para aplicaciones de escritorio, el desarrollo de la web dinámica hizo que fuera adoptado como patrón para diseñar la arquitectura de muchos sitios web. Existen múltiples frameworks para diversos lenguajes que permiten implementar el MVC a la arquitectura web. En el caso de PHP hay gran variedad, pero desde aquí vamos a destacar cuatro de ellos, todos software libre:

  • Zend Framework: Dado que Zend es la empresa con más peso en el mundo de PHP, comenzaremos con su framework. He de decir que hasta la versión 1.9 existen muchas quejas al respecto de su rendimiento, pero a partir de la versión 2 se reescribió el código para lograr aligerarlo. Está bajo licencia BSD, por lo que su uso es cercano al dominio público.
  • Symfony: Creo que a día de hoy es el framework más utilizado en PHP. Funcional, ligero, productivo y bien estructurado, es utilizado por gran número de CMS  (destacando Drupal) y por empresas potentes. Está bajo licencia MIT.
  • Codeigniter: Un veterano, al menos según mi percepción porque fue del primero del que oí hablar. Por lo que se dice tiene menos funcionalidades que Symfony o Zend, pero a su favor juega con tener una mayor flexibilidad y menor peso. Menos productivo pero más adaptable. Su licencia es GNU/GPL.
  • CakePHP: Irrumpió con mucha fuerza hace un par de años, pero parece que al final no ha logrado desbancar a Zend y Symfony del trono, en parte porque se dice que tiene una curva de aprendizaje más pronunciada. Incluye funcionalidades para casi todo y está bajo licencia MIT al igual que Symfony.

Y con estos cuatro no se acaba, hay docenas de frameworks para PHP funcionales como Yii, ZanPHP (de esto no tengo muy claro su estado, porque la web oficial a día de escribir este artículo, aparecía como un dominio caducado, pero en GitHub sigue) o KumbiaPHP. En cualquier caso, la oferta es amplia y variada en ese sentido.

Sesiones en PHP: uso básico

A la hora de guardar los datos de navegación de un usuario de nuestra web el uso de sesiones se torna esencial. Las sesiones son una forma fácil y práctica de almacenar estos datos del usuario (los almacena en una cookie de sesión que gestionará el propio navegador), de forma individual, para trabajar con ellos.

La idea es simple: cuando llamamos a la función session_start() PHP comprueba si existe un ID de sesión, en caso negativo crea una sesión nueva y en caso afirmativo mantiene los datos de la creada. Con la sesión activa podremos utilizar la variable array superglobal $_SESSION para almacenar los datos que queramos relativos a la navegación. Piensa en el carrito de la compra de cualquier tienda on-line, que va almacenando los items que vas comprando hasta que haces el pago, creo que es el mejor ejemplo de cómo funcionan estas variables.

Vamos a ver un ejemplo donde creamos una sesión y almacenamos la hora de la última conexión y de la última acción:

@session_start(); //iniciamos la sessión

if(!isset($_SESSION["first_connection"])){ //comprobamos si existe la variable y si no, inicializamos
  $_SESSION["first_connection"] = time(); //asignamos a la variable la fecha de creación
}else{
  $_SESSION["lastAction"] = time(); //sobreecribimos la fecha de la última acción
}

Un ejemplo tonto, pero básico.

Para destruir una sesión, por ejemplo al pulsar un botón de logout, usaríamos la función @session_destroy(). Y para acceder al id de la misma la función @session_id() nos lo devolverá. Si queremos cargarnos una variable de la sesión sin destruir la sesión basta con usar la función unset(), más o menos como en el ejemplo que va ahora:

//AHORA QUEREMOS DEJAR DE ALMACENAR LA ÚLTIMA ACCIÓN
unset($_SESSION["lastAction"]);

Ni se os curra hacer unset($_SESSION) sin indicar variable para cargároslas todas, esto deshabilitará el registro de las variables del array y os romperá un montón la cabeza.

En fin, como siempre si queréis más ejemplos en la web de PHP podéis explorar sobre el uso de sesiones. Un saludo y que os sea provechoso.

El patrón de diseño Singleton (implementado en PHP)

Vamos con la entrada número 400 del blog, y la 200 de informática. Curioso, llegados a este punto de casi dos años bloggeando un tema que no era el principal ha acabado ocupando el 50% del contenido del blog.

En fin, seguimos con los patrones de diseño. El otro día hablaba del patrón Decorator, hoy vamos con el Singleton.

La idea del patrón Singleton, también llamado de instancia única, es restringir la creación de objetos pertenecientes a una clase a sólo uno. Garantiza que sólo hay una instancia y proporciona un único punto de acceso.

La idea es que la clase tenga un constructor privado para que no pueda ser accedido desde fuera de la clase y que aunque haya clases hijas estas no puedan instanciar objetos. También debe tener una propiedad estática privada donde almacenaremos nuestra instancia y un método estático que sea el punto de acceso global a la misma, devolviéndola cuando se lo llama.

Vamos con el ejemplo típico y tópico del objeto de base de datos, que suele ser el uso más común de este tipo de clases. Porque crear varias instancias de acceso a una base de datos en la mayoría de los casos es un malgasto de recursos, lo mejor suele ser tener una sola instancia para realizar las conexiones.

class Database {
//Propiedad estática, inicializada a nulo, donde guardaremos la instancia de la propia clase
    static private $instance = null;
//Definimoms el método constructor como privado
    private function __contruct() {}
     
//Método estatico que sirve como punto de acceso global
    public static function getInstance() {
        if (self::$instance == null) {
//Si no hay instancia creada, lo hace. Si la hay tira p'alante
            self::$instance = new Database();
        }
//Al final devuelve la instancia
        return self::$instance;
    }
	     
 //a continuación ya meterías todas las funciones necesarias para un objeto de base de datos. CRUD, etc...
}

Y ya est… No, sorry man pero no. Con el código así todavía es posible que alguien logre hacer más de una instancia. Y te dirás ¿cómo? Pues porque todavía es posible usar la clonación y la serialización para lograrlo. Cosa mala, pero con los métodos mágicos de PHP5 podemos arreglarnos.

Para evitar la cuestión de la clonación definimos el método mágico __clone() en la clase, para que en lugar de permitir el clonado del objeto nos lance un error y detenga el script:

public function __clone()
{
  trigger_error("No puede clonar una instancia de ". get_class($this) ." class.", E_USER_ERROR );
}

Y vamos con el tema de la serialización y deserialización. Con la función serialize() se puede almacenar una representación apta de una variable (y una instancia de un objeto es, al fina, una variable) mientras que con unserialize() podemos acceder a ella como se si tratara de un clon. De nuevo hay que redefinir un método mágico, en concreto esta vez __wakeup(), que es el método que se invoca al deserializar un objeto. De esa forma se evita que pueda ser accedido. También podría hacerse con __sleep(), que es el que se invoca al serializar, pero veo más práctico evitar la deserialización.

public function __wakeup()
{
  trigger_error("No puede deserializar una instancia de ". get_class($this) ." class.", E_USER_ERROR );
}

En fin, he caído en el ejemplo tópico, pero también me pareció el más claro. Un saludo, disfruta este articulo 400.