25 de julio de 2011
Tras asistir al evento Desymfony en Castellón a principios de julio, llegué a casa con pilas cargadas para aprender tecnologías que allí se habían mostrado. Quedé encantado con Silex, Git, jQuery Mobile, cómo no con Symfony2, etc. Lástima que uno siempre anda mal de tiempo como para ponerse a aprender tanta cosa, así que me vino a la cabeza el hecho de crear una aplicación pequeña (donde Silex vendría de maravilla), ubicarla en Github (Así podría aprender lo básico de Git) y haciendo uso de HTML5. Con esto mataba varios pájaros de un tiro.
En este post, básicamente voy a hablar de Silex, que para quien no lo conozca se trata de un micro framework creado en PHP y basado en Symfony2 (silex-project.org), del que @nacmartin nos dio una maravillosa charla con la que creo que todos quedamos encantados.
[Requerimientos en instalación]
Al igual que Symfony2, Silex corre a partir de la versión 5.3 de PHP y ciertas extensiones pueden tener requerimiento de librerías que por defecto no vienen compiladas en el core de PHP. Un ejemplo de esto es la extensión Session, que hasta hace poco requería de la clase Locale de la librería Intl y digo hasta hace poco porque esta dependencia se hizo opcional y ahora, previamente a invocar la clase Locale, se mira si ésta existe o no.
La instalación es sencilla y se puede hacer de varias formas: bien vía git mediante su repositorio en https://github.com/fabpot/silex (que requerirá de una posterior compilación) o bien descargando el fichero ya compilado en formato phar. Yo particularmente me descargué el phar y lo he ido actualizando mediante consola con el simple compando php silex.phar update. Con esto, la instalación está terminada.
[Funcionamiento, servicios y extensiones]
Siguiendo con la sencillez característica de Silex, para declarar éste y hacerlo funcionar solo es necesario cargarlo desde un fichero php e instanciarlo de esta forma:
require_once __DIR__.'/silex.phar';
$app = new Silex\Application();
// Your code here.
$app->run();
Sin entrar en detalles de cómo funciona Silex y todo lo que se puede hacer con este micro framework (que para eso está su fantástica documentación), voy a mostrar las extensiones que yo he necesitado y los servicios que me he creado. Antes de nada, ¿qué es una extensión? ¿Qué es un servicio? ¿Y cuál es la diferencia entre ambos?
Un servicio en Silex es un recurso de tipos variables, objetos, etc. Que gracias al contenedor de servicios de Silex, siempre estará disponible. Ejemplo:
$app[‘my_service.host’] = ‘172.0.0.1’;
$app[‘my_service.connection’] = function() use ( $app )
{
return new \MyConnectionClass( $app[‘my_service.host’] );
}
// Usage.
$app['my_service.connection']->connect();
En este ejemplo podemos ver cómo se hace uso de dos características inexistentes en PHP hasta la versión 5.3: funciones anónimas y clousures, de ahí que Silex requiera esta versión de PHP como mínimo.
Una extensión se puede ver como una librería externa que puede ser registrada y usada por Silex. Ya hay algunas extensiones que están preparadas para ser cargadas, como son DoctrineExtension, SessionExtension o TwigExtension. Creo que con estas tres ya cubrimos gran parte de las necesidades que una aplicación de tamaño pequeño puede tener.
$app->register(new MyLibrary\SomeExtension(), array(
'config.host' => '127.0.0.1',
));
En este código, obviamente no se aprecian diferencias notables, pero mi intención no es la de documentar Silex (qué ya lo está y de forma increíble) sino la de comentar mi primera toma de contacto con el micro framework. Lógicamente, existen diferencias entre servicios y extensiones y voy a comentar de forma rápida cómo las veo yo:
[Aplicación Real]
Muy bien, hasta aquí todo muy bonito, pero ¿Cómo es una aplicación real? Voy a contar qué estoy haciendo en mi caso: como eran varias tecnologías las que iba a probar a la vez ¿por qué no añadir alguna más? ¿Por qué no hacer pruebas con alguna API y sistemas REST como el de Twitter? Pues si, estaría bien :) Manos a la obra.
Si se trata de una aplicación que va a usar la API de Twitter, requeriré de algún sistema de persistencia para el Singin, nada mejor que usar la extensión SessionExtension para empezar. Además, qué menos que usar un sistema de plantilla ¿no? Twig! Ya hay para empezar a divertirme.
require_once ( __DIR__ . '/silex.phar' );
require_once ( __DIR__ . '/vendor/twig/lib/lib/Twig/Autoloader.php' );
Twig_Autoloader::register();
$app = new Silex\Application();
$app->register( new Silex\Extension\SessionExtension() );
$app->register( new Silex\Extension\TwigExtension(), array(
'twig.path' => ( __DIR__ . '/views' ),
'twig.class_path' => ( __DIR__ . '/vendor/twig/lib' )
));
Aquí se puede ver como SessionExtension no se carga previamente, a diferencia de Twig que ha de ser descargado, incluido y además require hacer una llamada al register del autoloader. Esto es debido a que Silex se compila con Session pero no con Twig. Es algo que eché de menos en la documentación de Silex.
Lo siguiente es ver que para realizar las peticiones hacia la api de Twitter voy a necesitar tres escenarios distintos como mínimo:
Por lo cual, ya podemos crear la primera versión del routing
$app->get( '/', function() use ( $app ) {} );
$app->get( '/twitter-signin', function() use ( $app ) {} );
$app->get( '/receive-response-twitter', function() use ( $app ) {} );
Lo último que queda es usar alguna librería OAuth adaptada a Twitter, pero además habría que encapsularlo con un adapter que se sitúe entre mi aplicación y la librería OAuth. Qué mejor que crear un servicio de Silex que contenga este adapter y así probar cómo funcionan los servicios también.
require_once ( __DIR__ . '/vendor/adapter/twitter/lib/TwitterAuthAdapter.class.php' );
$app['twitter.customer_key'] = 'fakecustomerkey';
$app['twitter.user_password'] = 'fakepassword';
$app['twitter.callback_url'] = 'fakecallback';
$app['twitter'] = $app->share( function() use ( $app )
{
return new Twitter\TwitterAuthAdapter ( $app['twitter.customer_key'], $app['twitter.user_password'] );
});
Además del adapter habrá que crear el modelo que se encargue de ejecutar la lógica de negocio (por poco que sea) de la que consta esta aplicación y por último crear el routing para las acciones, que en mi caso son dos.
[Resumiendo]
Hasta ahora tengo:
Mmmmm, empiezo a ver algo… ¿Estoy intentando emular un MVC? Parece que sí y ha sido de forma inconsciente, simplemente aplicando la organización que desde hace años he estado usando. Aparte, el index.php empieza a crecer de una forma considerable ya que contiene toda la inicialización de Silex, sus extensiones, mis servicios pero además, el enrutamiento y toda la lógica de aplicación. Creo que he llegado a un punto, me estoy contestando a esa pregunta que siempre tenemos presente y que hicieron en la charla de @nacmartin, ¿Cuándo debemos usar un micro-framework y cuándo un framework?
Pues mi opinión al respecto, es la siguiente: cuando las necesidades de tu aplicación no crecen más allá de un par de plantillas que requieren algo de dinamismo, o bien se necesita procesar y almacenar (o enviar por email) los datos de un formulario o proveer de algún tipo de servicio web (REST o xml), tu herramienta es un micro-framework, tu herramienta es Silex.
Si necesitas más lógica (tanto de aplicación como de negocio), si necesitas crear una estructura organizativa porque tienes un número de ficheros considerables, si necesitas ceñirte al patrón MVC, si tu index.php empieza a ser poco mantenible, necesitas un framework, pero si tu aplicación es demasiado grande para ser creada con Silex pero no lo suficiente para usar Symfony2, prueba otras opciones, existen frameworks MVC en PHP más livianos que Symfony2 y se podrían ajustar seguramente mejor a tus necesidades.
Como digo, es mi opinión :-)
Para acabar, comentar que, para cumplir con su cometido, Silex está muy bien pensado, muy bien hecho y es una gozada usarlo, lo recomiendo totalmente. Siempre y cuando tu aplicación no exceda en cuanto a complejidad ;-)
En breve haré público el repositorio con la aplicación que estoy haciendo para probar Silex, además, tengo pensado ponerla en producción también.
[Actualización]
Os dejo el enlace con el repo en Github: https://github.com/aramirez-es/Compare-follows
[Actualización 23 agosto]
La web está en producción en el siguiente dominio: http://www.comparefollows.com
Enlaces interesantes:
Tags: Conferencias | Silex | Symfony2