PHP 8.5 adiciona pipe operator nativo: o que muda para quem mantém monolito em produção
Disponível desde novembro de 2025, o operador |> troca encadeamentos aninhados por uma leitura de cima para baixo. Mas ele só resolve parte do problema de legibilidade que existe em bases PHP antigas.

Disponível desde novembro de 2025, o operador |> troca encadeamentos aninhados por uma leitura de cima para baixo. Mas ele só resolve parte do problema de legibilidade que existe em bases PHP↳PHP44 conteúdosPadronizando seu código com PHP CS FixerDev (Back & Front) · mai 2019Docker de imagem. Para rodar projetos PHP em menos de 30 segundosDev (Back & Front) · jan 2026PHP 7.3: conheça as novidades desta versãoDev (Back & Front) · abr 2019Ver tudo em Dev (Back & Front) → antigas.
O PHP 8.5 foi lançado em 20 de novembro de 2025, segundo as notas oficiais de release publicadas no php.net. Entre as novidades da versão, listadas ao lado da extensão de URI nativa e do clone() com atualização de propriedades, está o operador de pipe (|>), que permite encadear chamadas de função da esquerda para a direita sem variáveis intermediárias.
Quase um ano depois do lançamento, a pergunta que interessa a quem mantém sistema em produção não é "o que é", e sim "vale reescrever o que já funciona". A resposta, como quase tudo em manutenção de legado, é: depende de qual legado.
O problema que o pipe operator ataca
Código PHP legado tem uma praga visual conhecida: funções aninhadas que precisam ser lidas de dentro para fora. O próprio exemplo das release notes do PHP 8.5 mostra isso com um gerador de slug a partir de um título:
$title = 'PHP 8.5 Released';
$slug = strtolower(
str_replace('.', '',
str_replace(' ', '-',
trim($title)
)
)
);
var_dump($slug);
// string(15) "php-85-released"Para entender a ordem real de execução, o olho precisa ir até o parêntese mais interno (trim) e trabalhar de volta para fora. Em cadeias curtas isso é só desconfortável; em cadeias de seis ou sete chamadas, comuns em pipelines de normalização de dados em sistemas antigos, vira uma fonte real de bug silencioso.
O mesmo código com o novo operador
Com o |>, a mesma transformação fica assim, segundo o exemplo das notas de lançamento:
$slug = $title
|> trim(...)
|> (fn($str) => str_replace(' ', '-', $str))
|> (fn($str) => str_replace('.', '', $str))
|> strtolower(...);Agora a leitura segue a ordem de execução: pega o título, tira espaços nas pontas, troca espaço por hífen, remove ponto, deixa minúsculo. Repare que trim(...) e strtolower(...) usam a sintaxe de callable de primeira classe, introduzida no PHP 8.1 - quem mantém base em versão anterior a essa já não tem essa peça disponível, então o pipe operator carrega uma dependência implícita de recursos mais recentes da linguagem.
A pegadinha: o pipe só passa um argumento
O detalhe que o exemplo acima esconde é por que str_replace precisou ser embrulhado em closures (fn($str) => ...) em vez de aparecer direto como str_replace(' ', '-', ...). O operador |> sempre passa o valor da esquerda como único argumento para o callable da direita. Funções como str_replace(), que exigem três argumentos obrigatórios, não encaixam diretamente na cadeia.
Na prática, isso significa que refatorar um pipeline legado para |> só é direto quando as funções envolvidas são unárias de verdade: trim(), strtoupper(), htmlspecialchars() com argumentos default, um método de objeto sem parâmetro extra. Assim que aparece uma função como str_replace(), preg_replace() ou qualquer helper interno que recebe configuração além do valor, a refatoração exige envolver a chamada numa função anônima - o que devolve parte da verbosidade que o operador prometia eliminar.
Comparando com o que o ecossistema já fazia
Quem trabalha com Laravel ou com pacotes como league/pipeline costuma conviver com algum padrão de pipeline implementado em userland, geralmente via classes que recebem um array de "stages" e os executam em sequência. Sem entrar no contrato exato de cada biblioteca (isso varia de implementação para implementação e não é o foco aqui), a tabela resume a diferença estrutural em relação ao operador nativo:
| Pipeline em userland (padrão geral) | Operador ` | >` nativo | |
|---|---|---|---|
| Requer pacote externo | Sim | Não | |
| Suporta abortar a cadeia no meio (early return) | Depende da implementação | Não, é só composição de chamadas | |
| Passa múltiplos argumentos entre etapas | Depende da implementação | Não, sempre um valor só | |
| Funciona em versão de PHP anterior a 8.5 | Sim | Não | |
| Overhead de aprender API de terceiros | Sim | Não, é sintaxe da linguagem |
Em resumo: o |> nativo resolve o caso simples - transformar um valor em sequência de etapas puras - sem precisar de dependência. Ele não substitui, por si só, um pipeline de middleware com controle de fluxo, tratamento de exceção por etapa ou log entre estágios, recursos que soluções de pipeline em userland como Laravel's Pipeline costumam oferecer a mais, dependendo de como cada uma é implementada.
Quando vale refatorar um monolito legado
Faz sentido trocar encadeamento aninhado por |> quando:
- A base já roda em PHP 8.5 (ou vai migrar para lá de qualquer forma) e não depende de compatibilidade retroativa com versão anterior.
- O trecho é uma cadeia de transformação pura de dado (normalização de string, formatação, sanitização) com funções que aceitam só o valor como argumento relevante.
- O código hoje é difícil de revisar em code review porque exige ler de dentro para fora - esse é o sintoma clássico que o operador resolve bem.
Quando não vale
Em contrapartida, a refatoração tende a não compensar quando:
- O projeto ainda está preso a PHP 8.1, 8.2 ou 8.3 por causa de dependência de framework ou extensão - nesse caso o
|>simplesmente não existe na versão em produção, e forçar a migração só para ganhar um operador de sintaxe é trocar seis por meia dúzia em termos de risco. - A cadeia mistura funções unárias com funções de múltiplos argumentos obrigatórios, forçando a reescrever metade das chamadas como closures - o ganho de legibilidade fica marginal e a mudança introduz risco de regressão num código que já funcionava.
- O time de manutenção é pequeno e já está sobrecarregado com dívida técnica mais urgente; reescrever uma cadeia de
strtolower/trimque já está testada e estável por puro gosto estético raramente é a prioridade certa.
O contexto maior do release
O pipe operator não veio sozinho. O mesmo PHP 8.5 trouxe a extensão de URI nativa (substituindo o uso de parse_url() por uma API orientada a objeto, Uri\Rfc3986\Uri), o atributo #[\NoDiscard] para avisar quando um valor de retorno é ignorado, e clone() com atualização de propriedades para simplificar o padrão "with-er" em classes readonly. Para quem decide se vale subir a versão do runtime de um monolito, o pipe operator isolado raramente é motivo suficiente - a decisão de migração costuma pesar o conjunto de features junto com o fim de suporte das versões anteriores, não um operador de sintaxe específico.
Este artigo foi escrito por Bisneto Braga, colunista de back-end. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.
GitHub bloqueia por padrão pushes com chaves da Anthropic e adiciona Salesforce ao secret scanning
A partir de hoje, o secret scanning do GitHub detecta chaves da Anthropic, Salesforce e Cloudsmith, e os tokens da Anthropic já entram bloqueados por padrão no push protection. Veja o que isso muda em repositórios públicos e privados.














