Manutenção e versões
LidoEsta aula aborda a manutenção de aplicações PHP, enfatizando a importância de acompanhar as versões do PHP, entender o ciclo de vida, migrar entre versões, lidar com depreciações e garantir compatibilidade. O conteúdo inclui exemplos práticos e exercícios para consolidar o conhecimento.
Nesta aula, vamos explorar um aspecto crucial do desenvolvimento em PHP: a manutenção contínua de aplicações e o gerenciamento de versões. O PHP evolui constantemente, com novas funcionalidades, melhorias de performance e correções de segurança. Ignorar essas mudanças pode deixar seu código vulnerável e incompatível com ambientes modernos. Aqui, você aprenderá a navegar por esse ciclo, migrar projetos com segurança e escrever código que sobreviva ao teste do tempo.
Vamos começar entendendo o ciclo de vida do PHP, depois abordaremos estratégias de migração, o impacto das depreciações e, por fim, como manter a compatibilidade. Ao final, você terá um guia prático para manter suas aplicações saudáveis e atualizadas.
Ciclo de vida do PHP
O PHP segue um ciclo de lançamentos previsível, com versões menores e maiores. Cada versão tem um período de suporte ativo e um período de segurança. Durante o suporte ativo, correções de bugs e novas funcionalidades são adicionadas. No período de segurança, apenas correções críticas de segurança são lançadas. Após o fim do suporte de segurança, a versão se torna obsoleta e não recebe mais atualizações, o que representa um risco para aplicações que ainda a utilizam.
Para ilustrar: a versão PHP 8.0 foi lançada em novembro de 2020, teve suporte ativo até novembro de 2022 e suporte de segurança até novembro de 2023. Já o PHP 8.3, lançado em novembro de 2023, terá suporte ativo até novembro de 2025 e suporte de segurança até novembro de 2026. É essencial conhecer essas datas para planejar atualizações.
Aqui está um exemplo de como verificar a versão do PHP no seu ambiente:
<?php
// Exibe a versão atual do PHP
echo PHP_VERSION;
?>
Além disso, a comunidade PHP adota uma política de versões semestrais, com lançamentos em junho e novembro. Isso permite que os desenvolvedores tenham um fluxo constante de melhorias, mas também exige atenção para não ficar para trás.
Migrando versões
Migrar uma aplicação PHP para uma versão mais recente é uma tarefa que exige planejamento e testes. O processo envolve atualizar o código para ser compatível com as novas funcionalidades e remover o uso de recursos depreciados. Uma migração bem-sucedida começa com a leitura das notas de migração disponíveis na documentação oficial, que listam todas as mudanças que podem afetar seu código.
Antes de migrar, é fundamental ter uma suíte de testes automatizados. Isso garante que, após a atualização, você possa detectar rapidamente qualquer comportamento quebrado. Além disso, é recomendável usar ferramentas de análise estática, como o PHPStan ou o Psalm, para identificar problemas potenciais antes mesmo de executar o código.
Um exemplo de mudança comum entre versões é a alteração no tratamento de strings numéricas. No PHP 8.0, comparações entre strings numéricas e inteiros mudaram para serem mais previsíveis. Veja:
<?php
// PHP 7.4: comparação frouxa pode gerar resultados inesperados
var_dump('123' == 123); // true
// A partir do PHP 8.0, a comparação é mais estrita em alguns casos
// Mas '123' == 123 continua true, pois a string é numérica
?>
Outra mudança importante é a introdução de atributos (annotations) no PHP 8.0, que substituem as docblocks para metadados. Migrar seu código para usar atributos pode ser uma tarefa de modernização, mas não é obrigatório para a compatibilidade.
Para facilitar a migração, o PHP fornece a extensão php-compat-info e ferramentas como o Rector, que automatizam muitas correções. O Rector, por exemplo, pode reescrever código para ser compatível com versões mais novas, aplicando regras predefinidas.
Depreciações
Depreciação é o processo de marcar funcionalidades como obsoletas, indicando que elas serão removidas em versões futuras. O PHP frequentemente deprecia funções ou sintaxes que foram substituídas por alternativas melhores. Usar código depreciado não causa erros imediatamente, mas gera avisos (deprecation warnings) e pode quebrar a aplicação em versões futuras.
Por exemplo, a função create_function() foi depreciada no PHP 7.2 e removida no PHP 8.0. Ela era usada para criar funções anônimas de forma insegura. A alternativa moderna é usar closures ou arrow functions. Veja a diferença:
<?php
// Depreciado no PHP 7.2, removido no PHP 8.0
$func = create_function('$x', 'return $x * 2;');
echo $func(5); // 10
// Alternativa moderna com closure
$func = function($x) { return $x * 2; };
echo $func(5); // 10
// Ou com arrow function (PHP 7.4+)
$func = fn($x) => $x * 2;
echo $func(5); // 10
?>
Outro exemplo é a constante FILTER_SANITIZE_STRING, que foi depreciada no PHP 8.1 e removida no PHP 9.0 (planejado). Ela era usada para limpar strings, mas sua implementação era inconsistente. Recomenda-se usar htmlspecialchars() ou strip_tags() conforme o caso.
Para identificar depreciações no seu código, você pode definir o nível de erro para exibir avisos de depreciação. Em desenvolvimento, configure o error_reporting para incluir E_DEPRECATED. Dessa forma, você verá os avisos no log e poderá corrigir antes que se tornem problemas.
<?php
error_reporting(E_ALL); // Exibe todos os erros, incluindo depreciações
?>
Compatibilidade
Manter a compatibilidade do seu código com diferentes versões do PHP é essencial, especialmente se você desenvolve bibliotecas ou pacotes que serão usados por outros projetos. Existem estratégias para escrever código que funcione em múltiplas versões, como usar verificações de versão (version_compare()) e condicionais.
Uma abordagem comum é usar polyfills para funcionalidades que só existem em versões mais novas. Por exemplo, a função str_contains() foi introduzida no PHP 8.0. Se você precisa suportar PHP 7.4, pode definir sua própria função condicionalmente:
<?php
if (!function_exists('str_contains')) {
function str_contains(string $haystack, string $needle): bool {
return $needle === '' || strpos($haystack, $needle) !== false;
}
}
?>
Além disso, o PHP fornece a função PHP_VERSION_ID que retorna um inteiro que pode ser comparado com constantes como PHP_VERSION_ID >= 80000 para verificar se a versão é 8.0 ou superior. Isso é útil para ativar comportamentos específicos.
Outra consideração importante é a compatibilidade com extensões e bibliotecas externas. Antes de migrar, verifique se todas as dependências do seu projeto suportam a nova versão do PHP. Ferramentas como o Composer podem ajudar, exibindo requisitos de plataforma.
<?php
// Verifica se a versão do PHP é 8.0 ou superior
if (PHP_VERSION_ID >= 80000) {
// Código específico para PHP 8.0+
} else {
// Código para versões anteriores
}
?>
Por fim, adote a prática de testar sua aplicação em várias versões do PHP usando contêineres ou CI (integração contínua). Isso garante que você detecte incompatibilidades cedo e mantenha um código robusto.
Boas práticas e observações finais
Manter uma aplicação PHP saudável não é apenas uma tarefa pontual, mas um processo contínuo. Aqui estão algumas boas práticas:
- Acompanhe o calendário de lançamentos do PHP e planeje atualizações com antecedência.
- Mantenha um ambiente de desenvolvimento separado para testar migrações antes de aplicá-las em produção.
- Use ferramentas de análise estática e testes automatizados para garantir a qualidade do código.
- Documente as mudanças necessárias durante a migração para futuras referências.
- Participe da comunidade PHP (fóruns, grupos, conferências) para se manter informado sobre as novidades.
Referências
- PHP: Versões Suportadas
- Apêndices do Manual PHP
- Migrando do PHP 7.4 para o PHP 8.0
- Migrando do PHP 8.0 para o PHP 8.1
- Migrando do PHP 8.1 para o PHP 8.2
- Migrando do PHP 8.2 para o PHP 8.3
- Atributos no PHP
- Rector - Ferramenta de migração automatizada
Exercícios
- Explique o que é suporte ativo e suporte de segurança no ciclo de vida do PHP. Por que é importante não usar versões sem suporte?
- Cite duas mudanças introduzidas no PHP 8.0 que podem afetar o código migrado do PHP 7.4.
- O que é depreciação? Dê um exemplo de uma função depreciada e sua alternativa moderna.
- Como você pode escrever código compatível com PHP 7.4 e PHP 8.0 ao mesmo tempo? Dê um exemplo de polyfill.
- Quais ferramentas você pode usar para ajudar na migração de versões do PHP? Descreva uma delas.
create_function() e mudou a forma como erros fatais são tratados (agora são exceções).
create_function() foi depreciada no PHP 7.2 e removida no PHP 8.0. A alternativa moderna é usar closures ou arrow functions, como fn($x) => $x * 2.
str_contains() (PHP 8.0+) em PHP 7.4, você pode definir um polyfill condicional: if (!function_exists('str_contains')) {
function str_contains(string $haystack, string $needle): bool {
return $needle === '' || strpos($haystack, $needle) !== false;
}
} Assim, o código funciona em ambas as versões.
create_function() por closures automaticamente.