lunes, 10 de junio de 2013

PHP. Cambio de codificación a UTF8

Migrando un sitio a UTF-8, he tenido que convertir todos los ficheros desde iso-8859-1. Para ello he usado un programa que lo hace automáticamente para un directorio especificado.
Lo curioso del tema, es que una vez hecha la migración, me he encontrado con este warning de PHP que aparentemente no parecía guardar ninguna relación:
PHP Warning:  Cannot modify header information - headers already sent
cuando intentaba hacer un session_start()

Lógicamente, toda la información que se encuentra acerca de este problema va en la línea de que se haga el session_start al principio del script y que no se devuelva ningún carácter al navegador antes.

El problema ha venido de la conversión a UTF8, el programa ha metido una marca en el fichero que se envía antes, y causa dicho error. Se trata de una Marca de Orden de bytes (conocido como BOM character), véase http://es.wikipedia.org/wiki/Marca_de_orden_de_bytes_(BOM)

La solución pasa por revisar si el programa que hemos usado permite no meter dicho BOM. Una vez quitados dichos caracteres, el problema ha desaparecido.

Por si a alguien le resulta de interés, para convertir las páginas en windows he usado el UTFCast (en el que puede configurarse que no incluya dicho BOM).
Y para quitar el caracter BOM de ficheros ya convertidos, he usado el "File BOM Detector".
Es importante señalar que editores como el notepad de windows, meten dicho carácter siempre que se guarda un fichero como utf8.

miércoles, 5 de junio de 2013

Llamadas Ajax en paralelo con PHP

Trabajando con llamadas Ajax de jQuery y con el AjaxSubmit de jquery.forms, me he encontrado con que aunque las llamadas son asíncronas, cuando se realizan muchas simultáneamente, se comporta como si se estuvieran encolando en lugar de realizarse en paralelo. Y el tiempo de respuesta de cada llamada va siendo el sumatorio de cada una de las llamadas (para procesos lentos esto es crítico).

El error ha sido pensar que había algún tipo de problema con jQuery o relacionado con javascript, porque ha resultado ser algo evidente, pero relacionado con PHP y el uso de las sesiones.
Al usar sesiones, si PHP trata de ejecutar en paralelo varios scripts que hacen uso de la misma sesión, cabe el riesgo de que se sobrescriban, por lo que cuando está usando una sesión, la bloquea y el resto de scripts deben esperar a que se libere para empezar su trabajo.

Una vez identificado el problema es tan sencillo de solucionar como liberar la sesión una vez que nuestro script no va escribir en ella con la función session_write_close().
Lo recomendable por tanto es intentar juntar lo máximo posible en nuestro script el uso de sesiones y abrirla, operar sobre ellas y desbloquearlas lo más rápido posible. O incluso desbloquearlas al principio si no vamos a escribir en ellas.