Antes de migrar sistema PHP antiguo: inventario y mapa
La primera etapa no lleva ni una línea de código nuevo. En PHP puro, el sistema suele ser una carpeta de archivos en la que cada uno mezcla SQL, HTML y reglas de negocio, y la URL es simplemente el nombre del archivo. Sin un mapa, cualquier estimación es una adivinanza.
Qué relevar, en este orden:
- Rutas y pantallas: cada archivo accesible por URL, quién lo usa y con qué frecuencia. Los logs del servidor web responden esto mejor que cualquier entrevista.
- Llamadas AJAX: los endpoints que jQuery invoca escondidos dentro de las pantallas.
- Tablas de la base de datos: quién lee y quién escribe en cada una, incluyendo triggers, vistas y procedimientos almacenados.
- Integraciones: pagos, correo electrónico, APIs de terceros, webhooks y tareas programadas (cron).
- Código muerto: archivos que no aparecen en los logs. Casi siempre existe una parte del sistema que nadie abre, y esa parte no se migra.
- Puntos de riesgo: todo lo que toca dinero, inventario, datos personales o reglas regulatorias.
¿Actualizar PHP primero o cambiar de framework?
Si el sistema todavía corre en una versión sin soporte, la tentación es empezar por actualizar PHP en el propio legado. Nuestra posición: haga lo mínimo necesario para correr en una versión con soporte y no deje que eso se convierta en un proyecto en sí mismo.
El motivo es práctico. En código antiguo, subir de versión suele chocar con funciones eliminadas, extensiones de base de datos obsoletas y tipos tratados con más rigor. Cada corrección es trabajo tirado a la basura si ese archivo se va a reescribir de todos modos. Actualizar la versión vale como etapa de seguridad y para poder ejecutar pruebas en un entorno actual. El resto del esfuerzo va al sistema nuevo, que ya nace en la versión actual del lenguaje.
Para ver el panorama completo de dónde encaja esta etapa, consulte nuestra guía de modernización de sistemas legados.
Pruebas de caracterización: registre el comportamiento antes de tocar nada
Un sistema legado casi nunca tiene pruebas. Y sin pruebas no se sabe si el nuevo hace lo mismo que el viejo. La salida es la prueba de caracterización: no dice lo que el sistema debería hacer, sino que registra lo que el sistema hace hoy.
Si el informe mensual redondea de una forma extraña, la prueba registra esa forma extraña. Después alguien del negocio decide si eso es un bug o una regla. Sin ese registro, la regla desaparece en la migración y nadie lo nota hasta que el cliente se queja.
En la práctica: para cada ruta prioritaria del inventario, llamamos al sistema antiguo con entradas reales (anonimizadas), guardamos la salida (JSON, fragmentos de HTML, filas grabadas en la base de datos) y después ejecutamos las mismas entradas contra el módulo nuevo, comparando. No hace falta una herramienta sofisticada; un script que haga solicitudes y compare respuestas ya resuelve mucho.
El error más común aquí es querer cubrirlo todo. Concentre el esfuerzo donde hay cálculos y dinero. Los registros simples pueden validarse con una guía manual.
Capa de convivencia: proxy por ruta y patrón strangler
La pieza central de una migración sin downtime es un punto de entrada delante de los dos sistemas. Puede ser un proxy inverso o el propio enrutador del sistema nuevo. Cada ruta apunta al legado o al nuevo, y el usuario no percibe la diferencia.
Es el patrón strangler: el sistema nuevo crece alrededor del viejo, ruta por ruta, hasta que el viejo deja de recibir tráfico y puede apagarse. No existe un día de cambio, y justamente eso es lo que elimina el riesgo.
Los puntos técnicos que suelen dar trabajo:
- Autenticación y sesión compartidas: el usuario no puede iniciar sesión dos veces. O el sistema nuevo entiende la sesión del legado, o los dos pasan a validar un mismo token. Es la primera pieza estructural, porque todo módulo nuevo depende de ella.
- Mismo dominio para los dos: evita problemas de cookies y de CORS.
- Front-end por etapas: jQuery y React conviven bien, pantalla por pantalla. Cambiar el back-end y el front de una misma pantalla en el mismo paso aumenta el riesgo; separarlos suele ser más seguro.
- Reglas duplicadas: mientras los dos existan, una corrección en el legado tiene que replicarse en el nuevo. Anótelo en una lista viva.
Migración de la base de datos y de los datos sin romper el sistema antiguo
La base de datos es el punto más peligroso porque los dos sistemas la usan al mismo tiempo. La regla que seguimos: nunca cambie el esquema y el código en el mismo paso.
En general mantenemos la base de datos tal como está al principio. El sistema nuevo lee las mismas tablas, con una capa de acceso que traduce nombres malos a algo legible. Cuando el esquema necesita cambiar, se hace por etapas: se crea la columna o tabla nueva, se escribe en los dos lugares, se migran los datos históricos, se cambia la lectura y solo al final se elimina lo antiguo, cuando el legado ya no lo usa.
El script de migración de datos debe ser repetible: ejecutarse diez veces sobre una copia de producción y dar el mismo resultado. Después, valide conteos, sumas y muestras. Aquí es donde aparecen los datos sucios: fechas inválidas, textos con codificaciones mezcladas, registros duplicados.
Cambiar de plataforma de base de datos es otro proyecto. Si puede, sepárelo de la migración de código.
En qué orden migrar los módulos
No existe un orden universal, pero hay criterios que funcionan:
- Primero, un módulo pequeño, visible y de bajo riesgo, como un informe o un registro auxiliar. El objetivo es probar la capa de convivencia, el deploy y el rollback, no entregar valor de negocio.
- Después, la autenticación, si aún no está resuelta, porque todo depende de ella.
- A continuación, los módulos que más duelen: los que más cambian, los que más errores dan, los que más retrasan al equipo.
- Los módulos muy acoplados migran juntos. Separarlos a la fuerza genera código de pegamento que nadie quiere mantener.
- El núcleo con dinero y reglas pesadas llega cuando el equipo ya domina el proceso, no antes.
Feature flags y rollback: cómo migrar sin downtime
Un feature flag es un interruptor que decide, por ruta, por perfil o por porcentaje de usuarios, si la solicitud va al viejo o al nuevo. Con él, el lanzamiento sigue un camino predecible: primero el equipo interno, después un grupo piloto, después todos.
El rollback debe consistir en apagar el flag o cambiar la ruta, en minutos, sin un nuevo deploy. Y hay que probarlo antes. Si el módulo nuevo graba datos en un formato que el legado no entiende, volver atrás lo rompe todo. Por eso el esquema de la base de datos cambia en etapas compatibles con las dos versiones.
Para cálculos sensibles, una técnica útil es la ejecución en sombra: la solicitud corre en los dos sistemas, solo el resultado del legado se devuelve al usuario, y las divergencias van a un registro. Usted descubre las diferencias antes de que cualquier cliente las vea.
Una vez que el 100% del tráfico esté en el nuevo, mantenga el legado disponible por un tiempo. Apagarlo el mismo día es prisa innecesaria.
Qué medir durante la migración incremental
Sin medición, "quedó mejor" es una opinión. Registre una línea base del sistema antiguo antes de empezar y compare módulo por módulo. Lo que seguimos:
- Tasa de errores y tiempo de respuesta por ruta, legado contra nuevo.
- Divergencias en las pruebas de caracterización y en la ejecución en sombra.
- Porcentaje del tráfico atendido por el sistema nuevo.
- Tickets de soporte por módulo, antes y después del cambio.
- Tiempo para entregar un cambio simple en un módulo migrado y en un módulo legado.
- Rutas del legado que aún se acceden. Cuando llegan a cero, el legado puede apagarse.
Errores comunes y por qué el método sirve para otros lenguajes
El error más frecuente es congelar el legado durante meses mientras se construye el nuevo. El negocio no se detiene, los cambios siguen llegando y el nuevo nace desactualizado. Otro es aprovechar la migración para "mejorar" reglas en el mismo paso: así ya no se puede comparar el nuevo con el viejo. Y está el clásico de dejar el legado encendido para siempre, lo que significa pagar dos mantenimientos.
Nada de esto depende de PHP. Inventario, pruebas de caracterización, capa de convivencia, base de datos por etapas, flags y rollback funcionan igual en Java, .NET, Delphi o Python antiguo. Cambia la herramienta, no el método. Si todavía hay dudas entre migrar poco a poco y empezar de nuevo, el texto sobre refactorizar o reescribir desde cero ayuda a decidir.
La IA entra como acelerador: ayuda a leer código sin documentación, mapear dependencias y generar borradores de pruebas. Pero la decisión sobre qué es regla y qué es bug sigue siendo humana. El plazo y el costo dependen del tamaño del sistema, del acoplamiento, de la calidad de los datos y de la cantidad de reglas sin documentar, y el artículo sobre cuánto cuesta modernizar un sistema legado detalla estos factores.
Si quiere ver cómo quedaría una pantalla o un flujo de su sistema en el nuevo stack antes de decidir cualquier cosa, puede pedir un prototipo gratis. Y si quiere conocer cómo conducimos este trabajo, vea nuestra página de modernización de sistemas legados.
De nuestra experiencia
En SKAD, refactorizamos con apoyo de IA cinco sistemas propios: SyncStop, 4Car, KaraokeApp, The Bee App y DEM, este último de inspección de equipos. Todos eran PHP puro con jQuery y Bootstrap, y las aplicaciones móviles estaban en Cordova. Hoy funcionan en PHP 8.3 con Slim 4 en la API, React con Vite en la web y React Native con Expo en la app. Mantuvimos el lenguaje PHP; lo que cambió fue el framework y la arquitectura. Después de la refactorización, el mantenimiento de estos sistemas quedó más ligero.
En otro trabajo, reconstruimos una plataforma de gestión y cuidado animal que era PHP 7 con Azure SQL, pasando a Slim 4, React con Vite y React Native, en Azure. La base de datos se mantuvo. Migramos primero los datos y después las funciones. Un desarrollador implementó a partir de un documento de plan, y nosotros seguimos el avance mediante listas macro organizadas por perfil de usuario.
Preguntas frecuentes
¿Se puede migrar un sistema PHP antiguo sin parar la operación?
Sí, si la migración es incremental: el sistema nuevo convive con el viejo detrás de un proxy y asume una ruta a la vez. Con feature flags y un rollback probado, cada cambio puede deshacerse en minutos.
¿Necesito actualizar la versión de PHP antes de migrar a un framework?
Solo lo suficiente para correr en una versión con soporte y permitir pruebas. Gastar meses corrigiendo código que será reescrito suele ser un desperdicio.
¿Qué framework elegir para reemplazar PHP puro?
Depende del equipo, del tamaño del sistema y de cómo se usará. La elección importa menos que la arquitectura: separar API, reglas e interfaz es lo que facilita el mantenimiento después.
¿Cuánto tiempo lleva migrar un sistema PHP legado?
Varía mucho según el número de módulos, el acoplamiento, la calidad de los datos y la falta de documentación. Solo el inventario y las pruebas de caracterización permiten una estimación honesta.
¿Qué es el patrón strangler?
Es construir el sistema nuevo alrededor del antiguo, redirigiendo ruta por ruta, hasta que el legado deje de recibir tráfico y pueda apagarse. No existe un día de cambio.
Conclusión
Antes de contratar cualquier cosa, haga un ejercicio simple: liste las diez rutas más usadas de su sistema, las tablas que toca cada una y qué pasa si una de ellas falla durante una hora. Esa lista ya muestra por dónde empezar y dónde está el riesgo. Si quiere una segunda opinión sobre ella, envíe un mensaje por WhatsApp y nuestro equipo hará un diagnóstico de su sistema legado.