Novidades do PHP 8.4

Novidades do PHP 8.4

Sendo uma das linguagens de programação mais utilizadas da atualidade, segundo relatório da W2Tech, principalmente em ambientes Web, o PHP recebe atualizações frequentes e sua nova versão major, o PHP 8.4, chega repleta de novidades.

Quando será o lançamento do PHP 8.4?

Antes de mergulharmos nas novidades que estarão disponíveis no PHP 8.4, é importante citar que no momento da escrita desse texto, a versão mais recente do PHP é a 8.3 (mais especificamente, 8.3.10).

A versão 8.4 do PHP está prevista para ser lançada em novembro de 2024, segundo a página oficial de preparação do lançamento da versão.

Banner promocional da Alura, com um design futurista em tons de azul, apresentando dois blocos de texto, no qual o bloco esquerdo tem os dizeres:

Novas funcionalidades do PHP 8.4

Existem mais de 40 RFCs (Request for Comments) descrevendo novidades do PHP 8.4. Então, obviamente, seria inviável listar todas aqui, mas vamos enumerar algumas.

Chamada de métodos em inicialização de objeto sem parênteses

Começando por uma bem simples, que outras linguagens já permitem há bastante tempo, é a possibilidade de chamar métodos de um objeto em sua inicialização sem a necessidade de utilizar parênteses. Para nós chamarmos um método de um objeto que acabamos de inicializar, em PHP, precisaríamos envolver a criação dele em parêntesis, da seguinte forma:

(new MinhaClasse())->meuMetodo();

A partir da versão 8.4, isso não será mais necessário, e poderemos fazer simplesmente:

new MinhaClasse()->meuMetodo();

Aumento do custo padrão de password hashing com BCrypt

A próxima também é muito simples, mas bastante especial para mim, pois eu participei da discussão que gerou essa RFC.

Para armazenar senhas de forma segura, realizamos um processo chamado hashing de senha. Esse processo precisa ter um custo computacional relativamente alto, por motivos de segurança.

Ao iniciar uma discussão sobre o uso do melhor algoritmo de hashing de senhas, "sem querer" eu incentivei o aumento do custo, e consequentemente da segurança, do custo padrão de hashing de senhas no PHP.

Sendo assim, ao chamar a famosa função password_hash, a partir do PHP 8.4 o custo será maior, tornando o armazenamento de senhas ainda mais seguro.

Acesso a propriedades com property hooks

Após duas pequenas novidades, vamos a uma das mais interessantes e faladas do PHP 8.4. A funcionalidade de property hooks chega para permitir que uma lógica seja executada ao acessar alguma proprieadade de um objeto.

Isso funcionará de forma similar aos métodos mágicos do PHP, mas de forma mais específica, tendo a definição de um bloco de código para ser executado ao acessar uma propriedade específica.

Se eu quiser que, ao acessar uma propriedade $nomeCompleto de um objeto da classe Usuario, eu possa retornar a junção das propriedades $nome e $sobrenome, agora é possível da seguinte forma:

class Usuario {
    public string $nomeCompleto {
        get => $this->nome . ' ' . $this->sobrenome;
    }
    public function __construct(private string $nome, private string $sobrenome) {}
}

$usuario = new Usuario('Vinicius', 'Dias');
echo $usuario->nomeCompleto; // Vinicius Dias

Há diversas nuances e possibilidades com essa nova funcionalidade e eu gravei um vídeo explicando alguns desses detalhes. Você pode assistí-lo a seguir:

Novas funções para manipulação de arrays

Para simplificar um pouco, vamos a outra novidade um pouco menor: novas funções para manipularmos arrays em PHP.

array_find

A primeira função que vamos ver se chama array_find e espera dois parâmetros: um array e outra função.

Essa função passada por parâmetro verificará se um item do array atende a uma condição e, caso atenda, o item será retornado. Caso contrário, o valor null será retornado.

Se eu quiser buscar em um array de notas, por exemplo, a primeira nota que seja maior que 7, eu poderia fazer da seguinte forma:

$notas = [5, 6, 7, 8, 9, 10];
$nota = array_find($notas, fn(int $nota): int => $nota > 7); // 8

É importante notar que, caso haja mais de um item que atenda a condição, apenas o primeiro será retornado, e se nenhum item atender, o valor null será retornado.

A função passada por parâmetro pode receber 1 ou 2 parâmetros, sendo o primeiro cada item do array em questão e o segundo sendo a chave correspondente a esse item.

array_find_key

Muito similar à array_find, há também a array_find_key, que funciona de forma análoga, mas ao invés de retornar o item que atende a condição, ela retorna a chave desse item.

$notas = [5, 6, 7, 8, 9, 10];
$chave = array_find_key($notas, fn(int $nota): int => $nota > 7); // 3

array_any

Já a função array_any irá retornar verdadeiro se a função passada por parâmetro retornar verdadeiro para qualquer um dos elementos, ou falso caso contrário.

Ela serve para verificar se algum elemento atende à condição especificada e não para buscar o elemento em si.

Ou seja, caso eu queria apenas verificar se alguma nota foi maior do que 7, posso fazer o seguinte:

$notas = [5, 6, 7, 8, 9, 10];
$algumaNotaMaiorQue7 = array_any($notas, fn(int $nota): bool => $nota > 7); // true

array_all

E de forma muito similar, a função array_all verifica se todos os elementos de um array atendem a uma condição. Caso todos atendam, a função retornará verdadeiro, caso contrário, falso.

Se eu quero verificar se todas as notas são maiores que 7, eu poderia fazer:

$notas = [5, 6, 7, 8, 9, 10];
$todasNotasMaiorQue7 = array_all($notas, fn(int $nota): bool => $nota > 7); // false

Parsing de HTML5 e mais novidades para a extensão DOM

O PHP permite que nós não só forneçamos dados em HTML, mas nós também podemos consumir e manipular dados em HTML de fontes externas. Isso é muito comum, por exemplo, para fazer web scraping.

Há diversas bibliotecas que facilitam o processo de parsing de HTML em PHP, mas isso também é possível nativamente, sem bibliotecas externas, através da extensão PHP DOM.

Porém, ao realizar o parsing de documentos HTML5, alguns avisos eram emitidos, o que além de ser incoveniente e poder ser confundido com erros, traz um impacto negativo na performance.

A partir do PHP 8.4 o parsing de HTML5 é suportado, além de novas funcionalidades terem sido adicionadas a essa extensão DOM.

Agora é possível utilizarmos seletores CSS para percorrer o DOM, há novas classes como DOM\HTMLDocument e DOM\XMLDocument além da já conhecida DOMDocument, dentre outras novidades.

Um simples exemplo de código que faz o parsing de um documento HTML5 e exibe o título da página:

$html = file_get_contents('https://dias.dev');
$dom = DOM\HTMLDocument::createFromString($html);

echo $dom->title;

Como há mais detalhes e novidades na extensão DOM, eu também gravei um vídeo com essas informações a mais e você pode conferí-lo aqui:

Visibilidade assimétrica

O PHP, assim como a maioria das linguagens de programação orientadas a objetos, permite a definição de visibilidade de suas propriedades.

O "problema" é que essa visibilidade é necessariamente a mesma para leitura e escrita, ou seja, se uma propriedade é privada, ela não pode ser lida nem escrita de fora da classe.

A partir do PHP 8.4 será possível especificar uma visibilidade para a leitura e outra para a escrita dos valores em propriedades, permitindo, por exemplo, que uma propriedade possa ser lida de fora da classe, mas não escrita.

Se eu quiser permitir que o $email de um objeto da classe Usuario seja acessado para leitura, mas não permitir que ele seja modificado, podemos ter o seguinte código:

class Usuario {
    public function __construct(private(set) string $email) {}
}

$usuario = new Usuario('[email protected]');
echo $usuario->email; // Funciona sem problemas
$usuario->email = '[email protected]'; // Gera um erro

Atributo #[\Deprecated] para marcar códigos obsoletos

Durante a evolução de uma base de código, é comum que funções, métodos e até constantes se tornem obsoletos e novas "versões" para atingir o mesmo objetivo sejam criadas.

Por exemplo, uma nova função ser criada com um número maior de parâmetros, mas executando a lógica de forma mais otimizada, uma constante sendo substituída por uma Enum, etc.

Para marcarmos nossos códigos como obsoletos, agora podemos utilizar o atributo #[\Deprecated]. Isso não só serve para documentar o código, mas também para que IDEs possam alertar sobre o uso de códigos obsoletos e para que futuras versões do PHP possam emitir avisos sobre o uso de códigos obsoletos.

#[\Deprecated("Use a função 'nova()'", since: "1.0.0")]
function antiga() {
    // ...
}

function nova() {
    // ...
}

antiga(); // Aviso de código obsoleto será exibido

Se quiser ver essa funcionalidade em ação, adivinha? Tenho um vídeo a respeito:

Nova implementação do compilador JIT, baseado no IR Framework

Nós já discutimos diversas novidades "visíveis" para o usuário final, mas o PHP 8.4 também traz muitas melhorias por baixo dos panos.

O compilador JIT (Just in Time) do PHP recebeu algumas novidades, sendo a principal uma nova implementação baseada no famoso framework Intermediate Representation (IR).

Essa nova implementação remove algumas limitações e permite mais otimizações por parte do compilador.

Além disso, há também outra novidade que é como o JIT Compiler do PHP vem desabilitado por padrão. Atualmente, essas são as configurações padrão relacionadas a JIT:

opcache.jit=tracing
opcache.jit_buffer_size=0

Isso desabilita o JIT porque o tamanho do buffer é definido como 0, mas é um pouco confuso já que o modo de JIT é definido como tracing.

A partir do PHP 8.4, o modo de JIT padrão será disable, e o tamanho do buffer será de 64m por padrão. Com isso, caso queiramos habilitar o JIT, já teremos um tamanho de buffer definido.

Se você não está familiarizado com o compilador JIT do PHP, eu gravei um vídeo explicando o que é e como ele funciona, e você pode assisti-lo a seguir:

Mais novidades

Como foi dito no início, há muitas novidades no PHP 8.4, e as que foram listadas aqui são apenas algumas delas. Se quiser conferir todas elas em detalhes, você pode acessar a página oficial de RFCs do PHP.

Descontinuações do PHP 8.4

Nem só de novas funcionalidades vive uma versão, então o PHP também traz algumas descontinuações. Vamos falar aqui sobre algumas poucas delas.

Suporte a tipos de parâmetros nullable implícitos

Até a versão 8.3 do PHP, era possível definir um tipo de parâmetro e definir um valor padrão para ele como null, da seguinte forma:

function minhaFuncao(string $parametro = null) {
    echo $parametro;
}
minhaFuncao(null);

O código acima é possível até o PHP 8.3, ou seja, posso passar o valor null como parâmetro mesmo o tipo sendo definido como string, pois ter null como valor padrão torna o tipo nullable.

A partir do PHP 8.4 esse código gerará um aviso Deprecated, informando que caso queira permitir o uso de null, você deve definir o parâmetro como nullable.

Sessões GET e POST

Sessões no PHP, assim como em outras linguagens, são uma forma de manter o estado de uma aplicação entre requisições. O PHP permite que você armazene dados em sessões, e por padrão, essas sessões são armazenadas em Cookies.

O problema é que, além de Cookies, que podem ser seguros, há outras formas de enviar o seu ID de sessão para o PHP, como através da URL ou no corpo de uma requisição POST.

A partir do PHP 8.4 essa prática é marcada como obsoleta e definir session.use_only_cookies=Off, por exemplo, emitirá um aviso de obsolência.

Outras obsolências

Além dessas principais descontinuações, há diversas funções, parâmetros e comportamentos que serão marcados como obsoletos.

Você pode conferir a lista completa na RFC de descontinuações para o PHP 8.4.

Como aprender mais sobre PHP

O PHP está evoluindo cada vez mais e há muito tempo já é uma linguagem robusta, madura, escalável e confiável para projetos de todos os portes.

Se você quiser aprender sobre PHP do zero, pode começar pela formação de PHP na Alura, mas caso já saiba bem PHP e queira se aprofundar ainda mais, há diversas opções como as formações de Boas práticas em PHP e Escalabilidade e Arquitetura de Sistemas PHP.

Vinicius Dias
Vinicius Dias

Vinicius Dias é Zend Certified Engineer (Engenheiro PHP Certificado pela Zend), iMasters Certified Professional, formado em Tecnologia da Informação e pós-graduado em Arquitetura de Software. Com mais de uma década de experiência na área, já trabalhou em diversas empresas ao redor do mundo, sendo atualmente Engenheiro de Software Senior em uma empresa estadunidense. Tem como lema a regra do bom escoteiro: Sempre deixe o código mais limpo do que quando você o encontrou.

Veja outros artigos sobre Programação