Ejemplo de excepciones desde Zend Framework

Siguiendo con el post anterior sobre el tema, quería mostrarles otro ejemplo de cómo se manejan las excepciones desde Zend Framework, donde la diferencia principal radica en que obtenemos una lista enorme de clases preestablecidas para el manejo de excepciones (como sucede en lenguajes como Java), lo que nos permite usarlas de forma directa sin tener que implementar nada más que el try/catch.


try{

$this->view->clientes = Models_Clientes::getAll();

}catch(Zend_Db_Statement_Exception $e){

$this->view->mensajeError =
'Se ha producido un error interno al intentar recuperar datos.'
.' Por favor envíe un email a sistemas@surforce.com' ;

}catch(Zend_Db_Adapter_Exception $e){

$this->view->mensajeError =
'Se ha producido un error al conectar a la base de datos.'
.' Por favor reintente en unos minutos';

}catch(Zend_Exception $e){

$this->view->mensajeError =
'Se ha producido un error inesperado.'
.' Por favor reintente en unos minutos';
}

$this->render ();


Repasando: las excepciones deben ordenarse como si fueran reglas de un firewall, la regla más específica debe ir al principio y la más general al final (ya que si lo hacemos al revés siempre entrarán por la primer coincidencia en la regla).

Con Zend_Db_Statement_Exception entrarán todas las fallas que ocurran por errores de sintaxis en el ejecución de sentencias SQL (error bastante grave), en el segundo caso con Zend_Db_Adapter_Exception cualquier falla en la conexión al motor de base de datos y en el último, ya una excepción genérica como Zend_Exception, capturamos cualquier otro error que no pudimos especificar con detalle (algo así como la "pantalla azul de la muerte" de Windows ;-)).

Si no agregamos este try / catch en el momento de la falla enviará directamente en pantalla todo el "volcado" de la Excepción y concluirá la ejecución de la aplicación de forma abrupta.

Pero, si además de esto agregamos en la vista un código como el siguiente, podremos enviar un mensaje al usuario sin distorsionar la interfaz de nuestra aplicación.

En este ejemplo, el código para desplegar el mensaje de error se encuentra en el layout de la aplicación:

< ?php if(!is_null($this->mensajeError)): ?>
< ?php echo $this->mensajeError ?>
< ?php endif ?>

Y con un poco más de trabajo, puede quedar más estético y hasta con una animación (moviendo lateralmente el cuadro un par de veces, como para alertar al usuario) y se vería de esta forma:


Las excepciones son la única forma de tener un manejo uniforme de errores (algo que tienen todos los lenguajes POO modernos) y poder controlar mejor cómo responder a situaciones no esperadas y que nuestra interfaz no quede "desarmada" delante del usuario, lo cual podríamos hasta definir en la configuración que cada vez que ocurra un "error general" envíe un email al departamento de sistemas con todos los datos para poder analizar el fallo ni bien sucede.

¿Y ustedes, usan excepciones? ¿qué otras ideas han aprovechado para implementar y mejorar la funcionalidad de nuestros sistemas?

Último post del blog

(Suspendido Brasil, feliz Día de los Inocentes ;-))

... por razones de índole laboral voy a cambiar de país de residencia (nuevamente, no hace un año que nos vinimos de Uruguay a Argentina) y voy a cambiar de tecnología: me paso completamente a Java, más concretamente JEE.

Saludos, sepan disculpar, voy a estar bastante ocupado con la mudanza (vender todo nuevamente para irnos a Brasil), así que hasta la vista! (alguien más llenará este vacío, seguro).

"Rendimiento: ¿conviene utilizar POO?"

Ayer enviaron la siguiente consulta a un foro, lo cual generó que escribiera esta respuesta que casi se me convirtió en un post y para no perderla, lo dejo documentado aquí con links de referencia y un poco más actualizado su contenido:

Consulta:
"Buenas a todos. Hace unos meses me comencé a meter de lleno con php. Después tuve que dejar otro tiempo más porque me surgieron proyectos en otras plataformas, y ahora estoy retomando para hacer un proyecto personal en php.

Me surgieron algunas dudas con respecto a la verdadera utilidad, en relación al rendimiento, de la programación orientada a objetos en php. Si bien no conozco como trabaja internamente php, es un lenguaje interpretado, es decir, que en cada carga o recarga de la página las clases en cuestión deben ser interpretadas una y otra vez.

¿Es más ineficiente interpretar una clase, que interpretar una secuencia de comandos? ¿Alguien conoce de esta interna?. En .Net las clases son compiladas una vez que fueron solicitadas, por lo tanto, con cargas o recargas posteriores solo resta usarlas tranquilamente, ya que sabemos que ya ha pasado por esa etapa previamente.

Solo me estoy enfocando en el rendimiento de la aplicación. Si lo analizamos desde otro punto de vista, de seguro que encontramos muchas más ventajas a la programación orientada a objetos que a la programación procedimental.
Espero que alguien me oriente un poco en esto."


El moderador y amigo GatorV le responde:

"Es mínimo el impacto, si a caso lo que es más es la memoria ram que llegue a consumir, aunque no es nada que impacte, ya que el compilador de PHP esta muy optimizado para evitar desperdiciar memoria.

Por otro lado si te importa un poco el tema de estar re-interpretando las clases, una vez que termines puedes usar Zend Optimizer para guardar solamente las clases en estado compilado, y asi eliminar el overhead de estar interpretando y ejecutando".


Mi respuesta (actualizada):

"Tus comentarios (completamente justificados) me hacen acordar a los mitos de la "optimización extrema" en PHP, algo que veo sí completamente injustificado.

La forma en que se hace las pruebas es generalmente muy fuera de la realidad, como hacer un loop de millones de registros para luego contar las milésimas de segundo entre usar un echo o un print.

El peor mal que podemos tener en la ingeniería de software es ir hacia la "optimización temprana" (varios [1], [2], [3], etc, sin descontar que el lenguaje PHP sigue evolucionando y siendo optimizado), es decir, preocuparnos tempranamente del rendimiento y no de la funcionalidad o el diseño de un sistema.

La parte que no se llega a entender es que ya pasamos la época de hacer páginas PHP embebidas con HTML y conexiones SQL, actualmente los proyectos requieren SISTEMAS, y estos poder escalar y desarrollar rápidamente de acuerdo a las necesidades del mercado.

¿Cuanto cuesta modificar un producto web que no es un sistema? ¿cuanto nos cuesta desarrollar funcionalidades nuevas?

Si no tienes diseño, si no aplicamos metodologías que incluyan POO, dudo seriamente que podamos estar aptos de desarrollar un sistema "medio" para arriba.

Pero eso de "no uses require_once porque es caro", "echo es más rápido que print" ó "print es más rápido que echo" (he visto artículos sobre "optimización extrema" que dicen lo contrario entre ellos), "usa ++$i en vez de $i++", etcétera, las considero completamente tontas e inútiles.

Podemos discutir que si tienes POO + Persistencia (BD), es seguro tendrás más consultas a la base de datos que si hicieras un JOIN y luego recuperaras los datos y procesaras, pero hay muchas técnicas para evitar esto, como el "lazy loading", evitando tener que consultar todas las veces por un mismo valor a la base de datos si ya lo tienes la primera vez, o evitar consultas SQL innecesarias por valores que perfectamente pueden estar en un array ya que no cambian (o en un archivo plano, luego lo puedes actualizar, etc), etc.

Siempre hay que tener en cuenta la escala del sistema, si es para 10 usuarios concurrentes, no me molestes con estas tonterías. ;-)

Pero puedes estar tranquilo, el problema no pasa por usar puramente POO, el problema para por otros lados, la latencia se estudia desde que el usuario ejecuta una acción y recorre todos los servicios y servidores hasta que el sistema responde, no es solo PHP.

PD: ahora me acuerdo que hace rato que quiero escribir un artículo sobre "lazy loading" ;-)


¿Tú qué opinas de la "optimización extrema"? ¿Crees en ella? ¿y de la "optimización temprana"? ¿te tomas el tiempo de verificar si realmente generan algún tipo de beneficios? ¿cómo optimizas tus sistemas? ¿cómo los diseñas?

Ejemplo de excepciones: "enviar un SMS"

Hace unos meses terminamos una aplicación de "trivias" (sistema de preguntas y respuestas) para celulares donde toda comunicación con el sistema se da a través de mensajes SMS.

Estimo que para sorpresa de muchos, está desarrollada enteramente en PHP5 + MySQL5, y se implementó un sistema en 3 capas para controlar toda la complejidad del sistema (que no era "trivial", el sistema está siendo usado para una campaña que aparece en televisión, publicidad impresa, web, etc e involucra marcas muy importantes, con un flujo enorme de usuarios participando lo que genera millones de mensajes).

Sé que en el mundo PHP no estamos tan acostumbrados a usar ni interfaces ni excepciones, así que me pareció oportuno comentar unos ejemplos extremadamente simples que pueden clarificar los beneficios de su uso.

Nuestra aplicación, como toda que trabaje con mensajes SMS, tiene un límite de 160 caracteres por mensaje, y para nuestro sistema, desbordar ese límite significa que existirán caracteres que se perderán (no es opcional enviar dos SMS en esa situación, el mensaje tiene que llegar al usuario en un solo SMS).

Por lo tanto, para la integridad de la aplicación debe poder saber en el mismo momento si ocurre esta situación "anómala" y tratar de resolverla de alguna forma.

A modo de ejemplo teórico
supongamos que nuestro sistema recupera de forma dinámica dos cadenas de texto, la primera es la presentación de la pregunta de la trivia (información de puntos, mensaje de aliento que se extrae de cientos de frases diferentes, etc) y la segunda parte será la pregunta en sí misma (nuevamente, una tabla con miles de preguntas que se obtienen al azar).

Definimos como regla que si ambas cadenas superan los 160 caracteres estamos delante de un problema "excepcional" que debemos resolver
, ya que -como comentamos anteriormente- no es solución ni cortar el mensaje, ni enviarlo en dos SMS o matar la aplicación y enviar información de log (ya que estamos en producción y el sistema tiene que responder al usuario a toda costa).

Determinamos que lo más importante es enviar la pregunta de la trivia y no tanto si una pregunta no llega con su primer parte informativa (se asume que la pregunta siguiente no entrará en una situación "excepcional"), por lo tanto podríamos hacer algo tan simple como:



/* [código del sistema] */

$informacion = $trivia->getMensajeInformativo();
$pregunta = $mensaje->getPreguntaSiguiente();

try{

Sms::enviar(
$informacion . $pregunta
);

}catch(Exception $e){

Sms::enviar(
$pregunta,
Sms::ENVIO_FORZADO
);

}


Lo que está entre medio de las llaves "try" es el código que puede fallar, dentro del envío de SMS revisa el tamaño del texto y si supera los 160 caracteres envía una excepción de esta forma (y de paso genera un log para poder tener registro de estas situaciones anómalas y solucionarlas a futuro):



/* [código del sistema] */

if(strlen($mensaje) > MAXIMO_TEXTO){

$error = 'Fallo grave, no pudo enviarse el SMS!';

Log::errorLog(__FILE__,__LINE__,$error);

throw new Exception($error);

}


El método enviar de Sms retorna una excepción, es capturada en un nivel más arriba y pasa a ejecutar un plan alternativo, enviar el mensaje SMS con solo la pregunta (fundamental para el juego de la trivia) y a su vez, en caso que pudiera ocurrir algún otro problema, activa una "bandera" de ENVIO_FORZADO (envía sin importar si tiene que cortar el texto).

Un punto interesante a tener en cuenta es el uso de constantes en la propia clase como para que ella misma "auto-documente" sus opciones posibles, ya que estoy ejecutando el método de la clase Sms pero a su vez uso la clase Sms para que me diga cuales son las opciones posibles y no tengo que estar recordando y/o investigando el código interno para colocar "números mágicos" del tipo 0,1,2,3, etc.


class Sms
{
const ENVIO_FORZADO = true;
const ENVIO_NORMAL = false;

/* [código de la clase] */
}


Nota: en este punto es importante destacar la función de un buen IDE, como podría ser Netbeans, que al teclear Sms:: nos mostrará toda la lista de opciones disponibles, entre ellas, las constantes.

También hay que tener en cuenta que es una situación "teórica" y a modo de ejemplo, ya que habría que implementar un sistema que controle los tamaños posibles de ambas frases, que la suma no supere 160 caracteres, si lo hace, que vuelva a solicitar una de las dos frases, etc. Para este ejemplo nos concentramos desde el punto de vista del enviador de mensajes, ya que a pesar que se hagan distintos controles para el mismo tema en cada capa, este tema igual lo tiene que poder contemplar la clase Sms.

Este ejemplo se puede profundizar, agregando distintos tipos de excepciones para cada tipo de error y solo forzar cuando es un error genérico, así "hilar más fino" y tratar de controlar la situación "excepcional".

Empezando con Zend Framework 1.7 + jQuery + ZendX


Por un tema de carga de trabajo no había podido entrar a experimentar con la versión beta de Zend Framework 1.7, pero el tiempo me ha ganado y ahora ya es estable y oficial, así que vamos a optar (en la empresa donde estoy trabajando actualmente) por armar la nueva plataforma de desarrollo con esta última versión (hicimos sistemas nuevos muy especializados, pero la idea ahora es tirar todos los sistemas "legacy" y empezar a reusar absolutamente todo lo que se haga).

Estamos tomando como base la idea inicial de SURFORCE y armando una estructura "CORE" (lo que era antes SURFORCE-BASE) que contendrá la nueva disposición de directorios según la documentación de Zend (como por ejemplo el directorio "html" fuera del acceso al resto de la aplicación), posteriormente los módulos generales de la aplicación (SURFORCE-MODULES) y una librería general del proyecto (lo que era antes SURFORCE-LIBRARY).

La filosofía que mantenemos, al igual que con los proyectos de SURFORCE, es seguir al máximo el aprovechamiento del Framework, si este -por ejemplo- sugiere usar Dojo, usaremos esta herramienta (así con todo).

Para empezar, tuvimos que ajustar el plan gracias al poco tiempo que teníamos para hacer las primeras entregas de funcionalidad de la nueva plataforma, así que optamos por una opción alternativa (dada la complejidad y nuestra falta de experiencia en Dojo buscamos bajar riesgos para no atrasarnos) y elegir en primera instancia jQuery (que también tiene integración con el framework, pero en menor medida).

Por lo tanto tuvimos que instalar, además de Zend como librería, ZendX, ya que ahí se encuentran todos los view helpers para jQuery.

Si quieres bajarlo, debes hacer un checkout con el svn en la url:

http://framework.zend.com/svn/framework/extras/trunk/library/ZendX/

Posteriormente, si quieres tener acceso tradicional a la liberería jQuery (invocarla directamente como un javascripts) puedes hacer uso de Google AJAX Libraries API, sin necesidad de instalar ninguna de ellas físicamente, accediendo de forma remota de esta manera:

En tu HEAD:
Y Zend Framework ya trae la última versión 1.7, por lo tanto haciendo update a la url del proyecto es suficiente.

En los próximos días actualizaré los proyectos de SURFORCE con estas mejoras para que sea de provecho para todos los que quieran iniciar con Zend Framework sin tanta dificultad.

"El Tao del Codificador"


Hay una frase que dice "menos no siempre es más, es menos" ;-)


A veces los "programadores" piensan que "el mejor código" (en terminos de calidad) es el que menos líneas ocupan, pero, el "desarrollador" sabe que es todo lo contrario, usará todas las líneas extras necesarias para clarificar y facilitar seguir el rastro de lo que se quiso hacer.


No se olviden, pasamos la mayor parte del tiempo manteniendo sistemas y trabajando en equipos con más personas, por lo que debemos codificar no pensando en uno mismo, sino, en los demás.


PD: la evidencia más clara que una línea no es buena es cuando necesitas agregar una o más líneas de comentarios para dejar una explicación de cómo funciona. El código de alta calidad se explica solo, sin necesidad de comentarios.





Ese es el Tao ;-)



Taller POO/PHP5: Lunes pasado finalizó el Grupo 2


Lamentablemente vengo un poco desbordado de trabajo y este post debería haber salido el lunes 17/11, sepan disculpar ;-)

El lunes pasado cerramos el Grupo 2, donde participaron 22 alumnos y fueron 9 alumnos los que sobrevivieron a todas las instancias del taller. Quiero destacar los que sacaron más puntos en el último y más complicado ejercicio: Pedro Del Moral, Federico Grochal y Alejandro Bovino.




Nuevamente, gracias a todos por participar y felicitaciones por el esfuerzo :-)

Taller POO/PHP5: ¡luego de 2 meses, ayer finalizó el primer grupo!

En este "simple pero emotivo acto", copio el comunicado que envié hoy a la madrugada al "Grupo 1" del taller.

"Estimados todos, alumnos del "Grupo 1":

Luego de muchas demoras, aún medio solucionado el tema del hosting y los problemas con el servidor, ya está disponible en el sitio la corrección general y a su vez el código de ejemplo en un .rar para que puedan bajarlo y probarlo.

A modo de homenaje y felicitaciones, el ejemplo de la solución de la última tarea está basado en el trabajo de los 3 alumnos que más puntos sacaron: Omar Lerma, Alfredo Alonso y Agustín Garassino

Los 7 alumnos de 20 cumplieron completamente todas las etapas para llegar al final del taller (8 semanas = 8 tareas) recibirán un último "premio" que se los estaré comunicando "personalmente" por email.

Al resto, gracias por participar, sé que muchos quedaron por el camino por razones de fuerza mayor (la mayoría por temas de trabajo), espero de todas formas ver en el futuro inmediato una forma que puedan retomar lo hecho hasta el momento y darle un cierre final (tal vez un examen).

Doy por concluido el dictado de este grupo del taller, el foro quedará abierto durante esta semana para hacer las consultas pertinentes sobre esta última corrección (o alguna duda pendiente de las anteriores), y podrán seguir accediendo al sistema hasta aproximadamente fin de año, donde cerraré el acceso al taller por temas de seguridad y para darle espacio a otros talleres.

Un saludo y gracias a todos por participar, espero haberles dejado algunos conocimientos más sobre POO, creo fue una gran experiencia para todos, principalmente para mi guiño"

En los próximos días habrán más novedades, aún quedan activos 5 grupos y posteriormente antes de fin de año haré nuevos anuncios con respecto a nuevos talleres abordando nuevas temáticas (que los mismos usuarios han venido sugiriendo).

Saludos! :-)

Taller POO/PHP5: el próximo lunes termina el primer grupo de 5!

Es increíble que hayan pasado un poco más de dos meses y ya estamos cerrando el "Grupo 1" de 5 grupos que hemos abierto (5 para todo público y 1 exclusivo para una empresa) en esta primer experiencia de taller de capacitación originado a través de este blog y con una masividad que no me esperaba, ya que en un principio pensé que podría ser complejo llenar cupos de 20 personas, pero terminamos con:
Y este lunes estoy entregando la corrección de la última tarea del taller con alguna sorpresa más para los que llegaron hasta el último día cumpliendo con todas las etapas. Lamentablemente algunos alumnos fueron quedando por el camino por temas laborales, pero igual siguieron haciendo consultas en los foros o leyendo las correcciones a las entregas aún sin llegar a terminar las tareas semanales.

Quiero agradecer el voto de confianza de todos los participantes y que en lo personal fue un gusto hacer toda esta experiencia (que seguirán más, ya están en preparación para el año que viene) y que además nos debe dejar a todos la lección de que se puede hacer este tipo de emprendimientos de "educación a distancia" (reales, no las estafas que abundan por Internet) y que -a pesar de lo que digan muchos "emprendedores"- las personas de "habla hispana" sí pagan por un taller a distancia, lo hagan con tarjeta de crédito o por giro directo, esto no ocurre "solo en EEUU" (como me llegaron a repetir varias veces argumentando que no iba a encontrar a nadie que pagara).

Vendrán nuevos post, tengo uno pendiente que haré al final del último grupo contando toda la experiencia y mis conclusiones, y vendrán nuevos talleres, que ya están "en la cocina", y alguna sorpresa más ;-)

Nuevamente, gracias a todos, gracias por su confianza y espero haberles dejado a todos "muchos más conocimientos sobre POO en PHP5" que al principio de iniciar, y espero, no quede en el olvido y lo apliquen en sus desarrollos diarios y que sigan investigando.

"PHP es más que programar estructurado embebido a HTML"

Gracias y saludos a todos! aún quedan varios grupos por concluir de aquí a fin de año! ;-)

Últimas horas para inscribirse al Grupo 5 del Taller POO/PHP5

Al momento ya hay 13 personas activas en el Grupo 5 del taller, por lo tanto quedan 7 lugares disponibles (como tope para que el grupo no se desborde) y lo recomendable es que si alguien más quiere inscribirse lo haga entre hoy y el fin de semana, ya que se encuentran disponibles todos los materiales de la semana y la letra para la nueva tarea que tiene como plazo de entrega el martes 4/10 a las 23:55.

Si quieres inscribirte el lunes ya te diría que estarás sobre la fecha y tendrás riesgo de atrasarte con la semana siguiente.

Último llamadooooo..... ;-)

Entradas populares