Sección: php

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)

Cajetín de búsqueda de funciones PHP para Firefox

No me lo puedo creer, pero no he encontrado un motor de búsqueda que funcione para consultar las funciones de PHP desde Firefox.

El único que he encontrado (https://addons.mozilla.org/en-US/firefox/addon/8984) no sé porqué no lo puedo instalar (tengo cuenta en addons.mozilla.org).

No he sabido buscar, puede que sea un poco torpe; así que he hecho un copia-pega de uno de los que tenía instalados y retocando un par de parámetros, ya tengo el mío.
Está en esta dirección: http://davidasorey.net/static/php-manual-search.xml

Para utilizarlo, sólo hay que salvar el fichero xml en nuestro directorio “Profile”/searchplugins de Firefox y listo.

Un día de estos lo subiré a addons.mozilla.org ;-)

Comentarios

Optimizadores para PHP

Cuando uno se enfrenta con un desarrollo web que debe atender miles de visitas diarias uno de los mayores problemas es el rendimiento o la velocidad con la que se cargan las páginas.

Si el lenguaje de programación que usamos es PHP existen herramientas que aceleran en gran medida la ejecución del código. Las que más conozco son eAccelerator y XCache.

Estos optimizadores de código funcionan “precompilando” los scripts en PHP a una especie de “bytecode” que se ejecuta mucho más rápido que la interpretación directa del script. La mejora es espectacular.

He instalado eAccelerator en un servidor de producción y realmente se nota mucho el aumento de velocidad. No puedo valorar XCache ya que no lo he usado más que para hacer alguna prueba que otra.

Comentarios (2)

SimpleXML … la verdad es que sí

Últimamente trabajo mucho con PHP y de vez en cuando toca lidiar con información de terceros en XML o HTML. Con las funciones (o métodos) de SimpleXML el trabajo es sencillísimo.

SimpleXML carga un archivo XML en memoria como una estructura similar a un array. A los atributos de una etiqueta se accede con la notación de array asociativo y al contenido de un nodo con la notación ->

Ejemplo:

<libros>
<libro id="1">
<titulo>El señor de los anillos</titulo>
<autor>Tolkien</autor>
</libro>
<libro id="2">
<titulo>El fin de la infancia</titulo>
<autor>Clark</autor>
</libro>
</libros>

Parsear este XML es trivial:

<?php
$libros = simplexml_load_file('libros.xml');
foreach ($libros->libro as $libro) {
    echo sprintf("Libro nº %s: Título: %s Autor: %s",
            (string)$libro['id'],
            (string)$libro->titulo,
            (string)$libro->autor);
}
?>

El forzar la conversión de cada valor a string no es superfluo: si no se hace esto lo que obtenemos es otro objeto SimpleXML anidado al “padre” en vez del contenido del atributo o del nodo.

Otro uso posible es el parseo de HTML. Para garantizarnos que el HTML de origen está bien formado, conviene pasarle antes un tidy:

tidy -asxhtml -clean -numeric fichero.html
Comentarios

Patrones de diseño para torpes – 3ª parte

El patrón “Singleton”

Uno de los patrones de diseño más conocidos es el patrón “Singleton“. Con este patrón se garantiza que sólo hay una instancia activa de una determinada clase.

Supongamos que tenemos una base de datos y queremos mantener una única conexión activa. Otro caso puede ser una clase que se dedique a grabar registros o trazas en un fichero. Imaginemos un objeto que descarga ficheros por FTP.

En todos estos casos puede ser conveniente tener un único objeto que realice el trabajo y garantizar que no hay varias instancias, por ejemplo, para no saturar una base de datos con conexiones, o no tener accesos simultáneos al mismo fichero, etc.

En la documentación oficial de PHP se muestra un ejemplo de este patrón para este lenguaje.

Otros patrones de diseño

Por motivos profesionales, últimamente casi programo exclusivamente con PHP. En developerWorks hay un artículo muy interesante donde amplían otro artículo anterior en el que presentaban cinco patrones básicos.

Explican y ponen ejemplos en PHP para los patrones “Adapter”, “Iterator”, “Decorator”, “Delegate” y “State”. Es una lectura obligatoria para cualquier desarrollador de PHP.

Comentarios

Siguiente Página »      artículos anteriores ->