Corregir errores `ereg is deprecated` en PHP 5.3

Desde principios de noviembre del año pasado (2010/11/10) tenemos ya disponible RedHat 6 (seguimos esperando por CentOS 6) que trae PHP 5.3.2, serie (5.3.x) con la cual ya hemos estado trabajando en nuestras plataformas de desarrollo (Fedora) desde hace poco más de un año, justamente para buscar estar preparados para los casos que ya hemos empezado a experimentar:

He actualizado mi servidor Linux (de RedHat/CentOS 5 a RedHat/CentOS 6) y al menos una de mis aplicaciones web (basada en PHP) ha dejado de funcionar mostrándome errores del tipo `Function ereg() is deprecated`.

La explicación es simple, como fue anunciado con anticipación (los logs de versiones previas de PHP ya mostraban un mensaje indicando la futura depreciación de las funciones tipo `ereg`) estas funciones fueron retiradas para siempre en PHP 5.3. Una de las razones principales para esta decisión es que eran mucho más lentas y su sintaxis menos familiar que las alternativas Funciones PCRE.

Afortunadamente la solución es también simple, aunque puede resultar demorada y tediosa, dependiendo de qué tan extensivamente se usaron las Funciones (que han sido depreciadas) de expresiones regulares POSIX dentro de la aplicación. Veamos entonces la solución, revisando independientemente cada una de las funciones depreciadas de uso más común:

Migrando ereg():

ereg('\.([^\.]*$)', $this->filename, $extension);

reemplazarla por:

preg_match('/\.([^\.]*$)/', $this->filename, $extension);

Nótese que he encerrado el patrón de coincidencia \.([^\.]*$) entre / / (slashes), mismos que son delimitadores de patrón. Si el patrón contuviera slashes (una URL por ejemplo) entonces quizás quieras usar el delimitador # (sharp) en lugar del slash.

Migrando eregi():

Siguiendo la lógica seguramente buscaríamos la función pregi_match(), que debería ser la versión no sensible a mayúsculas/minúsculas de preg_match(). Sin embargo no existe nada parecido, pues en su lugar se trabaja con los modificadores de expresión regular. Básicamente para volver a preg_match insensible a mayúsculas/minúsculas deberemos anexar la i luego del delimitador de patrón. Entonces, para cambiar:

eregi('\.([^\.]*$)', $this->filename, $extension);

reemplazarla por:

preg_match('/\.([^\.]*$)/i', $this->filename, $extension);

Migrando ereg_replace():

$this->filename = ereg_replace('[^A-Za-z0-9_]', '', $this->filename);

Reemplazarla por:

$this->filename = preg_replace('/[^A-Za-z0-9_]/', '', $this->filename);

Nuevamente, sólo agregué los slashes como delimitadores al patrón.

Migrando eregi_replace():

Nuevamente aplicamos la i como modificador de expresión regular, al igual que en el caso de eregi() explicado anteriormente:

$this->filename = eregi_replace('[^A-Za-z0-9_]', '', $this->filename);

Reemplazarla por:

$this->filename = preg_replace('/[^A-Za-z0-9_]/i', '', $this->filename);

Con lo cual se han cubierto los cambios necesarios en las Funciones de Expresiones Regulares POSIX de uso más frecuente. La filosofía se mantiene intacta para el resto de funciones no detalladas aquí pero que pertenecen a la misma librería como split() y spliti().

Finalmente, aprovecho para hacer notar que éste es sólo uno de los cambios/mejoras que pueden provocarte problemas al actualizar la versión del SO y/o de PHP. Sin embargo como ya te imaginarás, no es el único, y otro de los que se presentarán con regular frecuencia es que por defecto en PHP 5.3 ya no se soportan los short open tags para iniciar código PHP, es decir si al inicio (o en cualquier parte) de uno de tus scripts PHP estaba algo como esto:

// Código de ejemplo de short Open Tag
<?
  $pi = 3.1416;
  // Más código aquí
  // y más aún acá

Deberás reemplazar <? por el tag completo que es <?php así:

// Código de ejemplo del Open Tag completo
<?php
  $pi = 3.1416;
  // Más código aquí
  // y más aún acá

Si experimentas problemas adicionales a los indicados, sería excelente que los comentes aquí para completar el artículo con sus respectivas soluciones!

Suerte!