jueves, 22 de mayo de 2014

PHP avanzado: Llamadas recursivas en funciones anónimas (closures)

PHP

Una closure es una función sin nombre que puede por ejemplo asignarse a una variable o pasarse como parámetro a otra función. PHP soporta closures desde la versión 5.3 con una restricción importante: El ámbito de las variables es totalmente privado. Esto quiere decir que desde dentro de la closure no se puede acceder a variables externas a no ser que sean variables globales y las declares con la palabra clave global. Una excepción a esto son las variables superglobales. Además desde PHP 5.4 se puede acceder a $this si la closure se declara dentro de un método de una clase. Esa restricción no es un problema por si mismo, pero restringe el uso de variables locales cuando declaras la closure dentro de una función o de un método de una clase. Para solucionar eso se usa la palabra clave use. Entonces si queremos hacer una llamada recursiva a la closure tendremos que pasar una referencia a la propia closure a través de la palabra clave use. Por ejemplo (*):

$factorial = function( $n ) use ( &$factorial ) {
    if( $n == 1 ) return 1;
    return $factorial( $n - 1 ) * $n;
};

(*) Ejemplo sacado de Stack Overflow.

martes, 20 de mayo de 2014

Añadir métodos a una clase en Javascript

Javascript es un lenguaje de programación que está cada vez más en alza debido a sus enorme flexibilidad y a sus muchas posibilidades. Una característica que los principiantes en este lenguaje no suelen conocer es que se puede añadir y modificar el comportamiento de los métodos de una clase posteriormente a la declaración de la misma. Y esto puede hacerse tanco con clases propias como con clases nativas del lenguaje.

Por ejemplo la clase String, que es nativa de Javascript, tiene muchos métodos útiles como pueden ser trim(), substring(), indexOf() o replace(); pero carece por ejemplo de un método stripTags() que elimine las etiquetas HTML de una cadena de texto. Sin embargo podemos añadirlo fácilmente:

String.prototype.stripTags = function() {
    return this.replace(/<(?:.|\n)*?>/gm, '').trim();
}

Una vez declarado podemos hacer lo siguiente:

var x = "<p>Hola <b>mundo</b>.</p>";
x = x.stripTags();
document.write(x);

El resultado será "Hola mundo" sin los tags HTML.

martes, 22 de abril de 2014

Cual es el mejor IDE para programar en PHP

Un IDE (Integrated Development Environment) o entorno de desarrollo integrado es la herramienta que los programadores usamos para programar. En realidad los programadores somos gente simple: lo único que de verdad necesitamos para programar es un buen editor de texto. Luego si queremos probar nuestro desarrollo necesitaremos el compilador o intérprete del lenguaje de programación que estemos usando y dependiendo del caso igual algunas herramientas adicionales como un servidor web o la máquina virtual de Java. Pero de entrada lo único imprescindible es un editor de texto.

Como editor de texto nos vale casi cualquier cosa: desde el inútil bloc de notas de Windows hasta el complejo EMACS de GNU, pasando por el Notepad++ o el Ultra Edit en Windows, el gEdit en Ubuntu o el VI o el Nano en cualquier distribución Linux. Los programadores que ya peinamos canas recordamos aun los tiempos en que los IDE no se habían generalizado y la nuestra única herramienta era un editor de textos.

¿Que es un IDE?

Un IDE es un conjunto de herramientas integradas en un único paquete que proporciona a los programadores un marco para el desarrollo de aplicaciones informáticas. Un IDE puede servir para programar en un único lenguaje, en varios lenguajes o ser de propósito general (para cualquier lenguaje, generalmente añadiendo plugins).

Un IDE puede tener algunas de las siguientes herramientas (o todas ellas):

¿Cual es el mejor para programar en PHP?

Y ahora que ya he explicado que es un IDE, ¿Cual es el mejor para programar en PHP? Pues la pregunta es complicada. Cada programador tendrá sus preferencias, pero personalmente después de haber probado varios tanto en Windows como en Linux me quedo con PhpStorm.

PhpStorm es un IDE comercial multiplataforma de JetBrains que incluye editores para PHP, HTML y JavaScript, análisis de código en tiempo real, prevención de errores y mucho más. A mi me gusta sobre todo porque es muy rápido y bastante intuitivo de usar. He probado otros IDE como Eclipse y NetBeans, ambos gratuitos y open source, pero prefiero la rapidez de PhpStorm.

martes, 15 de abril de 2014

iTherm, una app para controlar la fiebre infantil

Hoy quiero dar difusión a un proyecto de un amigo que está buscando financiación. Se trata de iTherm un brazalete termómetro para niños que se conecta vía bluetooth con un dispositivo móvil (iPhone o Android) para realizar una medición constante de la temperatura del niño, pudiendo configurarse alertas para que avise si la temperatura supera un cierto límite. Dejo a continuación el vídeo de la entrevista que le han hecho recientemente La Vanguardia.

lunes, 14 de abril de 2014

El experto

Hoy voy a publicar un vídeo que he visto en Microsiervos. El vídeo se titula The Expert (el experto). Es una parodia perfecta de aquellas reuniones de trabajo en las que los jefes llaman a un empleado experto en cierto campo pero luego no tienen en cuenta sus opiniones. Como nota final decir que yo me he encontrado más de una vez en situaciones como esta, algunas igual de surrealistas y que en cierta ocasión tras una reunión así tuve yo otra reunión con mi manager donde me acusó de actitud negativa y falta de visión comercial. Mi campo es el desarrollo de aplicaciones informáticas, pero este se puede aplicar a casi cualquier trabajo de oficina. El vídeo está en inglés pero se entiende bien y además se pueden activar los subtítulos que funcionan perfectamente.

viernes, 28 de marzo de 2014

Symfony2 avanzado: Usando un objeto Query para crear un QueryBuilder

Este caso es un poco difícil de explicar. Vamos a suponer lo siguiente: Tenemos una entidad Factura y un repositorio FacturaRepository que tiene una función findFacturas(). Dicha función recibe un parámetro obligatorio $usuario de clase Usuario y otro opcional $filtros que por defecto es un array vacío. La mencionada función, que está perfectamente testeada y no desea cambiarse, prepara dinámicamente una query DQL teniendo en cuenta los permisos del usuario y un montón de filtros y devuelve un objeto de clase Query que al ejecutarla devuelve la lista de facturas del usuario.

namespace Company\ContabilidadBundle\Entity;

class Factura {
  //...
}

class FacturaRepository {
  public function findFacturas(Usuario $usuario, $filtros = array( )) {
    //...
    return $query;
  }
}

Por otro lado, en otra parte de la aplicación, tenemos un formulario en el que necesitamos poder seleccionar una de las facturas del usuario mediante un cuadro de selección (combobox). Para ello lo más lógico es añadir al formulario un campo de tipo entity. El problema es que que no podemos aprovechar la query que tenemos en nuestro repositorio porque los campos entity se cargan con un QueryBuilder.

Hoy me he encontrado con este mismo problema. Quedaba totalmente descartado Convertir en un QueryBuilder una query DQL de dos palmos y medio de largo, perfectamente testeada, por su complejidad (y porque no me daba la gana), así que me he puesto a investigar si había alguna forma de convertir o cargar un objeto Query en un objeto QueryBuilder. No ha sido fácil pero lo he conseguido...

Este es el resultado:

namespace Company\ContabilidadBundle\Form\Type;

class FormularioFormType extends AbstractType {

  //...

  public function buildForm(FormBuilderInterface $builder, array $options) {

    //...

    $builder->add(
      'factura',
      'entity',
      array(
        'class' => 'CompanyContabilidadBundle:Factura',
        'query_builder' => function(EntityRepository $repository) use($usuario) {

          $query = $repository->findFacturas($usuario);
          $qb = $repository->createQueryBuilder('f');
          $qb->where($qb->expr()->in('f', $query->getDql()));
          $qb->setParameters($query->getParameters());
          return $qb;
        }
    ));
  }
}

Veámoslo paso a paso:

  1. En primer lugar obtenemos el objeto Query del repositorio. Dicho objeto estará listo para ser ejecutado devolviendo el resultado que deseamos.
  2. En segundo lugar extraemos la sentencia DQL y los parámetros del objeto Query con las instrucciones $query->getDql() y $query->getParameters().
  3. En último lugar creamos un nuevo objeto QueryBuilder y simulamos una subquery como esta: SELECT * FROM Facturas f WHERE f IN (...), poniendo la sentencia DQL original en el lugar de los puntos suspensivos.

Es rebuscado pero funciona perfectamente.

sábado, 1 de marzo de 2014

Symfony 2: Añadiendo bundles externos

Esta es la tercera parte del mini-curso de Symfony 2 que empecé hace tiempo. En el último capítulo creamos nuestro primer proyecto Symfony 2. El proyecto recién creado traerá todas las dependencias necesarias para empezar a programar con el framework Symfony. Sin embargo una de las grandes ventajas de Symfony 2 es que es fácilmente ampliable mediante librerías externas programadas por terceros llamadas bundles.

Hay bundles para todos los gustos: unos añaden características nuevas a Symfony 2, otros mejoran su seguridad, otros amplían funcionalidades, etc. La forma de instalar un bundle externo es nuevamente mediante el uso de composer. Para ello hay que añadir las dependencias en el archivo composer.json que encontraremos en la raíz de nuestro proyecto Symfony de la siguiente forma:

{
    "require": {
        "vendor/package": "version",
    }
}

En este caso vendor y package forma el nombre del bundle mientras que version es el número de versión (por ejemplo: 1.2.3 o 1.2.* o >1.2.3 o >1.2.3,<1.3, etc. Para buscar bundles compatibles podemos ir a Packagist, que es el repositorio de paquetes instalables vía Composer.


En ejemplo: añadiendo Bootstrap

Vamos a verlo con un ejemplo. Supongamos que queremos añadir el framework CSS Bootstrap a nuestro proyecto Symfony. Podríamos descargarnos la librería de Bootstrap y añadirla manualmente a nuestro proyecto, pero en Symfony siempre que sea posible preferiremos hacerlo vía bundle externo. Buscando en Packagist encontramos que hay varios bundles que añaden Bootstrap a Symfony. Yo he elegido Mopa Bootstrap porque lo conozco de antes, pero además es uno de los que más descargas y mejor valoración tienen en Packagist. Visitamos la página web oficial del proyecto Mopa Bootstrap en Github y allí la sección de instalación nos indica como añadir el bundle a Symfony 2; hay que añadir el siguiente código en el archivo composer.json:

{
    "require": {
        "mopa/bootstrap-bundle": "v3.0.0-beta3",
        "twbs/bootstrap": "v3.0.0"
    }
}

Una vez hecho esto hay que ejecutar composer update desde el directorio principal del proyecto para que se actualicen las dependencias y se descarguen las librerías.

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing mopa/composer-bridge (v1.3.0)
    Downloading: 100%

  - Installing mopa/bootstrap-bundle (v3.0.0-beta3)
    Downloading: 100%

  - Installing twbs/bootstrap (v3.0.0)
    Downloading: 100%

Como podemos ver además de los dos bundles indicados nos ha instalado un tercero: mopa/composer-bridge (v1.3.0). Esto es porque Composer sabe que es necesario instalarlo o sino mopa/bootstrap-bundle (v3.0.0-beta3) no podrá funcionar. Ahora ya podemos empezar a usar Bootstrap en nuestro proyecto web. Pero, ¿Como se usa mopa/bootstrap en Symfony? Para saber eso hay que leerse la documentación.


Mini-curso de Symfony 2

  • Primeros pasos: Conceptos y definiciones sobre Symfony 2.
  • Primer proyecto: Como empezar un proyecto Symfony 2.
  • Añadiendo bundles externos: Agregar dependencias a composer.json.