Antes de migrar sistema PHP antigo: inventário e mapa
A primeira etapa não tem uma linha de código novo. Em PHP puro, o sistema costuma ser uma pasta de arquivos em que cada um mistura SQL, HTML e regra de negócio, e a URL é simplesmente o nome do arquivo. Sem mapa, qualquer estimativa é chute.
O que levantar, nessa ordem:
- Rotas e telas: cada arquivo acessível por URL, quem usa e com que frequência. Os logs do servidor web respondem isso melhor que qualquer entrevista.
- Chamadas AJAX: os endpoints que o jQuery chama escondidos dentro das telas.
- Tabelas do banco: quem lê e quem escreve em cada uma, incluindo triggers, views e procedures.
- Integrações: pagamento, e-mail, APIs de terceiros, webhooks e tarefas agendadas (cron).
- Código morto: arquivos que não aparecem nos logs. Quase sempre existe uma parte do sistema que ninguém abre, e essa parte você não migra.
- Pontos de risco: tudo o que mexe com dinheiro, estoque, dados pessoais ou regra regulatória.
Atualizar PHP primeiro ou trocar de framework?
Se o sistema ainda roda numa versão sem suporte, a tentação é começar por atualizar PHP no próprio legado. Nossa posição: faça o mínimo necessário para rodar numa versão suportada e não deixe isso virar um projeto em si.
O motivo é prático. Em código antigo, subir de versão costuma esbarrar em funções removidas, extensões de banco antigas e tipos tratados com mais rigor. Cada correção é trabalho jogado fora se aquele arquivo vai ser reescrito de qualquer jeito. Atualizar a versão vale como etapa de segurança e para poder rodar testes num ambiente atual. O resto do esforço vai para o sistema novo, que já nasce na versão atual da linguagem.
Para a visão completa de onde essa etapa se encaixa, veja o nosso guia de modernização de sistemas legados.
Testes de caracterização: grave o comportamento antes de mexer
Sistema legado quase nunca tem testes. E sem teste você não sabe se o novo faz a mesma coisa que o velho. A saída é o teste de caracterização: ele não diz o que o sistema deveria fazer, ele registra o que o sistema faz hoje.
Se o relatório mensal arredonda de um jeito estranho, o teste grava o jeito estranho. Depois alguém do negócio decide se aquilo é bug ou regra. Sem esse registro, a regra some na migração e ninguém percebe até o cliente reclamar.
Na prática: para cada rota prioritária do inventário, chamamos o sistema antigo com entradas reais (anonimizadas), guardamos a saída (JSON, trechos de HTML, linhas gravadas no banco) e depois rodamos as mesmas entradas contra o módulo novo, comparando. Não precisa de ferramenta sofisticada; um script que faz requisições e compara respostas já resolve muito.
O erro mais comum aqui é querer cobrir tudo. Concentre o esforço onde há cálculo e dinheiro. Cadastros simples podem ser validados com um roteiro manual.
Camada de convivência: proxy por rota e padrão strangler
A peça central de uma migração sem downtime é um ponto de entrada na frente dos dois sistemas. Pode ser um proxy reverso ou o próprio roteador do sistema novo. Cada rota aponta para o legado ou para o novo, e o usuário não percebe a diferença.
É o padrão strangler: o sistema novo cresce em volta do velho, rota por rota, até o velho deixar de receber tráfego e poder ser desligado. Não existe dia da virada, e é justamente isso que tira o risco.
Os pontos técnicos que costumam dar trabalho:
- Autenticação e sessão compartilhadas: o usuário não pode logar duas vezes. Ou o novo sistema entende a sessão do legado, ou os dois passam a validar um mesmo token. É a primeira peça estrutural, porque todo módulo novo depende dela.
- Mesmo domínio para os dois: evita problemas de cookie e de CORS.
- Front-end em etapas: jQuery e React convivem bem, tela a tela. Mudar o back-end e o front de uma mesma tela no mesmo passo aumenta o risco; separar costuma ser mais seguro.
- Regras duplicadas: enquanto os dois existem, uma correção no legado precisa ser replicada no novo. Anote isso numa lista viva.
Migração do banco e dos dados sem quebrar o sistema antigo
O banco é o ponto mais perigoso porque os dois sistemas o usam ao mesmo tempo. A regra que seguimos: nunca mude o esquema e o código no mesmo passo.
Em geral mantemos o banco como está no início. O sistema novo lê as mesmas tabelas, com uma camada de acesso que traduz nomes ruins para algo legível. Quando o esquema precisa mudar, vai em etapas: cria-se a coluna ou tabela nova, escreve-se nos dois lugares, migram-se os dados históricos, troca-se a leitura e só no fim remove-se o antigo, quando o legado não o usa mais.
O script de migração de dados deve ser repetível: rodar dez vezes numa cópia de produção e dar o mesmo resultado. Depois, valide contagens, somas e amostras. É aqui que aparecem os dados sujos: datas inválidas, textos com codificações misturadas, registros duplicados.
Trocar de plataforma de banco é outro projeto. Se puder, separe da migração de código.
Em que ordem migrar os módulos
Não existe ordem universal, mas existem critérios que funcionam:
- Primeiro, um módulo pequeno, visível e de baixo risco, como um relatório ou um cadastro auxiliar. O objetivo é provar a camada de convivência, o deploy e o rollback, não entregar valor de negócio.
- Depois, a autenticação, se ainda não estiver resolvida, porque tudo depende dela.
- Em seguida, os módulos que mais doem: os que mais mudam, os que mais dão erro, os que mais atrasam a equipe.
- Módulos muito acoplados migram juntos. Separá-los à força gera código de cola que ninguém quer manter.
- O núcleo com dinheiro e regra pesada vem quando o time já domina o processo, não antes.
Feature flags e rollback: como fazer migração sem downtime
Feature flag é um interruptor que decide, por rota, por perfil ou por percentual de usuários, se a requisição vai para o velho ou para o novo. Com ele, a liberação segue um caminho previsível: primeiro a equipe interna, depois um grupo piloto, depois todos.
O rollback tem de ser desligar a flag ou trocar a rota, em minutos, sem novo deploy. E precisa ser testado antes. Se o módulo novo grava dados num formato que o legado não entende, voltar atrás quebra tudo. Por isso o esquema do banco muda em etapas compatíveis com as duas versões.
Para cálculos sensíveis, uma técnica útil é a execução em sombra: a requisição roda nos dois sistemas, só o resultado do legado é devolvido ao usuário, e as divergências vão para um registro. Você descobre as diferenças antes de qualquer cliente ver.
Depois de 100% do tráfego no novo, mantenha o legado disponível por um período. Desligar no mesmo dia é pressa sem necessidade.
O que medir durante a migração incremental
Sem medição, 'ficou melhor' é opinião. Registre uma linha de base do sistema antigo antes de começar e compare módulo a módulo. O que acompanhamos:
- Taxa de erro e tempo de resposta por rota, legado contra novo.
- Divergências nos testes de caracterização e na execução em sombra.
- Percentual do tráfego servido pelo sistema novo.
- Chamados de suporte por módulo, antes e depois da troca.
- Tempo para entregar uma mudança simples num módulo migrado e num módulo legado.
- Rotas do legado ainda acessadas. Quando chegam a zero, o legado pode ser desligado.
Erros comuns e por que o método vale para outras linguagens
O erro mais frequente é congelar o legado por meses enquanto o novo é construído. O negócio não para, as mudanças continuam chegando, e o novo nasce desatualizado. Outro é aproveitar a migração para 'melhorar' regras no mesmo passo: aí não dá mais para comparar o novo com o velho. E há o clássico de deixar o legado ligado para sempre, o que significa pagar duas manutenções.
Nada disso depende do PHP. Inventário, testes de caracterização, camada de convivência, banco em etapas, flags e rollback funcionam do mesmo jeito em Java, .NET, Delphi ou Python antigo. Muda a ferramenta, não o método. Se ainda há dúvida entre migrar aos poucos e começar de novo, o texto sobre refatorar ou reescrever do zero ajuda a decidir.
A IA entra como acelerador: ajuda a ler código sem documentação, mapear dependências e gerar rascunhos de testes. Mas a decisão sobre o que é regra e o que é bug continua sendo humana. Prazo e custo dependem do tamanho do sistema, do acoplamento, da qualidade dos dados e da quantidade de regra sem documentação, e o artigo sobre quanto custa modernizar um sistema legado detalha esses fatores.
Se quiser ver como uma tela ou um fluxo do seu sistema ficaria na stack nova antes de decidir qualquer coisa, dá para pedir um protótipo grátis. E se você quer conhecer como conduzimos esse trabalho, veja a nossa página de modernização de sistemas legados.
Da nossa experiência
Na SKAD, refatoramos com apoio de IA cinco sistemas nossos: SyncStop, 4Car, KaraokeApp, The Bee App e DEM, este de inspeção de equipamentos. Todos eram PHP puro com jQuery e Bootstrap, e os aplicativos eram em Cordova. Hoje rodam em PHP 8.3 com Slim 4 na API, React com Vite na web e React Native com Expo no app. Mantivemos a linguagem PHP; o que mudou foi o framework e a arquitetura. Depois da refatoração, a manutenção desses sistemas ficou mais leve.
Em outro trabalho, reconstruímos uma plataforma de gestão e cuidado animal que era PHP 7 com Azure SQL, passando para Slim 4, React com Vite e React Native, no Azure. O banco foi mantido. Migramos os dados primeiro e as funções depois. Um desenvolvedor implementou a partir de um documento de plano, e nós acompanhamos o andamento por listas macro organizadas por perfil de usuário.
Perguntas frequentes
Dá para migrar um sistema PHP antigo sem parar a operação?
Dá, se a migração for incremental: o sistema novo convive com o velho atrás de um proxy e assume uma rota por vez. Com feature flags e rollback testado, cada troca pode ser desfeita em minutos.
Preciso atualizar a versão do PHP antes de migrar para um framework?
Só o suficiente para rodar numa versão suportada e permitir testes. Gastar meses corrigindo código que será reescrito costuma ser desperdício.
Qual framework escolher para substituir PHP puro?
Depende da equipe, do tamanho do sistema e de como ele será usado. A escolha importa menos que a arquitetura: separar API, regras e interface é o que facilita a manutenção depois.
Quanto tempo leva migrar um sistema PHP legado?
Varia muito com o número de módulos, o acoplamento, a qualidade dos dados e a falta de documentação. Só o inventário e os testes de caracterização permitem uma estimativa honesta.
O que é o padrão strangler?
É construir o sistema novo em volta do antigo, redirecionando rota por rota, até o legado não receber mais tráfego e poder ser desligado. Não existe um dia de virada.
Conclusão
Antes de contratar qualquer coisa, faça um exercício simples: liste as dez rotas mais usadas do seu sistema, as tabelas que cada uma toca e o que acontece se uma delas falhar por uma hora. Essa lista já mostra por onde começar e onde está o risco. Se quiser uma segunda opinião sobre ela, mande uma mensagem pelo WhatsApp e nosso time faz um diagnóstico do seu sistema legado.