Migrar de PHP4 a PHP5

25 Julio, 2007

Dado que ya tiene fecha para el funeral nuestro querido PHP4 me decidí a migrar el servidor a PHP5. La instalación se hizo en un par de minutos gracias a la colaboración de Debian y Aptitude. PHP5 viene con el soporte para MySQL desactivado así que había que activarlo en php.ini

Llegaba el momento de comprobar el resultado, todas las webs iban bien menos una (siempre tiene que haber alguien para joder la marrana), daba problemas con los Warnings. Según parece PHP4 viene con estos avisos desactivados mientras que PHP5 si los muestra. La solución era fácil, editar el php.ini.

Después de esto y algunos pequeños cambios más en el archivo de configuración (a gusto del consumidor) la migración ha sido un éxito, supongo que en parte porque casi todas las webs se basan en scripts precocinados y preparados para PHP5 aunque el único problema seria con los TAGS de PHP.

Hosting web con soporte PHP5

Recientemente he actualizado mi distribución debian (unstable) y ahora al ejecutar cualquier script php siempre aparece el siguiente error:

PHP Warning: mime_magic: type search/400 \\input text/x-tex invalid in Unknown on line 0
PHP Warning: mime_magic: type search/400 \\section text/x-tex invalid in Unknown on line 0
PHP Warning: mime_magic: type search/400 \\setlength text/x-tex invalid in Unknown on line 0
PHP Warning: mime_magic: type search/400 \\documentstyle text/x-tex invalid in Unknown on line 0
PHP Warning: mime_magic: type search/400 \\chapter text/x-tex invalid in Unknown on line 0
PHP Warning: mime_magic: type search/400 \\documentclass text/x-tex invalid in Unknown on line 0
PHP Warning: mime_magic: type regex [Cc]onstant[[:space:]]+[Ss]torytext/x-inform invalid in Unknown on line 0

La solución es bien sencilla, hay que ir al fichero /usr/share/file/magic.mime y comentar las siguientes líneas (ponerle un # delante):

#0 search/400 \\input text/x-tex
#0 search/400 \\section text/x-tex
#0 search/400 \\setlength text/x-tex
#0 search/400 \\documentstyle text/x-tex
#0 search/400 \\chapter text/x-tex
#0 search/400 \\documentclass text/x-tex

Y esta:

#0 regex [Cc]onstant[[:space:]]+[Ss]tory text/x-inform

Una vez guardado el archivo ya no ocurrirá más.

Me pareció realmente interesante el artículo de Geoff Howland, fundador de Lupine Games, que opina, en resumidas cuentas, que para aprender a hacer juegos hay que hacer juegos, ni más ni menos. Aparte de aprender a programar, hay que programar videojuegos, pero no querer programar un Quake, un World of Warcraft o un Need For Speed, hay que empezar por lo sencillo. Empieza haciendo juegos sencillos que te permitan empezar a adentrarte en los conceptos del arte de crear videojuegos.

El autor recomienda empezar haciendo un Tetris, seguidamente un Breakout, un Pac-Man, un juego con scroll tipo Super Mario, etc. No soy ningún experto en desarrollo de videojuegos, de hecho mi experienca es mínima, pero estoy totalmente de acuerdo con este camino. Para tu primer juego, será mucho más fácil de alcanzar un juego tipo Tetris que no un Half Life, marcarse un objetivo razonable hará que sea más fácil llegar a un juego aceptable, jugable y que además te habrá permitido aprender muchos conceptos básicos. En el Tetris por ejemplo puedes aprender lo que es el bucle principal del juego, los casos especiales (selección de opciones, final del juego, etc). Cada juego te aportará un nivel más de experiencia, un peldaño más hacia la cima del desarrollador de videojuegos.

El artículo puede leerse completo en GameDev.

Si alguna vez has tenido que desarrollar alguna aplicación web con gran cantidad de código JavaScript seguro que te has encontrado con algún error. Seguramente te habrás dado cuenta de que en esos casos IE no es tu mejor aliado. Los mensajes de error que genera el IE son bastante malos en mi opinión, en algunos casos no acierta ni la línea que contiene el error.

Si en vez de IE pruebas suerte con firefox, almenos tienes una consola donde aparece un error mucho más detallado y al hacer doble click en él vas al código problemático directamente.

Pero aún así, esto se puede mejorar muchísimo, gracias a firebug, una extensión de firefox que permite ver errores de javascript detalladamente, ejecutar código al vuelo, ver todo el árbol DOM, añadir breakpoints, observar variables,ver las peticiones HTTP, incluso las de AJAX (esto es realmente útil) y hasta puedes ver cómo evoluciona el uso del ancho de banda que genera tu web al cargarse. También es de gran utilidad la herramienta “Inspect”, que te permite mediante el ratón seleccionar un área de la web y visualizar instantaneamente el código referente a ella. Otra característica a destacar es que puedes editar CSS al vuelo y se aplica instantaneamente en la web, ideal para hacer pruebas y dar espaciados, cambiar colores, tamaños, etc.

Te recomiendo que la pruebes, es totalmente libre y gratuita y te permitirá avanzar mucho más rápido en el desarrollo de tus páginas web.

Si no puedes desarrollar con firefox también puedes probar la versión especial de firebug para otros navegadores, incluido IE.

Firebug en PC Frikis

Sí, es cierto, lo acabo de descubrir, y luego explicaré los detalles, pero antes quiero contar qué es lo que me ha llevado a afirmar esto.

La semana pasada me tocó analizar junto a un compañero un código JavaScript que no funcionaba correctamente, utilizaba arrays asociativos para almacenar distintas categorías, por ejemplo:

var paises = new Array();
paises['es'] = ‘España’;
paises['pt'] = ‘Portugal’;
paises['us'] = ‘Estados Unidos’;
paises['uk'] = ‘Reino Unido’;

Hasta aquí, todo parece normal, es un array asociativo, como clave guardo el código del país y como valor el nombre, igual que lo haría en PHP por ejemplo. Pero luego, al intentar ordenarlo con opciones.sort(); que supuestamente ordena el array, no funcionaba, ni siquiera pasándole como parámetro una función personalizada para la ordenación (Especificación del método sort)
Supusimos que el método sort() no soportaba arrays asociativos e implementamos la solución utilizando arrays normales y corrientes, con claves numéricas, a la vez que nos preguntábamos cómo podía ser que JavaScript tuviese esa falta tan grave.

Hoy me disponía a comentar este error y buscar una nueva implementación de sort que soportara arrays asociativos (o incluso hacerla yo mismo si no hubiese encontrado ninguna) cuando sin quererlo me he encontrado con que JavaScript no tiene arrays asociativos, no existen. Entonces, ¿Cómo es que el ejemplo anterior funciona? (Sin contar el método sort)

Funciona porque lo que estamos haciendo es añadirle propiedades al objeto de tipo Array. En JavaScript, cuando hacemos variable['nombre'] lo que ocurre es que añadimos una nueva propiedad con el nombre “nombre” al objeto “variable”. Por eso, si hacemos:

var paises = new Array();
paises['es'] = ‘España’;
paises['pt'] = ‘Portugal’;
paises['us'] = ‘Estados Unidos’;
paises['uk'] = ‘Reino Unido’;
alert(paises.length);

Si existiesen los arrays asociativos debería aparecer una ventanita con un 4 ¿verdad? Pues como no existen, sale un 0, porque no le estamos añadiendo valores al array, si no propiedades al objeto.

Otros hechos que hacen sospechar de que JavaScript no tiene soporte para arrays asociativos es que no hay forma de definir un array asociativo ni con el constructor del objeto Array ni con la sintaxis para crear un array de forma literal.

Me he sorprendido mucho al leer esto en http://www.andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/ , pues llevo años viendo como en muchos tutoriales explican equívocamente cómo utilizar arrays asociativos en JavaScript, tal y como yo lo he hecho.

¿Te imaginas poder bajar, instalar, organizar y por supuesto, ejecutar todas las aplicaciones desde un mismo gestor? ¿Te imaginas poder modificar el código fuente de tu aplicación favorita en un instante y volver a ejecutarla con facilidad? Y además de todo esto, ¿Que pueda funcionar en cualquier plataforma?
Aunque en realidad no es todo tan bonito, y el dicho gestor ya está disponible en las distribuciones de Linux (apt, synaptic, yum), algo que se acerca bastante a la idea inicial es Gnope.

Sí, con Gnope puedes bajar, instalar, organizar y lanzar aplicaciones hechas en PHP-GTK. Con Gnope también puedes modificar el código fuente de la aplicación que te bajes, puesto que es PHP, volver a ejecutar la aplicación modificada y disfrutar de los cambios. Entonces, ¿Qué es lo que falla en Gnope? Pues la calidad. Tanto del gestor de aplicaciones como de las aplicaciones disponibles. En el instalador aparacen fallos durante la instalación (en la consola que se abre, aunque no afectan a la instalación, según parece) y luego, las aplicaciones que hay disponibles, además de ser pocas, son de baja calidad/utilidad y por supuesto, el hecho de que son interpretadas hace que las aplicaciones sean mucho más lentas de lo habitual.

Eso sí, hay que tener en cuenta que Gnope tiene poco más de 1 año de vida y es posible que en un futuro empecemos a ver aplicaciones útiles y más depuradas.

Si sueles programar en PHP y te interesa realizar aplicaciones “de sobremesa” con tu lenguaje favorito te recomiendo que eches un vistazo a la web de Gnope y la de PHP-GTK.

Gnope, instalador de PHP-GTK

Es algo obvio, trivial, para mi y para cualquiera, si un sonido se puede reproducir, también se podrá copiar, si un vídeo se puede reproducir, también se podrá copiar, si un disco con un determinado software se puede leer, también se podrá copiar.

¿Por qué siguen gastando ingentes cantidades de dinero para intentar hacer algo que es imposible, por pura lógica?

Esto viene de las últimas noticias que estoy leyendo, sobre la copia de las primeras películas HD-DVD, la copia de los juegos de Wii y Game Cube y por supuesto, también los de Sony (PS3). Lo mejor de todo es cómo lo han hecho, con un mínimo esfuerzo, almenos en los casos de los juegos de Sony y en los HD-DVD, que son los que más me he informado.

Resulta que puedes copiar un juego de PS3 simplemente instalando Linux y utilizando el conocido comando dd de forma habitual, lo cual es de risa. Millones invertidos en buscar métodos para que los discos no puedan ser copiados para que luego, con un simple comando, que cualquier usuario medio de Linux conoce, se puedan copiar.

Con el HD-DVD pasa algo parecido, una gran cantidad de recursos se ha invertido para desarrollar el AACS para que luego, un usuario indignado por no poder reproducir correctamente su película en su monitor, al no disponer de HDCP (sí, quieren proteger hasta las conexiones), se ponga a investigar y logre copiar la película directamente en su disco duro utilizando un pequeño programa en Java (y algo de maña en buscar las claves que decodifica un reproductor oficial, en memoria). Además, todo el trabajo de conseguir la clave de la película se lo hace un programa reproductor de HD-DVD. Lo cual también es bastante obvio, en algún punto, el programa necesitará trabajar con la clave de decodificación y la guardará en memoria, la cual podrá ser investigada con un debugger. Por lo tanto, es inútil tanta encriptación, en algún momento, algún aparato o software, tendrá que decodificar la película y ese aparato o software será manipulable.
Al fin y al cabo, lo único que se consigue poniendo todas estas trabas es que el usuario final, el que compra la película, acabe teniendo un producto de menor calidad que el que puede conseguir bajándose de internet, libre de sistemas anti copia, que podrá reproducir dónde más le guste y convertirlo al formato que prefiera, para poder ver su peli favorita incluso en su reproductor de vídeo portátil o hasta en el móvil.

Cada vez me encuentro con más casos en los que necesito escribir caracteres especiales, más allá de la eñe (Ñ), las tildes u otros caracteres habituales entre la mayoría de europeos occidentales (ç, à, ê, å, etc). El verdadero problema llega cuando necesitas escribir en otros idomas como ruso, árabe, chino, japonés, polaco, etc, o como mínimo, hacer tu web/aplicación compatible con estos juegos de caracteres.

El problema tiene fácil solución, se llama utf-8, un juego de caracteres especial que utiliza de 1 a 4 bytes por caracter, según sea necesario y es compatible con los canales de transmisión de 8bits. Es decir, que podemos enviar un texto con caracteres de múltiples culturas a la vez, utilizando los canales habituales, mail, web, irc, ftp, etc.
Lo único que queda por saber es cómo convertir documentos de texto que tengamos en iso-8859-15 (el juego de caracteres habitual en españa) a utf-8. Esta tarea la podemos realizar utilizando el comando “iconv” en linux (o bajando la misma aplicación en versión para Windows) y ejecutando el siguiente comando:

iconv documento.txt -f iso-8859-15 -t utf8 -o documento-utf.txt
documento.txt es el nombre del fichero que queremos convertir, -f iso-8859-15 es la codificación actual del fichero, -t utf8 es la codificación de destino y -o documento-utf.txt es el fichero dónde el programa escribirá el resultado.

Este comando me ha resultado especialmente útil para convertir algunas de mis páginas web a utf8. Por cierto, esta web usa utf-8.

Si eres un habitual desarrollador de aplicaciones web te habrás encontrar alguna web con el problema del botón de “Atrás”, esa flecha apuntando hacia la izquierda que encontramos en cualquier navegador web. Resulta que si has realizado dos peticiones POST seguidas al volver atrás el navegador te indicará que la página ha caducado o bien nos preguntará si queremos reenviar los datos. En este punto la mayoría de usuarios, que obviamente no son desarrolladores y no entienden cómo funciona esto, se pierden. No saben si volver a enviar los datos, si seguir tirando para atrás, si volver adelante (donde se encontrarán lo mismo) o cerrar directamente la página, pensando que la página falla.

¿Solución? Ajax

Sí, esa mezcla de JavaScript y otro lenguaje de servidor como PHP, ASP, Ruby; es una buena solución para evitar este problema, ya que la petición se hace en el fondo (background) y no altera la ruta de navegación, por lo que podemos volver atrás y adelante sin problemas haciéndole la vida más fácil al usuario. Además, como estamos hablando de formularios, no nos tendremos que preocupar por si los motores de búsqueda indexan o no ese contenido ya que, de todas formas, los “crawlers” no envían formularios.

En muchos servidores de host PHP-MySQL, algunos incluso de pago, no se permite la conexión remota a MySQL por cuestiones de seguridad. Normalmente esto no es un problema ya que la base de datos accedemos desde el propio espacio web y no se necesita la conexión remota.

Pero en otros casos sí puede ser necesario. Tengo un script que recoge datos de varias webs alojadas en distintos servidores y algunos no permiten la conexión remota a MySQL así que tuve que hacer un pequeño wrapper en PHP, muy sencillo, para salir del paso.

Se trata de un script que recoge los parámetros de conexión, una consulta SQL, la serializa, la codifica en base64 y la envía.

$link = mysql_connect("localhost",$_GET['user'],$_GET['pass']);
mysql_select_db($_GET['db'],$link);
$result = mysql_query(base64_decode($_GET['query']),$link);
$output = array();
while($row = @mysql_fetch_assoc($result)) { $output[] = $row; }
echo base64_encode(serialize($output));

Este archivo se situa en el servidor que no permite el acceso remoto a MySQL. Luego para leer estos datos en el servidor que desea acceder remotamente utilizamos este script:

$query = "SELECT * FROM table";
$url = "http://www.remoto.com/wrapper.php?";
$url .= "user=usuariomysql";
$url .= "&pass=passmysql";
$url .= "&db=dbmysql&query=";
$url .= base64_encode($query);
$fp = fopen($url,'r');
$read = '';
while(!feof($fp)) { $read .= fgets($fp); }
fclose($fp);
$read = unserialize(base64_decode($read));

Y si se protege la url http://www.remoto.com/wrapper.php con contraseña mejor todavía.