Sección: programación

Algunos fallos tontos en el desarrollo web con PHP

¿A qué desarrollador web no le ha pasado alguna vez tener algo que no funciona, probar mil cosas y luego darse cuenta que era un error o fallo trivial? Para tirarse de los pelos, ¿verdad? Voy a relatar algunos.

  • ¿Por qué no entra por el if?
    Este es típico: un if que controla una sóla condición. Ejemplo en PHP, pero aplicable a cualquier lenguaje -excepto Python :-)

    loQueSea();
    if ($varControl)
        hazAlgo();
    otraCosa();

    Al cabo de un rato piensas que  si entra por el if, además debes cambiar otra variable y escribes:

    loQueSea();
    if ($varControl)
        hazAlgo();
        $otraVarControl = true;
    otraCosa();

    Y nunca consigues que otraVarControl se quede a true. ¿Qué pasa aquí? Fácil: no hemos puesto llaves al if.
    Conclusión: aunque el if sólo controle una sentencia, mejor con llaves siempre. Al final siempre va a haber más de una sentencia bajo ese if:

    loQueSea();
    if ($varControl) {
       hazAlgo();
       $otraVarControl = true;
    }
    otraCosa();
  • ¡No pilla los cambios!
    Es la típica llamada de un cliente (o un jefe): ¡me has dicho que cambiaste el XXX y no lo veo, sigue como antes!
    Nuestro XXX puede ser un fichero .js, un .css, una imagen o cualquier otro tipo de recurso que estamos seguros que hemos actualizado y que aún así, nos dicen que no lo ven.
    A los desarrolladores web no nos gustan mucho las cachés, ni proxies, etc, y además nos conocemos todos los típicos trucos para hacer un refresco completo de la página, pero nuestros jefes, clientes y usuarios sí que utilizan cachés (en el navegador, en su proxy). Además no se saben esos “mágicos” atajos de teclado que utilizamos sistemáticamente (Ctrl-Shift-R, Ctrl-F5 en IE) para ver cómo va nuestro trabajo en el navegador.
    Solución: forzar el refresco. Supongamos el siguiente HTML que incluye un .js sobre el cual hemos hecho cambios importantes:
    <html>
    <head>
    <script src=”fichero.js” type=”text/javascript”></script>

    Subimos el fichero actualizado al hosting o servidor de producción, hacemos la llamada o enviamos el correo de rigor (”oye, ya está hecho”) y al rato tenemos el típico “yo lo veo como antes”.
    Nuestro fallo: presuponer que el entorno del usuario es el mismo que el nuestro. Puede que esté navegando a través de un proxy (suelen guardar en caché los elementos que le solicitan), su navegador puede estar configurado para que también “cacheé” algunos recursos, etc.
    La solución más fácil es añadir un “query string” a la llamada al recurso. Esto nos garantiza que será tratado como un fichero diferente y cargado de nuevo:
    <html>
    <head>
    <script src=”fichero.js?version=1″ type=”text/javascript”></script>


    Nos da igual cuál es esta “query string”, simplemente lo que queremos es que todos los proxies, navegadores y demás clientes entiendan que es un recurso diferente. Este truco es válido para CSS, imágenes, swf. Por ejemplo, en la regla CSS:

    div.cabecera {background-image: http://mi.servidor.com/img/fondo.png?r=1}

    Si se tiene todo el trabajo integrado en un sistema de control de versiones, es muy útil configurar nuestro “deploy” para que este “parámetro” tome siempre el número de versión. Si estamos desarrollando la aplicación todavía, el truco infalible para que el navegador siempre lea los recursos como “nuevos” es hacer las llamadas así en nuestro fichero .php:

    <html>
    <head>
    <script src=”fichero.js?version=<? echo time() ?>” type=”text/javascript”></script>
    <link href=”fichero.css?version=<? echo time() ?>”  rel=”stylesheet” type=”text/css” />

  • Página en blanco, no se ve nada. ¿Qué falla?
    Este típico error suele pasar cuando PHP está configurado para no mostrar ningún error (lo más recomendable en producción). Las soluciones son dos:

    • Editar el php.ini y cambiar el ajuste “display_errors” (nada recomendable).
    • Escribir la siguiente instrucción para saltarnos este ajuste para un “script” en concreto:
      <?php
          ini_set('display_errors', 1);
          // Sigue nuestro script

      La función ini_set() permite ajustar parámetros de configuración para un script determinado. Es muy útil cuando algo falla y no vemos dónde.

  • Los usuarios de mi aplicación no pueden hacer “login”, o unos acceden al perfil del otro.
    Este es un error bastante insidioso y puede tener diferentes orígenes. Hay que conocer cómo maneja PHP las sesiones: PHP asigna al usuario una ‘cookie’ única con el identificador de sesión. En el servidor se guardan ficheros de sesiones en un directorio, un fichero para cada sesión ‘asignada’ a un usuario. Problemas potenciales:

    • El usuario no está aceptando cookies: en este caso es imposible que PHP asocie una sesión y sus datos con un usuario. Se puede configurar para que PHP mande el identificador de sesión en la URL, pero no es nada recomendable. Se puede comprobar si el usuario acepta cookies intentando enviarle una y leyéndola a continuación. Si no la tenemos, sacamos una advertencia al usuario.
    • El directorio del servidor donde se guardan las cookies no está accesible (problemas de permisos, falta de espacio, etc).
    • Si tenemos una configuración con balanceo de carga (varios servidores atendiendo a la misma URL) tenemos que asegurarnos que una vez que un usuario ‘entra’ por un servidor, sigue siempre en el mismo servidor. Otra solución es guardar las sesiones en una base de datos en vez de almacenarlas como ficheros.

Hay muchísimos más fallos tontos que nos podemos encontrar, pero éstas son algunas de las que más tiempo me han hecho perder ;-)

Comentarios (3)

Selectores CSS: la intersección entre diseño y programación

El uso de selectores CSS en los “frameworks” para JavaScript más conocidos ha permitido lo que hace unos años era impensable: los diseñadores entienden el código de los programadores y los programadores pueden comprender el CSS de los diseñadores.

jQuery es especialmente adecuado: no distingue entre selectores “por id” ni selectores por “clase” (Prototype tiene dos funciones diferentes, $() y $$(), para estas tareas).

$('.lateral a.externo').click(function(ev) {
    // Código  a ejecutar
})

Este sencillo código es fácil de entender y un diseñador al verlo rápidamente intuye que en todos los tags A dentro de la “capa” lateral que tengan la clase externo se hará algo al hacer click.

.lateral a.externo {color: red; padding: 5px; margin: 0;}

Este fragmento de CSS afecta a los mismos elementos que el javascript anterior. Un desarrollador enseguida ve también a qué elementos afecta.

Lo bueno es que si el diseñador y el programador hablan en el mismo lenguaje (selectores CSS), el desarrollo es muy fácil y se puede trabajar en paralelo fácilmente.

Comentarios

Firefox, mucho más que un navegador

Por eso cada vez lo utilizo menos como navegador (en favor de otros) pero cada vez más como herramienta de desarrollo web. Mi sesión de trabajo suele comenzar abriendo Firefox, el editor que esté utilizando en ese momento (no me acabo de decidir entre jEdit y Komodo Edit) y otro navegador (Opera o Safari, dependiendo del sitio -trabajo o casa-) para consultar el correo, documentación, etc.

Una de mis herramientas principales de trabajo, hoy por hoy, es Firebug. Sobre esta extensión se han construido algunas extensiones más para Firefox muy útiles como Firefinder (encuentra nodos en el DOM mediante consultas XPath o selectores CSS),  YSlow, (monitoriza la carga de las páginas) o FirePHP (ayuda en la depuración de scripts PHP escribiendo en la consola de Firebug). Otras extensiones que me resultan muy útiles para el desarrollo web son Web Developer y, recientemente, Tamper Data.

Si utilizo Firefox, es por Firebug. Así de simple. Como navegador de uso diario no me acaba de gustar: me parece demasiado pesado.

Comentarios (1)

Desarrollando aplicaciones para dispositivos móviles: vuelta al pasado

Parecía que la idea de estandarizar los desarrollos y las plataformas ya estaba asentada, que todo el mundo tenía claro que el desarrollo “cross-platform” era preferible a tener que lidiar con distintos sistemas, dispositivos, APISs y demas.

Pero no. De un tiempo a esta parte, con la creciente implantación de los “smartphones”, estamos volviendo atrás en este aspecto. En estos momentos ya tenemos unas cinco plataformas a las que atender si queremos desarrollar aplicaciones para móviles (seguro que me dejo alguna en el tintero):

Cada plataforma utiliza sus propias herramientas, APIs y lenguajes. Así no hay manera.

Parece que se pretende excluir a los desarrolladores “amateurs” del mercado de vendedores de aplicaciones o que estos se decanten por una plataforma en exclusiva.

Personalmente me sentía muy tentado por empezar a programar algunas cosillas para móviles, pero esta situación me desanima mucho. La única forma que me parece asumible es usar el mínimo común múltiplo, J2ME, y no estoy seguro de que todas las plataformas lo acepten, aparte del propio lío de “configurations” y “profiles” de J2ME.

Comentarios

Las elecciones desde el punto de vista informático

Pasada la resaca electoral, les voy a contar un poco por encima cómo trabajamos y lo que hacemos cuando hay elecciones.

Lo habitual es contactar unas semanas antes con el organismo responsable y solicitar una acreditación. En las elecciones que hemos cubierto hasta ahora (Generales 2009, Galicia y País Vasco 2009) el mecanismo ha sido similar: el organismo nos facilita una página web de acceso restringido desde la cual podemos descargar los ficheros con los datos de los recuentos.

Por lo general, antes del día “D” se ofrece una simulación con datos de prueba para que los medios podamos comprobar que nuestros desarrollos funcionan.

El formato de los datos no es estándar, cada organismo ofrece el que mejor le parece. En las pasadas elecciones generales se nos ofrecían un fichero de texto (comprimido) con los datos del recuento a nivel estatal, autonómico y provincial y otro conjunto de ficheros (también comprimidos) con el desglose del recuento por municipios.

Con antelación se nos facilitó la documentación sobre el formato de estos ficheros (por ejemplo: campo 1, tres posiciones, código del municipio; campo 2, dos posiciones, provincia; ….; campo n, código del partido, campo n+1, votos, …)

Por fortuna, en las elecciones gallegas han utilizado un sistema informático similar, que emitía ficheros de datos muy parecidos, así que gran parte del trabajo ya lo teníamos hecho. Variaba la forma de desglosar: a nivel autonómico, provincial, comarcal y por municipios.

El Gobierno Vasco facilitaba los datos en un fichero XML único, en el cual también se desglosaban los datos a nivel autonómico, provincial y por municipios.

Una vez que hemos escrito el programa o “script” que analiza estos ficheros de datos, lo más conveniente es guardarlos en una base de datos relacional y escribir las consultas contra esta base de datos.

Como los ficheros de datos se van actualizando cada poco tiempo, lo más práctico es dejar que la computadora haga ella sóla el trabajo. En el caso de los datos del País Vasco, la dirección y nombre del fichero de datos ha sido toda la noche la misma, con lo que pudimos dejar un “script” corriendo cada minuto mientras pedíamos una pizza.

Los ficheros de datos del recuento en Galicia cambiaban de nombre cada vez que se actualizaba el recuento. Esto nos obligó a hacer un poco de trabajo manual, aunque lo teníamos también “semi-automatizado”: llamábamos a un “script” pasándole el nombre de fichero de datos y se disparaba la actualización.

Por otra parte, en la página web se iba mostrando una especie de “marcador” con los datos parciales, el porcentaje escrutado, etc. Obviamente, estos datos provenían de nuestra base de datos, pero no podíamos arriesgarnos a que cada página vista disparase una consulta a la base de datos: saturaríamos los (ya bastante congestionados) servidores rápidamente.

La solución que adoptamos fue la siguiente: un “script” generaba un fragmento de HTML (haciendo las pertinentes consultas) cada 30 segundos, lo escribía en un fichero y lo que la página web mostraba era este HTML “precompilado”. Bueno, bonito y barato ;-) Por otra parte, el lunes por la mañana, previendo que íbamos a tener muchas consultas para buscar municipios, resultados por comarcas, etc, en las páginas de resultados, decidimos “cachear” o guardar los resultados de las consultas, ya que estaba todo escrutado. De esta forma nos ahorramos muchas consultas a la base de datos, que suele ser el cuello de botella de las aplicaciones web.

Si usted busca los resultados electorales de su pueblo y la página tarda un poco en mostrarle los resultados, está de enhorabuena: es usted la primera persona que busca los resultados de este municipio, y, además, los siguientes usuarios que busquen los resultados de este mismo sitio tendrán una respuesta mucho más rápida.

Espero que les haya interesado esta entrada. Si quieren que les cuente algo más, dejen un comentario. Contestaré lo que mejor pueda.

Comentarios (3)

Siguiente Página »      artículos anteriores ->