Refactorización de código legacy en PHP: guía paso a paso

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: por qué la refactorización de código legacy no es un lujo, sino una necesidad



Cada desarrollador PHP tarde o temprano se enfrenta a código legacy. Puede ser un proyecto escrito hace 10 años en PHP 5.3, o una aplicación que «simplemente funciona», pero causa dolor con cada cambio. La refactorización de dicho código no es solo «peinar» el estilo, sino un proceso críticamente importante que mejora la mantenibilidad, el rendimiento y la seguridad de la aplicación.



En este artículo analizaremos enfoques prácticos para la refactorización de código PHP legacy, utilizando las capacidades modernas del lenguaje (PHP 7.4–8.3) y patrones probados. Aprenderá cómo realizar cambios de forma segura sin romper el sistema en funcionamiento.



1. Evaluación y documentación del estado actual



El primer paso y el más importante es entender con qué está tratando. No intente refactorizar a ciegas.



1.1. Cree un mapa de dependencias

Utilice herramientas como PhpMetrics o Deptrac para visualizar las conexiones entre clases. Esto ayudará a identificar «objetos divinos» (god objects) y dependencias cíclicas.



// Ejemplo de una clase "divina" típica en código legacyclass UserManager {    public function save($data) {        // 200 líneas de código: validación, envío de email, registro, trabajo con BD    }        public function sendNewsletter() {        // Otras 150 líneas    }        public function generateReport() {        // Y otras 100 líneas    }}


1.2. Escriba pruebas de caracterización

Antes de cambiar el código, asegúrese de que el comportamiento actual esté documentado con pruebas. Utilice el enfoque «Golden Master» (snapshot testing):



// Prueba que fija el comportamiento actualpublic function testLegacyCalculation(): void{    $calculator = new OldCalculator();    $result = $calculator->compute(10, 20);        // Si no hay especificación, simplemente guardamos el resultado    $this->assertSame(30, $result);}


Consejo: Si el proyecto no tiene pruebas en absoluto, comience con pruebas de integración para las operaciones comerciales críticas. Utilice PHPUnit con vfsStream para aislar el sistema de archivos.



2. Mejora por etapas: de funciones globales a POO



La mayor parte del código PHP legacy consiste en funciones globales y estilo procedural. La migración gradual a POO es una etapa clave de la refactorización.



2.1. Encapsulación de funciones globales

Reemplace las funciones globales por métodos estáticos de clase, luego por servicios completos.



// Antes: función globalfunction send_email($to, $subject, $message) {    mail($to, $subject, $message);}

// Después: clase de servicioclass MailService { public function __construct( private MailerInterface $mailer ) {} public function send(string $to, string $subject, string $message): bool { return $this->mailer->send($to, $subject, $message); }}


2.2. Eliminación de variables globales

Las variables globales ($GLOBALS, $_SESSION directamente) son la principal fuente de errores. Utilice el patrón Registry o inyección de dependencias (DI).



// Malo: trabajo directo con variables globalesfunction getCurrentUser() {    global $db;    $id = $_SESSION['user_id'];    return $db->query("SELECT * FROM users WHERE id = $id");}

// Bueno: inyección explícita de dependenciasclass UserProvider { public function __construct( private PDO $db, private SessionInterface $session ) {} public function getCurrentUser(): ?User { $id = $this->session->get('user_id'); return $this->db->query('SELECT * FROM users WHERE id = ?', [$id]); }}


3. Reemplazo seguro de construcciones obsoletas



PHP evoluciona, y muchas construcciones antiguas se han vuelto inseguras y

Blogs

Book Recommendations