Por qué no deberíamos usar los "short tags" <? y <?=

Recientemente en una discusión en un foro uno de los tantos "expertos" que pueblan la comunidad PHP se mostraba contrario a mi explicación de qué cosas debía corregir en su código otro usuario.

Puntualmente la situación era la siguiente:

---Cita (Autor enriqueplace)---

[...]Sustituye los <?= por <?php echo, lo mismo que <? por <?php, está en desuso (por más que veas algunos ejemplos en el manual de Zend, eso es error de algún programador descarriado ;-))[...]

---Fin de Cita---


Y el usuario respondía:

"Che guru, fijate que lo que esta mal es usar el tag como "<?", pero no esta depcrecated el uso de "<?="

Chau guru."


En lo personal puedo aceptar (y me parece obvio) que desarrolladores duden y vuelvan a preguntar, pero no que contradigan sin fundamentos por el simple hecho que "ellos lo usan".

Dado que la discusión se trasladó al ámbito personal (la idea de esta persona era simplemente descalificar), nuestros aportes fueron borrados por el administrador del foro. Como considero que vale la pena la explicación sobre por qué no debemos usar los "short tags" o "etiquetas cortas" de apertura y cierre de PHP (en lo personal hace años evito esta práctica, pero he visto que algunos desarrolladores aún siguen usando).

Aquí la copia de la respuesta dada en el foro:

"Me remito al manual de PHP (que este capítulo está escrito hace mucho tiempo):

Sintaxis básica del lenguaje
http://www.php.net/manual/es/languag...ax.phpmode.php

Donde da ejemplos de todos los tags posibles para PHP, y el segundo dice:

2. <? echo ("esta es la más simple, una instrucción de procesado SGML \n"); ?>
<?= expression ?> Esto es una abreviatura de "<? echo expression ?>"


Este ejemplo hacer referencia al "formato corto de etiquetas" o "short tags", por lo cual el manual aclara:

"El método segundo no siempre está disponible. El formato corto de etiquetas está disponible con la función short_tags() (sólo PHP 3), activando el parámetro del fichero de configuración de PHP short_open_tag, o compilando PHP con la opción --enable-short-tags del comando configure. Aunque esté activa por defecto en php.ini-dist, se desaconseja el uso del formato de etiquetas corto."

Aunque esto pudiera no ser suficiente, el manual vuelve a reiterarlo un poco más abajo y ampliando otras situaciones donde además no es conveniente:

"Note: No se debe usar el formato corto de etiquetas cuando se desarrollen aplicaciones o bibliotecas con intención de redistribuirlas, o cuando se desarrolle para servidores que no están bajo nuestro control, porque puede ser que el formato corto de etiquetas no esté soportado en el servidor. Para generar código portable y redistribuíble, asegúrate de no usar el formato corto de etiquetas."

No recuerdo ahora (tampoco vale la pena buscarlo en este contexto) pero creo haber leído que en la versión 6 o 7 de PHP estos tags serán eliminados.

PD:
ahh, casi me olvido, en el manual de Zend Framework dice claramente "Short tags are never allowed" ("las etiquetas cortas nunca son permitidas"), de ahí mi expresión que "a pesar de ver ejemplos en el manual de Zend, no usarlos como excusa para decir "que no están en desuso / permitidos"".


Nota: Si se toman el tiempo para investigar un poco verán que las fuentes pueden ser contradictorias con sus sugerencias: el manual de PHP dice no usarlos, la guía de buenas prácticas del wiki de los desarrolladores de Zend Framework recomienda por un lado tampoco usarlos, pero por otro lado sí (en determinadas condiciones), y luego se pueden ver ejemplos de código en los dos sentidos (con y sin "short tags").

Claramente la respuesta válida no es "los short tags se pueden usar porque PHP lo permite usar" (de esa forma validaríamos muchas prácticas erróneas) o porque simplemente "yo lo uso hace tiempo" o porque "nunca leí nada que dijera lo contrario" (y ni siquiera han consultado el manual oficial).

En conclusión

Mi recomendación es que no uses los "short tags", usa siempre <?php y <?php echo, solo tienes que escribir unos caracteres más y usas una sintaxis que no te trae problemas en ningún contexto y es la versión "oficial" de los tags de PHP (lo otro es una abreviación).

Promoción por Febrero 2009: Libro + 25% de descuento en cursos

Luego de recibir varias sugerencias de usuarios que quieren comprar el libro y a su vez hacer un curso en marzo, me solicitaron la posibilidad de tener algún descuento, así que pasamos a la siguiente promoción: ;-)

Por cada libro que se adquiera durante Febrero 2009 obtendrán un 25% de descuento en los cursos que se iniciarán en Marzo 2009 (proporcional al valor del libro):
  1. Libro Versión Económica 30 usd -> obtienes descuento de 7,5 usd
  2. Libro Versión Estándar 50 usd -> obtienes descuento de 12,5 usd
  3. Libro Versión Extendida 60 usd -> obtienes descuento de 15 usd
Aclaraciones
  • Al contrario de promociones típicas que dicen "solo para productos nuevos", esta promoción incluye a todos los usuarios que ya han comprado el libro (obviamente no voy a dejar fuera a mis primeros lectores ;-)).
  • Los descuentos se aplican por persona y por libro, no es transferible, y solo para los cursos que inician en Marzo 2009.
  • Si se adquiere más de un curso, el descuento de mantiene para cada curso, por ejemplo: Libro Extendido, 15 usd de descuento para el curso de Análisis y otros 15 de descuento para el de Zend (obviamente, estás pagando por un libro y 2 cursos).
  • Para empresas / grupos / organizaciones, estudiaré caso a caso en base a la cantidad de usuarios, me envían un email y lo analizo.
Recordatorio: solo por Febrero 2009 y para los cursos que inician en Marzo 2009, el descuento no se transfiere para otros períodos.

Próximamente más novedades ;-)

¡Disponible el libro: "POO para PHP5"! (actualizado)


Bueno, luego de revisarlo una y otra vez (y otra vez) ya se encuentra terminada la primer versión del libro que junta toda la experiencia acumulada en todos los cursos dictados a la fecha (tanto a distancia como presenciales).

Breve resumen del temario incluido
  • Introducción a los conceptos
  • Cómo pensar en objetos
  • Diagramas UML
  • Todas las Relaciones entre los Objetos
  • Traducción de UML a Código y viceversa.
  • Múltiples ejercicios con sus soluciones, aplicando los conceptos vistos.
  • Cómo desarrollar una clase de Persistencia, Paquetes, Arquitectura en 3 capas, Polimorfismo, uso de Interfaces, Programación Orientada a la Implementación versus Programación Orientada a la Interfaz, etc.
  • Se agregan nuevos capítulos sobre Paquetes y Manejo de Excepciones.

En la actualidad el libro consta de 22 capítulos y 265 páginas.

Libro + Servicio = Valor Agregado

Si decides adquirir el producto completo podrás tener acceso a un servicio personalizado a través de usuarios.surforce.com y por el período de tiempo que elijas obtendrás:

  1. Poder hacer consultas directas al autor: cualquier parte del libro, tanto dudas sobre ejemplos, capítulos, ejercicios, etc. Estas se responderán normalmente durante las próximas 24-48hs (aunque lo más probable que obtengas una respuesta en pocas horas).
  2. Acceso a todos los fuentes (php, uml, etc): generalmente en un libro se destaca el código principal de una solución o ejemplo y no se escriben páginas y páginas con todo el código ya que se hace difícil de leer y seguir. Por lo tanto queda disponible todo el código original de los ejemplos completos de todos los ejercicios del libro, revisados y comentados.
  3. Actualizaciones Mensuales: tanto correcciones como ejemplos o hasta capítulos nuevos, lo que podrá incluir a futuro acceso a material multimedia (screencasts, podcasts, etc).
  4. Cambiar el Contenido del Libro: si consideras que algún capítulo, ejemplo o ejercicio podría mejorarse, o algún tema que ves no se encuentra tratado en el libro, tu sugerencia será recibida y tenida en cuenta para la próxima actualización mensual del libro.

A quién va dirigido el libro
  1. A todo desarrollador de PHP que quiera aprender de manera sólida todos los conceptos de la POO bajo la última versión PHP5.
  2. Alumnos de los cursos que quieren tener el último material revisado y ampliado.
  3. Futuros alumnos del curso de POO que quieren tener un material de lectura antes de iniciar las clases (cada año se renuevan los ejercicios que hay que resolver semanalmente).
  4. Quienes no tienen tiempo suficiente para realizar un curso a distancia por espacio de 2 meses seguidos y quieren seguir su propio ritmo como si tuvieran un docente para hacerle consultas.

Costo del Libro Digital

El libro es el mismo, se entrega la última versión vigente del libro (pdf), pero difiere el período de tiempo de soporte del autor, recibir actualizaciones y "material extra" (todo accediendo a usuarios.surforce.com).
  1. Versión Económica - 2 meses de servicios: 30 usd
  2. Versión Estándar - 4 meses de servicios: 50 usd
  3. Versión Extendida - 6 meses de servicios: 60 usd
Cada versión asegura por lo menos 1 actualización por mes de nuevas versiones del libro (correcciones, nuevos capítulos, material extra, screencasts, etc), acceso a todo el código fuente y respuestas a todas las dudas que puedan surgir en su lectura.

Más que un libro, es un servicio que busca transmitir "conocimientos y experiencia" y aumentar su alcance "un poco más allá de lo tradicional".

Forma de Pago & Entrega

De la misma forma que hemos hecho con los cursos / talleres a distancia, a través de giros por Paypal o por Western Union, dentro de las siguientes 24hs se hace la entrega de la última versión vigente del libro (pdf) y en aproximadamente 48hs se habilita el acceso al sistema usuarios.surforce.com (la demora se debe a cambios en el sistema que estoy implementando en estos días).

Capítulo de ejemplo


Si deseas hacer una consulta, envía un email a: libros@surforce.com

Si deseas adquirir el libro, envía un email a: ventas@surforce.com

Todas las dudas o sugerencias, tanto en los comentarios de este post como en el email, bienvenidas ;-)

En una horas: Libro Digital sobre "POO para PHP5"



En unas horas queda disponible para su compra mi primer libro digital, que incluirá además un conjunto de servicios: entre ellos, poder hacer consultas de cualquier tema del libro con respuesta directa del autor, actualizaciones mensuales, etc.

Capítulo de ejemplo


En un rato más novedades. ;-)

Disponible la primera versión de SURFORCE-CORE

La idea es tal cual se cuenta en el sitio oficial de Code Google, el proyecto SURFORCE-CORE busca compartir algo de experiencia con respecto a intentar trabajar en varios proyectos con Zend y busca, más que aumentar la productividad, no perderla... ¿pero cómo?


Con los proyectos conjuntos de SURFORCE-BASE, SURFORCE-LIBRARY y SURFORCE-MODULES se buscó tener de alguna forma una "arquitectura" común para aprovechar en cada nuevo proyecto. Evolucionando la idea original, SURFORCE-CORE sustituye a SURFORCE-BASE, este último funcionaba como un template que permitía usarlo como "base" pero luego lo modificábamos y tendríamos uno distinto para cada nuevo proyecto.

Ahora, con "CORE", la idea es usar siempre el mismo, como una aplicación que irá mejorando, y que tendrá todas las funcionalidades básicas para sistemas simples y repetitivos, como CMS o Admin's, y que posteriormente se diferenciarán no en el CORE (que es el mismo), sino, en su configuración y en sus módulos.

Esta primera versión resuelve varios problemas que surgieron durante el desarrollo de distintos proyectos:
  1. A diferencia de BASE, que todo partía de la raíz del proyecto, ahora el "document root" para el servidor Apache es solo el directorio "html" y el resto de la aplicación queda oculto en un nivel no accesible desde el exterior (seguridad, configuración sugerida por Zend).
  2. El CORE puede ser igual, pero los módulos deben poder ser dinámicos: generalmente todos los bootstrap (index.php) de sistemas ZF incluyen varias líneas "a fuego" donde se especifica la ruta donde encontrar los controllers para cada módulo. Esto fue sustituido por una carga dinámica donde obtiene la lista de módulos a partir del config.ini (archivo que será siempre distinto según el proyecto).
  3. Diferenciación de ambientes Desarrollo / Producción: como bien supo enseñarnos sistemas como Ruby On Rails, ahora se crean por lo menos dos ambientes, uno de desarrollo y otro de producción, con distintas configuraciones de bases de datos y distintos niveles de mensajes de error (por ejemplo, en producción no se envían a pantalla mensajes de error).
  4. Mayor configuración a partir del config.ini: definición de flags como debug (para habilitar rutinas de mayor detalle en los logs), ambiente de desarrollo (poder diferenciar distintas bases de datos), id de aplicación (poder contar con una única tabla de menú para posibilitar un menú dinámico a partir del id de aplicación), módulo de arranque por defecto, timezone, etc.
  5. El módulo "default" contendrá toda la información común para todos los proyectos: el layout por defecto, models genéricos (como el manejo de usuarios de la aplicación, etc), login a la aplicación, administración de los usuarios, etc.
  6. Carga dinámica de porciones de css y javascripts por controller: en la práctica me he dado cuenta que uno o más javascripts para todo el sitio era -en la mayoría de los casos- poco flexible (principalmente trabajando en un equipo de varios desarrolladores). Por consiguiente se agregó la posibilidad que por cada controller el layout busque un archivo con el mismo nombre del controller en ejecución pero con extensión .js y/o .css, permitiendo trabajar más libres de tener que mantener una nomenclatura común para absolutamente todo el sitio y estar cargando con funciones o estética que solo se aplican en controllers específicos (evitar que se repitan nombres de funciones, id's, etc).
  7. Se agregan cuadros de mensajes genéricos para el sistema: lo cual permiten enviar al usuario mensajes de información, alertas, etc, con un simple div, que a su vez se puede animar con jQuery para poder capturar la atención del usuario.
Hay que recordar que CORE nos permite tener un mismo sistema genérico para aprovechar entre varios sistemas similares que pueden a su vez estar en distintos servidores y que podrán ser adaptados con la simple configuración de su .ini y la carga de información en las tablas correspondientes. Posteriormente solo nos preocuparemos de crear módulos e instalarlos en el CORE correspondiente, con la ventaja de poder mover el módulo entre sistemas y continuar trabajando.

En resumen

Creo que se ha hecho un avance interesante que puede beneficiarnos a todos, tener una estructura genérica que resuelva los problemas comunes que encontramos a la hora de crear aplicaciones muy similares, y con simple configuración o creación de módulos poder cambiar su comportamiento y ser más productivos.

Destaco lo "simple", sin entrar en grandes extensiones complejas de código, con un poco de creatividad bien aplicada se pueden obtener beneficios sustanciales en la productividad de un equipo de trabajo.

En los próximos días iré agregando más información y tal vez hasta un screencasts contando un ejemplo completo de instalación y prueba.

PD: están todos invitados a participar en el foro de discusión y colaborar con su desarrollo.

Reglas básicas para trabajar con clases bajo PHP (actualizado)

Discutiendo sobre el tema en un foro hice el siguiente resumen básico de cómo deberíamos trabajar con clases bajo PHP:
  1. Una clase debe estar en un solo archivo/fichero, y el nombre del archivo/fichero debe ser el mismo que el nombre de la clase. Por ej, "Cliente.php" y la clase internamente debe llamarse "Cliente", en "ningún caso" [1] los nombres deben diferir (simil Java).
  2. Cada clase debe manejar su relación con otras clases de forma independiente de las clases con las cuales interactúa: para que una clase sea consistente esta debe saber a qué clases llamar para poder trabajar, sin importar que otra clase con la que debe relacionarse comparta una misma relación. A pesar que PHP permita colocar todos los include/require a las clases en un archivo centralizado (como muchas veces se hace en "index.php") , debemos evitarlo. Lo único que logramos es que la clase sea inconsistente en otro contexto al fallar porque ella no sabe resolver sus relaciones (imaginemos que una de esas clases no se usará en index.php, por lo tanto no estará la lista de include/require de clases que necesita para poder funcionar).
  3. En la relación entre las clases debes usar require_once, lo que resuelve si dos clases que se relacionan entre sí dependen a su vez de la misma clase, por consiguiente solo se invoca una vez, y seguimos manteniendo la independencia de la clase, ya que si nos llevamos una de esas clases a otro contexto, esta seguirá funcionando correctamente y permitirá el reuso normal de la misma sin dar ningún tipo de error de "clase ya requerida" (si usas solo include o require, no puedes llamar dos veces a la misma clase, por eso existen include_once y require_once).
  4. En un mismo contexto, nunca redefinir la misma clase, ya que pierde consistencia el diseño del sistema. Por ej, en un sistema contable tener una clase Cliente que según la clase que la llame puedan "reescribir" internamente la clase para que su diseño sea distinto a la clase original. Una clase debe ser única en un mismo sistema, no puede ser que existan dos versiones de la implementación de una misma clase.
  5. Anexo: debemos usar todos el mismo estándar de codificación (Zend)
Originado a partir de una consulta en un foro: "¿Redeclarar un clase?"

Notas complementarias

  • [1] - Estamos hablando de lo básico de POO para PHP, particularmente este punto puede variar como lo hace trabajar con una herramienta como Zend Framework, ya que PHP no encuentra por sí solo la ubicación física de una clase usan la "artimaña" de colocar en su nombre la ruta para llegar a ella. Esta práctica no es un "estándar" y debería en algún momento caer en desuso si se implementa correctamente el manejo de "namespace" en alguna versión futura de PHP. Pero volvemos al principio, con esta práctica el nombre de la clase queda distorsionado, ya que ahora, además del nombre está la ruta para llegar a la clase y esto es solo por un tema de la incapacidad de PHP y no tiene nada que ver con la POO (gracias GeL/T0 por tus valiosos comentarios ;-))

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".

Entradas populares