Sistemas

PHP 8.5 na prática: menos código repetido e menos dor de cabeça

Pipe, clone com alterações, NoDiscard, arrays, URLs e cURL: veja como o PHP 8.5 ajuda a reduzir repetição e resolver dores do dia a dia, com exemplos práticos.

Elefante roxo em uma mesa de programação, com notebook e o título PHP 8.5.
PHP 8.5: recursos para simplificar o código e reduzir dores do dia a dia. · Crédito: Ilustração editorial criada com inteligência artificial para ernani.dev.

Sabe aquele código que funciona, mas dá um pequeno cansaço só de abrir o arquivo? Função dentro de função, objeto copiado na mão, retorno importante que alguém esqueceu de conferir... Quem mantém sistemas conhece bem esse tipo de dor de cabeça.

O PHP 8.5, lançado em 20 de novembro de 2025, trouxe recursos que ajudam justamente nessas tarefas. E a parte interessante está nos detalhes: menos repetição, transformações mais fáceis de acompanhar e avisos que podem revelar distrações antes que elas virem um chamado de suporte. A data e os destaques estão no anúncio oficial da versão.

Vamos olhar para problemas concretos e para o que dá para melhorar no código.

1. Operador pipe: acompanhar o caminho de um dado ficou mais fácil

Imagine receber códigos de produtos por uma planilha. Alguns chegam com espaços nas pontas; outros, em letras minúsculas. Para padronizar um identificador que usa letras de A a Z, você poderia escrever:

$codigo = strtoupper(trim('  ab-123  '));

Funciona perfeitamente. Só que, conforme surgem mais transformações, as chamadas aninhadas vão ficando trabalhosas de ler.

Com o operador |>, você escreve as etapas na ordem em que acontecem:

$codigo = '  ab-123  '
    |> trim(...)
    |> strtoupper(...);

echo $codigo; // AB-123

Leia assim: “pegue o texto, retire os espaços das pontas e transforme as letras em maiúsculas”. Cada etapa recebe o resultado da anterior. Os três pontos em trim(...) fazem parte da sintaxe que transforma a função em um callable; não são um pedaço de código que ficou faltando.

Onde ajuda: importação de cadastros, preparação de dados recebidos por APIs e sequências de transformação. O ganho apresentado aqui é de leitura e manutenção, especialmente quando o fluxo cresce.

Documentação do operador pipe.

Exemplo do operador pipe no PHP 8.5: o código ab-123 perde os espaços nas pontas com trim e passa para maiúsculas com strtoupper.

O resultado de uma etapa vira a entrada da próxima. Ilustração didática produzida para ernani.dev.

2. Copiar um objeto mudando só o necessário

Pense em uma configuração de integração: normalmente, o tempo limite é de 10 segundos, mas uma importação específica precisa de 60. Você quer criar uma configuração derivada e preservar a original.

O PHP 8.5 permite passar as alterações diretamente para clone(), inclusive ao criar cópias de objetos com propriedades readonly:

final readonly class ConfiguracaoApi
{
    public function __construct(
        public string $endpoint,
        public int $timeout,
    ) {}

    public function comTimeout(int $segundos): self
    {
        return clone($this, ['timeout' => $segundos]);
    }
}

$padrao = new ConfiguracaoApi('https://api.example.com', 10);
$importacao = $padrao->comTimeout(60);

echo $padrao->timeout;     // 10
echo $importacao->timeout; // 60

A dor que diminui: repetir todas as propriedades para reconstruir um objeto só porque um campo mudou. Isso fica especialmente útil em configurações e objetos que representam valores e devem permanecer imutáveis.

No exemplo, a alteração acontece dentro da própria classe, respeitando as regras de visibilidade. E vale guardar um detalhe: a clonagem continua sendo rasa; objetos armazenados dentro de outros objetos não são duplicados automaticamente.

Documentação de clonagem.

3. NoDiscard: um “ei, você esqueceu de olhar o resultado!”

Uma função pode responder se há estoque suficiente. Mas chamar essa função e ignorar a resposta não faz o sistema tomar decisão nenhuma. É aquele clássico “a validação existe, mas ninguém usou”.

O atributo #[\NoDiscard] permite sinalizar que o retorno de uma função merece atenção:

#[\NoDiscard]
function estoqueSuficiente(int $disponivel, int $pedido): bool
{
    return $disponivel >= $pedido;
}

estoqueSuficiente(2, 5); // Warning: o retorno foi ignorado.

Para usar o resultado na decisão:

if (!estoqueSuficiente(2, 5)) {
    echo 'Estoque insuficiente para esse pedido.';
}

Onde ajuda: funções de validação, operações que devolvem um resultado relevante e métodos que retornam uma nova versão de um objeto.

O PHP emite um aviso quando o retorno é descartado. A regra de negócio continua por nossa conta: atribuir o resultado a uma variável já conta como uso, e o atributo não bloqueia uma venda automaticamente. É um lembrete útil para o programador, não uma implementação completa de controle de estoque.

Documentação de NoDiscard.

4. Primeiro e último item de um array, sem complicar

Às vezes, a necessidade é simples: pegar o primeiro status de um pedido ou o último evento de uma lista. O detalhe é que o array pode ter chaves textuais, índices que não começam em zero ou estar vazio.

Agora existem array_first() e array_last():

$status = [
    'recebimento' => 'Pedido recebido',
    'separacao' => 'Separação concluída',
    'transporte' => 'Saiu para entrega',
];

echo array_first($status); // Pedido recebido
echo array_last($status);  // Saiu para entrega

As funções retornam os valores das pontas do array. Se ele estiver vazio, retornam null.

Parece uma novidade pequena, e é mesmo. Mas reduzir uma expressão repetitiva a uma função com nome claro facilita bastante a leitura de um sistema grande.

Só cuidado com o significado de “último”: ele segue a ordem do array. Para encontrar o evento mais recente por data, é preciso garantir essa ordenação antes. E null também pode ser um valor armazenado; sozinho, esse resultado não prova que a lista estava vazia.

Documentação de array_first() e array_last().

5. URLs com uma estrutura melhor para trabalhar

Quem integra sistemas acaba montando e alterando muitos endereços: consulta de produtos, paginação, filtros e links de retorno. Fazer tudo com concatenação de strings exige atenção a cada separador e componente.

A nova extensão URI oferece classes que seguem os padrões RFC 3986 e WHATWG. Um exemplo com a classe baseada na RFC 3986:

use Uri\Rfc3986\Uri;

$paginaAtual = new Uri(
    'https://api.example.com/produtos?pagina=1'
);

$proximaPagina = $paginaAtual->withQuery('pagina=2');

echo $proximaPagina->toString();
// https://api.example.com/produtos?pagina=2

A melhoria prática: alterar um componente do endereço por uma API própria para isso. Nesse exemplo, withQuery() cria uma nova instância, preservando a anterior.

Duas observações evitam confusão: esse método substitui a query inteira, então outros filtros precisam ser incluídos se você quiser mantê-los. E interpretar uma URL conforme um padrão não define quais destinos sua aplicação deve aceitar; essa regra continua no sistema.

Documentação da extensão URI e do método withQuery().

6. Integrações podem reaproveitar trabalho com cURL

Se o sistema consulta repetidamente a mesma API, parte do trabalho está em resolver o domínio e estabelecer conexões. O PHP 8.5 adiciona curl_share_init_persistent(), que permite manter estruturas de compartilhamento do cURL entre requisições PHP em ambientes com processos duradouros.

Quando configurado para isso, o recurso pode reaproveitar informações de DNS e conexões. É uma possibilidade interessante para um painel que consulta serviços externos com frequência.

O problema que ele ajuda a reduzir: repetir etapas de comunicação que poderiam ser reaproveitadas. O ganho depende do ambiente, da configuração do cliente HTTP e do comportamento da API. Só atualizar o PHP não faz toda integração adotar esse recurso automaticamente.

Documentação de compartilhamento persistente do cURL.

E na hora de atualizar?

Minha sugestão é começar por um ambiente de testes: conferir framework e dependências, executar os fluxos principais e observar os avisos. Importação, checkout, login e tarefas agendadas merecem entrar nessa rodada.

O PHP 8.5 também traz depreciações. Por exemplo, os casts (integer), (boolean) e (double) devem dar lugar a (int), (bool) e (float). Os recursos depreciados e as mudanças incompatíveis estão documentados no guia oficial.

Os exemplos acima mostram novas maneiras de tratar problemas conhecidos. Você pode adotar cada recurso onde ele deixa o código mais claro, sem precisar transformar a atualização em uma reescrita completa.

Para quem mantém sistemas no dia a dia, esse é um bom motivo para olhar com carinho para o PHP 8.5: facilitar o trabalho de hoje e deixar um código mais tranquilo de entender daqui a seis meses.

Qual dessas novidades você colocaria primeiro em um projeto seu?

EN

Ernani Nascimento

Desenvolvimento de sistemas, inteligência artificial, automações, dados e jogos. Um espaço para compartilhar experiências e aprendizados construindo projetos reais.

Conheça o autor ↗

Continue explorando.

DA IDEIA À PRÁTICA

Tem algo em mente?
Vamos construir.

Vamos conversar ↗