zend

FirePHP – Integra logs de PHP en Firefox

En todo desarrollo se hacen necesarias herramientas que permitan hacer un seguimiento del código. Hoy voy a mostrar cómo mostrar logs desde PHP directamente a una consola en Firefox. ¡Di adiós a los “echos” y a los “var_dump”!

Páginas web modulares en PHP con Zend Framework

Jeroen Keppens está escribiendo en su blog una serie de artículos muy muy interesantes acerca de cómo implementar módulos autocontenidos empleando Zend Framework. Esta estrategia es increíblemente potente ya que, al ser módulos autocontenidos, podremos copiarlos directamente a un proyecto nuevo y ya funcionarán. Si se programan de forma suficientemente versátil, se podrán encajar entre sí como piezas de un lego que dan forma a la aplicación final. ¿No es genial? :)

En el primero de ellos nos muestra cómo crear el esqueleto de un módulo. Los pasos básicos a seguir son:

  1. zf create project .
  2. zf create module nombremodulo
  3. zf create controller index 1 nombremodulo
    1. Bug – Renombrar el nombre de la clase del controlador añadiendo el prefijo Nombremodulo_.
  4. Añadir configuración de módulos en application.ini:
    resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”
    resources.modules[] =

Básicamente con eso ya lo tenemos, accesible en el path relativo /nombremodulo. ¡Ha sido sencillo!

Por supuesto cada módulo se comporta como una mini-aplicación, por lo que podremos completarlo con su propio fichero Bootstrap.php. Nota: A mi me surgió la duda de cómo poder asegurarse de que un determinado método del Bootstrap principal se ha ejecutado (Por ejemplo, el resource db). Nada más tenemos que llamar a $this->getApplication() y obtendremos el Bootstrap principal. ¿Y esto por qué? Porque al estar contextualizados dentro de un módulo, no obtenemos el objeto Application como cabría esperar, sino el Bootstrap.

Llevado por la emoción, y teniendo en cuenta varios proyectos que tengo pendientes, me puse manos a la obra a programar mi primer módulo autocontenido: Usuarios. Será un módulo muy configurable que permita manejar sesiones, mostrar captchas, registro libre de usuarios o sólo por parte del administrador, acl, facebook connect, y más. Cuando tenga algo presentable lo liberaré :)

El caso, necesitaba que mi módulo fuera configurable. Por ejemplo, ¿se muestran captchas para hacer login? ¿Tras cuantos intentos fallidos? ¿Y qué tipo de captcha? ¿Dónde se almacenan los usuarios? ¿Y en qué campos? Para resolver eso necesitaba de un fichero de configuración. En lugar de tratar de que el propio módulo ejecute sus propios resources en su Bootstrap, opté por la solución fácil: Cargar a mano el fichero de configuración, y revisar sus opciones.

Pero de nuevo Jeroen Keppens ha dado en el clavo proponiendo la solución pro. En su segundo artículo sugiere un ingenioso y completo método para manejar configuraciones a nivel de módulo. No implementa aun manejo de errores, pues se trata de una pre-beta, pero ilustra a la perfección cómo solucionarlo.

Sólo le veo una pega a las soluciones que propone: Dependen en gran parte de su biblioteca extendida, es decir, es necesario tener accesibles a nivel de aplicación numerosas clases desarrolladas por él. Por supuesto, siempre hay una segunda opinión, y en mi caso ubico dichas bibliotecas en /modules/modulename/library/, pese a que en un futuro eso suponga ficheros repetidos. ¿No se trataba de tener módulos autocontenidos? ;)

Liberado Zend Framework 1.8.4 y más

A través del Developer Center de Zend me entero de que hoy se ha liberado la última versión estable de Zend Framework. Esta release de mantenimiento ha corregido más de 50 tickets abiertos en 20 componentes distintos. Con un poco de suerte ya podremos disfrutar de la rama 1.8 sin tantos workarounds para salir del paso.

Por lo pronto, y si utilizáis svn, ya tardáis en hacer un svn up :)

A finales del próximo mes de julio lanzarán la versión 1.9.0. ¿Qué está previsto que traiga? Pues bastantes cosas, como por ejemplo un lector de feeds mucho más completo y elaborado, enrutador para peticiones de tipo REST, soporte LDAP, patrón factory en Zend_Log, etc.

Además, acaban de lanzar también un visor de roadmap que estará activo a partir de ahora para todas las futuras releases. Si bien esta herramienta será muy útil tanto para fieles como para curiosos, no contará con fecha de lanzamiento, pues tal y como explican en su blog, es muy complicado estimar fechas cuando todo el trabajo lo realizan voluntarios en su tiempo libre.

Edit: Acabo de comprobar que además han corregido la creación de controladores en modulos desde la utilidad en línea zf. ¡Bravo! :)

Nueva página web de Torrijos

captura5El pasado día 11 de junio se presentó en el salón de plenos del Palacio de Pedro I la nueva página web del Ayuntamiento de Torrijos. Este momento marcó un punto y aparte en este nuevo portal para el ciudadano. Durante los últimos meses hemos dedicado muchísimos esfuerzos, ganas e ilusión a este proyecto, y creo que hemos logrado nuestro objetivo: Ofrecer una web renovada con contenidos de actualidad que sustituyera a la antigua.

Singleton serializado en sesión de PHP

Llevo un par de días liado programando desde cero una pequeña tienda online (Sin pasarelas ni florituras). Entre los hitos que tenía para hoy, el más importante es crear el carrito de la compra. He buscado por el todo poderoso, pero todas las soluciones que veía me parecían ineficientes o feas. No quería almacenar el carrito de forma “permanente” en la base de datos, de modo que lo lógico me parecía usar la memoria de las sesiones. Evidentemente el carrito debía ser un singleton, pero ¿cómo hacer que se serialice automáticamente en memoria?

Echemos un primer vistazo a un singleton en PHP:

class Example
{
    // Hold an instance of the class
    private static $instance;

    // A private constructor; prevents direct creation of object
    private function __construct()
    {
        echo 'I am constructed';
    }

    // The singleton method
    public static function singleton()
    {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }

        return self::$instance;
    }

    // Example method
    public function bark()
    {
        echo 'Woof!';
    }

    // Prevent users to clone the instance
    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

}

Sencillo, verdad? :) Pero este es el esqueleto de un singleton básico. Se declara como privado el constructor, de forma que si necesitas una instancia del objeto debas hacerlo necesariamente por el método estático Example::singleton(). Este método construye una nueva instancia, o bien devuelve la que ya había (Almacenada en el atributo estático $instance). Sin embargo la clase que yo necesito debe cargarse por defecto de memoria, y almacenar el objeto de nuevo cuando éste se destruya. La solución aquí:

class ShoppingCart
{

    private $_items;
    private static $_instance;
    private static $_namespace = "spp";

    private function __construct()
    {
        $this->_items = Array();
    }

    public function __destruct()
    {
        $shopping = new Zend_Session_Namespace(self::$_namespace);
        $shopping->object = serialize(self::$_instance);
    }

    public function __clone() {
        throw new Exception("Cannot clone singleton!");
    }

    public static function singleton()
    {
        $shopping = new Zend_Session_Namespace(self::$_namespace);

        if (!isset(self::$_instance)) {
            if(isset($shopping->object)) {
                self::$_instance = unserialize($shopping->object);
            } else {
                $c = __CLASS__;
                self::$_instance = new $c;
            }
        }

        return self::$_instance;
    }

    public function addItem($id, $quantity)
    {
        // Código que añade un nuevo item
    }

    public function removeItem($id)
    {
        // Código que elimina un item
    }

    // Resto de funciones del carrito de la compra
}

Básicamente funciona igual, excepto que antes de crear un nuevo objeto, comprueba si hay alguno en el espacio de nombres de memoria asignado en el atributo estático $_namespace. Igualmente, cuando el objeto se destruye automáticamente por el recolector de basura, se serializa para guardarse la nueva versión en memoria.

Es importante darse cuenta de esto último: El método __destruct() no funcionará si ya hemos finalizado la sesión del usuario mediante session_write_close(). Por esa razón, en algunos casos tendremos que llamar explícitamente al destructor antes de que se cierre la sesión. Resulta que el método para redirigir a otra página Zend_Controller_Action::_redirect($url) cierra la sesión. Me he vuelto loco hasta que he averiguado la razón. Se corrige simplemente llamando a ShoppingCart::__destructor() antes de hacer la redirección.

Zend Framework 1.8.0 Released

¡Qué gran noticia! :) Ha sido liberada la nueva versión de Zend Framework. Como principales novedades nos ofrece la posibilidad de utilizar Zend Tool, la herramienta de consola para hacer el trabajo sucio por nosotros, y además una nueva capa para servicios de computación nube (ugh!) en Amazon.

Desde la famosa aparición de Ruby on Rails en el año 2004, no han parado de aparecer nuevos frameworks de desarrollo implementando las fantásticas ideas alrededor de RoR. En PHP, por nombrar algunos, pronto se hicieron muy populares CakePHP o Symphony. Pero por otra parte tenemos a Zend, la empresa detrás del motor intérprete de PHP (En consecuencia, gozan de un principio de autoridad más que merecido en dicho lenguaje). Corría el año 2005 cuando lanzaron la primera versión de su framework.

Pese a que aun hoy se podría decir que carece de muchas funcionalidades que hace años son comunes hasta en los frameworks más espartanos, a título personal Zend Framework fue el que me cautivó desde el primer momento: Su funcionamiento es totalmente modular. A diferencia de sus competidores, no obliga a dar el salto de la noche a la mañana, sino que permite ir adoptando poco a poco sus utilidades, instalándolas bajo demanda. Lenta pero implacablemente vas cayendo presa de sus encantos, hasta que ya un día te das cuenta de que has dejado de programar en PHP; Ahora programas en ZF :)

Una de las ventajas de que sea tan increíblemente modular es que puedes dar el salto a su sistema MVC poco a poco. Primero empiezas con un bootstrap y controladres básicos, luego vas dominando las vistas y los layouts, hasta que finalmente un día añades modelos de datos, y modificas el enrutador a tu antojo. Todo ello controlando desde el primer momento qué estructura de directorios emplear, o de qué manera funcionará la maquinaria.

No sé a vosotros, pero yo una de las cosas que mas detesto de todas las novedosas herramientas de programación que surgen últimamente es la magia. Sigues los tutoriales y piensas “¡Dios mio! ¡He creado un blog en 10 minutos! Pero no tengo ni idea de cómo“. Y eso no deja buen sabor de boca. ¿Que ocurre si necesitas alterar levemente el funcionamiento de la aplicación que se crea en el tutorial? Pues que sudas tinta y en el peor de los casos vuelves acobardado a tu metodología de siempre. Esto no pasa zon ZF :)

Pero al lío, que mi disertación sobre frameworks se ha alargado. ¿Por qué me emociona tanto la nueva release? Porque, tras varios meses programando con él, acaba de salir el script de consola que permite crear los andamios de tu aplicación (Scaffolding). Pero, como todo en Zend, es totalmente personalizable. Puedes configurar el funcionamiento por defecto del script mediante el Provider y el Manifest.

Además, y cosa que me encanta, esta herramienta ha sido lanzada junto con una nueva arquitectura de aplicaciones: Zend_Application. Básicamente encapsula las funcionalidades del fichero bootstraping en un recurso reutilizable dentro de un objeto. O visto desde otra perspectiva, es el objeto principal con su método main(). Orientación a objetos al poder!

Respecto al apartado de la computación nube… No tengo mucho que comentar. Me gustan las infraestructuras estándar (Como LAMP), y eso de volcar mis recursos en plataformas propietarias, heterogéneas, y sólo en manos de un proveedor, no me gusta nada. Así que por el momento dejo el cloud computing a los gurús de las blackberries.