O PHP Group lançou a versão 8.5 da linguagem de script open source que alimenta grande parte da web, incluindo sites que utilizam o CMS WordPress.
O lançamento do PHP 8.5 em novembro marcou o segundo ano do compromisso da comunidade PHP de fornecer atualizações importantes em um cronograma anual, seguido por dois anos completos de suporte ativo para cada versão.
Embora o 8.5 tenha acabado de ser lançado, ele já está incluído no nosso benchmark anual de PHP que avalia o desempenho por trás de diversos CMSs e frameworks populares.
Se estiver planejando migrar aplicativos PHP para a versão 8.5, precisará entender o que mudou nesta nova versão. Isso inclui novos recursos que podem melhorar seu código e funcionalidades antigas que os desenvolvedores do PHP estão prestes a remover.
Aqui estão os pontos de destaque desta versão.
Novos recursos e melhorias no PHP 8.5
Vamos começar pelas novas adições ao código base do PHP. Essas mudanças normalmente começam como solicitações de comentários (RFCs) que podem ser aprovadas e atribuídas a uma versão futura do PHP.
Os novos recursos abaixo são os que mais têm chamado atenção no PHP 8.5.
Chamadas de função em cadeia com um operador pipe
Um novo operador pipe (|>) encadeia as chamadas de função de uma forma que será familiar para programadores de JavaScript. O pipe opera da esquerda para a direita, passando um único valor ao longo da cadeia em cada etapa.
Com as versões anteriores do PHP, os programadores podem ter realizado uma tarefa semelhante aninhando funções ou passando por uma série de chamadas de função no valor retornado de cada etapa.
Aqui está um exemplo simples usando o novo operador pipe:
$text = ' New-in-php-8.4 ';
$result = $text
|> trim(...)
|> (fn($str) => str_replace('4', '5', $str))
|> (fn($str) => str_replace('-', ' ', $str))
|> strtoupper(...);
var_dump($result);
// string(14) "NEW IN PHP 8.5"
(Observe que estamos usando a sintaxe first-class callables (...), introduzida no PHP 8.1 com as chamadas de função trim() e strtoupper())
A cadeia acima poderia ser escrita em uma única linha, mas o objetivo do operador pipe é justamente melhorar a legibilidade.
O acima exposto é equivalente a aninhar essas operações (na ordem inversa) desta forma:
$text = " New-in-php-8.4 ";
$result = strtoupper(
str_replace(‘-, ' ',
str_replace('4', '5',
trim($text)
)
)
);
Um programador também poderia ter concluído a tarefa em versões anteriores do PHP desta forma:
$text = " New-in-php-8.4 ";
$result = trim($text);
$result = str_replace('4', '5', $result);
$result = str_replace(‘-, ' ', $result);
$result = strtoupper($result);
Analisar URLs com a nova extensão URI
As URLs (também conhecidas como URIs para aqueles que são mais exigentes) são essenciais para a navegação na web, mas a função parse_url() que foi incorporada ao PHP desde a versão 4 é conhecida por falhar com entradas malformadas, o que pode gerar erros ao manipular ou validar endereços.
Para aprimorar a análise de URLs, o PHP 8.5 incorpora as bibliotecas uriparser e Lexbor, oferecendo suporte aos padrões de URL RFC 3986 e WHATWG.
Você pode invocar a biblioteca uniparser iniciando o trabalho com a nova extensão URI desta forma:
$uri = new UriRfc3986Uri("https://kinsta.com/blog/php-8-5/");
echo $uri->getScheme(); // https
echo $uri->getHost(); // kinsta.com
echo $uri->getPath(); // /blog/php-8-5
Como alternativa, você pode escolher a biblioteca de URLs Lexbor WHATWG desta forma:
$uri = new UriWagWgUrl("https://kinsta.com/blog/php-8-5/");
echo $uri->getScheme(); // https
echo $uri->getUnicodeHost(); // kinsta.com
echo $uri->getAsciiHost(); // kinsta.com
echo $uri->getPath(); // /blog/php-8-5
Os exemplos acima são os mais básicos. As duas bibliotecas representadas pela extensão URI no PHP 8.5 compartilham funcionalidades, mas também apresentam diferenças significativas.
Uma diferença importante é que a biblioteca RFC 3986 oferece suporte a representações “raw” e “normalized-decoded” de URIs. Isso pode ser útil ao trabalhar com entradas e saídas codificadas em porcentagem. Usadas em um navegador, por exemplo, estas duas URIs são idênticas:
Nas versões anteriores do PHP, você poderia começar com rawurldecode() e rawurlencode() (que também estão em conformidade com a RFC 3986), mas a nova extensão está pronta para trabalhar com todos os componentes de URIs imediatamente, estejam eles codificados ou não.
Aqui estão alguns exemplos extraídos diretamente do RFC por trás da nova API de análise:
$uri = new UriRfc3986Uri("https://%61pple:p%61ss@ex%61mple.com/foob%61r?%61bc=%61bc");
echo $uri->getRawUserInfo(); // %61pple:p%61ss
echo $uri->getUserInfo(); // apple:pass
echo $uri->getRawUsername(); // %61pple
echo $uri->getUsername(); // apple
echo $uri->getRawPassword(); // p%61ss
echo $uri->getPassword(); // pass
echo $uri->getRawHost(); // ex%61mple.com
echo $uri->getHost(); // example.com
echo $uri->getRawPath(); // /foob%61r
echo $uri->getPath(); // /foobar
echo $uri->getRawQuery(); // %61bc=%61bc
echo $uri->getQuery(); // abc=abc
Ao usar a biblioteca WHATWG URL com a nova extensão, todas as URIs são tratadas como “raw”, portanto não existe um conjunto separado de funções para oferecer formatos alternativos. Porém, a biblioteca consegue converter entre caracteres ASCII e Unicode, frequentemente encontrados em URIs.
Atente-se à nova diretiva INI max_memory_limit
Dizem que com grande poder vem grande responsabilidade. Se esse poder incluir a escolha da quantidade de memória do servidor que seu aplicativo PHP pode tentar usar, você poderá ser responsável por falhas no aplicativo quando os processos consumirem mais memória do que a disponível.
Parte de uma instalação típica do PHP é um arquivo php.ini com informações de configuração que inclui uma diretiva que especifica um limite de consumo de memória para qualquer processo (ou thread) do PHP. Uma diretiva INI comum para um limite de memória de 128 MB tem a seguinte aparência:
// php.ini
memory_limit 128M
Em algumas plataformas de hospedagem, os desenvolvedores de aplicativos PHP podem substituir o memory_limit em tempo real usando a função ini_set() em seu código:
ini_set(‘memory_limit’, ‘256M’);
// Start code that requires up to 256 MB of memory
Você também pode passar para a função o valor -1, como em ini_set('memory_limit', '-1') – para não impor nenhum limite.
Substituir a diretiva INI para um limite de memória pode ser arriscado para desenvolvedores que não estejam intimamente familiarizados com as configurações de memória dos servidores nos quais seus aplicativos serão executados. Se um ou vários threads PHP tentarem consumir mais do que o pool de memória total, o resultado poderá ser uma falha do aplicativo sem aviso durante a execução.
O PHP 8.5 adiciona uma diretiva INI chamada max_memory_limit, que funciona como um teto rígido, mesmo em configurações onde desenvolvedores têm acesso ao ini_set() para ajustar o uso de memória no código.
Aqui estão exemplos de entradas no arquivo php.ini de uma instalação do PHP 8.5:
// php.ini
max_memory_limit 256M
memory_limit 128M
Com max_memory_limit definido como 256 MB, veja como o PHP se comporta nesse caso:
ini_set('memory_limit', '256M'); // This is OK
ini_set('memory_limit', '512M'); // Fail with warning
ini_set('memory_limit', '-1'); // Fail with warning
As tentativas acima de definir um novo limite de 512 MB (ou ilimitado) não terão sucesso. Em vez disso, o PHP definirá o limite de memória com o valor atribuído a max_memory_limit no arquivo php.ini e emitirá um aviso. (A mensagem de aviso pode aparecer na tela e também ser registrada em log, dependendo das configurações de relatório de erros da instalação do PHP.)
Uma abordagem inteligente para os desenvolvedores do PHP 8.5 será usar a função ini_get() para ver se o novo limite máximo foi definido, como ini_get('max_memory_limit') e então ajustar o código de acordo com o valor retornado. Em versões anteriores do PHP, essa chamada retornaria false com segurança.
Obtenha o primeiro ou o último valor de um array
Você poderia presumir que o PHP já tinha funções para ler os valores armazenados como o primeiro ou o último item de um array. Acontece que não tinha.
Mas desde o PHP 7.3, o PHP possui funções para descobrir as primeiras e últimas chaves de um array. Portanto, para encontrar os primeiros e últimos valores, você poderia usar as funções array_key_first() ou array_key_last() e, em seguida, usar as chaves retornadas para fazer referência aos valores que está procurando:
$array = ["One", "Two", "Three"];
echo $array[array_key_first($array)]; // "One"
O PHP 8.5 elimina uma etapa dessa tarefa e permite que você alcance os valores diretamente com as novas funções array_first() e array_last().
Tudo isso é muito simples:
$array = ["One", "Two", "Three"];
echo array_first($array); // "One"
echo array_last($array); // "Three"
echo array_last([]); // null
Acima, você pode ver que um array vazio retornará null, mas isso por si só não confirma que o array inteiro está vazio, pois um valor de array pode ser null:
echo array_last([1, 2, null]); // null
Receba lembretes para usar o valor de retorno de uma função
O PHP 8.5 adiciona um novo atributo #[NoDiscard] que indica que o valor de retorno de uma função pode ser crítico. O PHP confirmará se o valor de retorno é consumido de alguma forma e, se não for, acionará um aviso.
Um exemplo simples:
#[NoDiscard("this message property will be appended to the built-in warning.")]
function foo(): string {
return 'bar';
}
// Warning:
// The return value of function foo() is expected to be consumed,
// this message property will be appended to the built-in warning.
foo();
// This will not trigger a warning:
$result = foo();
// Also satisfactory is the (void) cast:
(void) foo();
No exemplo acima, o valor de retorno da função definida não é usado em primeira instância, o que aciona um aviso. Mas, quando atribuído à variável $result ou convertido como void, o valor será considerado consumido.
Os autores da RFC por trás dessa adição no PHP 8.5 descreveram usos mais convincentes para esse atributo do que o simples exemplo acima. Um cenário era uma função crítica com um relatório de erros mais complexo do que um simples “sucesso/falha”, sendo melhor comunicado por meio do valor de retorno da função.
Outros aprimoramentos relacionados a atributos
Além do novo atributo #[NoDiscard], outros aprimoramentos na funcionalidade de metadados de atributos nesta versão incluem:
- Os atributos agora podem direcionar constantes.
- O atributo
#[Override]agora pode ser aplicado a propriedades. - O atributo
#[Deprecated]pode ser usado em traits e constantes. - Um novo atributo
#[DelayedTargetValidation]pode ser usado para suprimir erros de compilação gerados por atributos do núcleo ou de extensões quando eles são aplicados a alvos inválidos.
Depreciações e remoções no PHP 8.5
A cada versão do PHP, uma lista de funcionalidades é marcada para remoção em versões futuras. Usar recursos obsoletos no seu código acionará avisos. Quando finalmente removidos do PHP, seu uso poderá resultar em erros fatais.
Aqui estão alguns elementos notáveis que foram descontinuados ou removidos no PHP 8.5:
- O operador backtick como um alias para
shell_exec()foi descontinuado. - Nomes de cast não canônicos
(boolean),(integer),(double)e(binary)foram descontinuados. Em vez disso, use(bool),(int),(float)e(string). - A configuração disable_classes INI foi removida, pois causa a quebra de várias suposições do mecanismo.
- O término das instruções
casecom ponto e vírgula em vez de dois pontos foi descontinuado. - O uso de
nullcomo índice de array ou ao chamararray_key_exists()agora é descontinuado. Use uma string vazia. - Não é mais possível usar “array” e “callable” como nomes de alias de classe em
class_alias(). - Os métodos mágicos
__sleep()e__wakeup()foram suavemente descontinuados. Em vez disso, os métodos mágicos__serialize()e__unserialize()devem ser usados. - Um aviso agora é emitido quando você converte NAN em outros tipos.
- Desestruturar valores que não são arrays (exceto
null) usando[]oulist()agora emite um aviso. - Agora um aviso é emitido ao converter floats (ou strings que parecem floats) para
intquando eles não podem ser representados como tal.
Resumo
Essa foi uma visão geral dos destaques da versão PHP 8.5. Estamos confiantes de que o novo operador pipe e o parsing aprimorado de URIs serão populares entre desenvolvedores. Talvez até mesmo as novas funções array_first() e array_last(), que muitos poderiam jurar que já existiam.
Mas qualquer nova versão do PHP engloba centenas de alterações. Você pode encontrar uma lista completa das atualizações do PHP 8.5 no repositório oficial do PHP Group no GitHub.
Enquanto isso, aqui na Kinsta, estamos trabalhando para disponibilizar o PHP 8.5 para nossos clientes de hospedagem para WordPress. Quando estiver disponível, você poderá migrar para a nova versão usando nossas ferramentas de configuração de PHP.