Lançado em 25 de novembro de 2021, o PHP 8.1 está finalmente aqui, repleto de várias funcionalidades interessantes.

Neste artigo, vamos cobrir em detalhes o que há de novo no PHP 8.1. Desde suas novas funcionalidades e melhorias de desempenho até mudanças e depreciações significativas, vamos passar por todas elas em profundidade.

Vamos nessa!

Novas funcionalidades do PHP 8.1

Vamos começar cobrindo todas as novas funcionalidades do PHP 8.1. É uma lista e tanto.

Pure Intersection Types

O PHP 8.1 adiciona suporte para Pure Intersection Types. É similar aos union types introduzidos no PHP 8.0, mas seu uso pretendido é exatamente o oposto.

Para entender melhor o seu uso, vamos refrescar como funcionam as declarações type no PHP.

Essencialmente, você pode adicionar declarações type a argumentos de função, valores de retorno e propriedades de classe. Essa atribuição é chamada de sugestão type e garante que o valor seja do tipo correto no momento da chamada. Caso contrário, ele lança um TypeError imediatamente. Por sua vez, isso ajuda a depurar melhor o código.

No entanto, declarar um único type tem as suas limitações. Union types ajudam a superar isso, permitindo que você declare um valor com vários types, e a entrada tem que satisfazer pelo menos um dos types declarados.

Por outro lado, a RFC descreve os Intersection Types como:

Um “Intersection Types” requer um valor para satisfazer restrições de vários types em vez de um único.

…Pure Intersection Types são especificados usando a sintaxe T1&T2&… e podem ser usadas em todas as posições onde os types são aceitos atualmente…

Observe o uso de & (AND) operador para declarar os Intersection Types. Em contraste, nós usamos o operador | (OR) para declarar os union types.

O uso da maioria dos types padrão em um Intersection Types resultará em um tipo que nunca poderá ser cumprido (por exemplo, integer e string). Assim, os Intersection Types só podem incluir types de classe (ou seja, interfaces e nomes de classe).

Aqui está um exemplo de código mostrando como você pode usar o Intersection Types:

class A {
    private Traversable&Countable $countableIterator;
 
    public function setIterator(Traversable&Countable $countableIterator): void {
        $this->countableIterator = $countableIterator;
    }
 
    public function getIterator(): Traversable&Countable {
        return $this->countableIterator;
    }
}

No código acima, definimos um countableIterator variável como uma interseção de dois types: Traversable e Countable. Neste caso, os dois types declarados são interfaces.

Intersection Types também estão em conformidade com as regras de variância padrão do PHP já utilizadas para verificação de types e herança. Mas há duas regras adicionais com como os Intersection Types interagem com a subtipagem. Você pode ler mais sobre as regras de variância dos Intersection Types em sua RFC.

Em algumas linguagens de programação, você pode combinar UnionTypes e Intersection Types na mesma declaração. Mas o PHP 8.1 o proíbe. Portanto, sua implementação é chamada de Pure Intersection Types. No entanto, a RFC menciona que ela é “deixada como um escopo futuro”.

Enums

O PHP 8.1 está finalmente adicionando suporte para enums (também chamadas de enumerações ou types enumerados). Eles são um tipo de dados definido pelo usuário que consiste em um conjunto de valores possíveis.

O exemplo mais comum de enums em linguagens de programação é o type booleano, com true e false como dois valores possíveis. É tão comum que é utilizado em muitas linguagens de programação modernas.

De acordo com a RFC, enums no PHP serão restritos a “enumerações de unidades” no início:

O escopo desta RFC está limitado a “enumerações unitárias”, ou seja, enumerações que são em si um valor, ao invés de simplesmente uma sintaxe extravagante para uma constante primitiva, e não incluem informações adicionais associadas. Esta capacidade oferece um suporte bastante expandido para modelagem de dados, definições de tipo personalizadas e comportamento no estilo monad. Enums habilitam a técnica de modelagem de “tornar os estados inválidos não representativos”, o que leva a um código mais robusto com menos necessidade de testes exaustivos.

Para chegar a esta fase, a equipe do PHP estudou muitas linguagens que já suportam enumerações. A pesquisa deles descobriu que você pode categorizar as enumerações em três grupos gerais: Fancy Constants, Fancy Objects, e Tipos de dados algébricos completos (ADTs). É uma leitura interessante!

PHP implementa enums “Fancy Objects”, com planos para estendê-lo para ADTs completos no futuro. Ele é conceitual e semanticamente modelado após os tipos enumerados no Swift, Rust e Kotlin, embora não seja modelado diretamente em nenhum deles.

O RFC usa a famosa analogia de naipes em um baralho de cartas para explicar como funcionará:

enum Suit {
  case Hearts;
  case Diamonds;
  case Clubs;
  case Spades;
}

Aqui, o enum Suit define quatro valores possíveis: HeartsDiamondsClubsSpades. Você pode acessar esses valores diretamente usando a sintaxe: Suit::Hearts, Suit::Diamonds, Suit::Clubs, e Suit::Spades.

Este uso pode parecer familiar, uma vez que os enums são construídos sobre classes e objetos. Eles se comportam de forma semelhante e têm quase os requisitos exatos. Os enums compartilham os mesmos namespaces que as classes, interfaces e traços.

Os enums mencionados acima são chamados de Pure Enums.

Você também pode definir os Backed Enums se quiser dar um valor equivalente em escala a qualquer caso. No entanto, os Backed Enums podem ter apenas um type, seja int ou string (nunca ambos).

enum Suit: string {
  case Hearts = 'H';
  case Diamonds = 'D';
  case Clubs = 'C';
  case Spades = 'S';
}

Além disso, todos os diferentes casos de um enumeração apoiada devem ter um valor único. E você nunca pode misturar e pure e backed enums.

A RFC se aprofunda em métodos de enumeração, métodos estáticos, constantes, expressões constantes, e muito mais. Cobri-los a todos está além do escopo deste artigo. Você pode consultar a documentação para se familiarizar com toda a sua bondade.

O type de retorno never

O PHP 8.1 adiciona uma nova dica do type de retorno chamado never. É super útil para usar em funções que sempre throw ou exit.

Segundo a RFC, as funções de redirecionamento de URL que sempre exit (explícita ou implicitamente) são um bom exemplo para o seu uso:

function redirect(string $uri): never {
    header('Location: ' . $uri);
    exit();
}
 
function redirectToLoginPage(): never {
    redirect('/login');
}

Uma função never declarada deve satisfazer três condições:

  • Não deve ter a declaração return definida explicitamente.
  • Não deve ter a declaração return definida implicitamente (por exemplo, declarações if-else).
  • Deve terminar a sua execução com uma declaração exit (explícita ou implicitamente).

O exemplo de redirecionamento de URL acima mostra tanto o uso explícito quanto implícito do tipo never retorno.

O type de retorno never partilha muitas semelhanças com o type de retorno void. Ambos asseguram que a função ou método não retorna um valor. No entanto, ele difere pelo aplicativo de regras mais estritas. Por exemplo, uma função declarada void ainda pode sem um valor explícito return, mas você não pode fazer o mesmo com uma função never declarada.

Como regra geral, vá com void quando você espera que o PHP continue executando após a chamada da função. Vá com never quando você quer o oposto.

Além disso, never é definido como um tipo “inferior”. Portanto, qualquer método de classe declarado never pode “nunca” mudar o seu tipo de retorno para outra coisa. No entanto, você pode estender um método declarado void com um método never declarado.

Fibers

Historicamente, o código PHP tem sido quase sempre código síncrono. A execução do código para até que o resultado seja retornado, mesmo para operações de E/S. Você pode imaginar porque este processo pode tornar a execução do código mais lenta.

Existem várias soluções de terceiros para superar este obstáculo para permitir aos desenvolvedores escrever código PHP de forma assíncrona, especialmente para operações de E/S simultâneas. Alguns exemplos populares incluem amphp, ReactPHP, e Guzzle.

No entanto, não há uma maneira padrão de lidar com tais instâncias no PHP. Além disso, tratar código síncrono e assíncrono na mesma call stack leva a outros problemas.

Fibers são a forma do PHP lidar com o paralelismo através de threads virtuais (ou green threads). Ela procura eliminar a diferença entre código síncrono e assíncrono, permitindo que funções PHP interrompam sem afetar toda a call stack.

Aqui está o que o RFC promete:

  • Adicionar suporte para Fibers ao PHP.
  • Apresentar uma nova classe de Fiber e a correspondente classe de reflexão ReflectionFiber.
  • Adicionar as classes de exceção FiberError e FiberExit para representar erros.
  • Fibers permitem implementações transparentes de E/S sem bloqueio das interfaces existentes (PSR-7, Doctrine ORM, etc.). Isso porque o objeto placeholder (promessa) é eliminado. Ao invés disso, as funções podem declarar o tipo de resultado de I/O em vez de um objeto placeholder que não pode especificar um tipo de resolução porque o PHP não suporta genéricos.

Você pode usar Fibers para desenvolver funções de PHP com full-stack e interruptível, que você pode então usar para implementar multitarefas cooperativas em PHP. Como Fibers pausa toda a execution stack, você pode ficar tranquilo sabendo que não prejudicará o resto do seu código.

Gráfico que ilustra o fluxo de execução do código PHP com Fibras
Gráfico que ilustra o fluxo de execução do código PHP com Fibras (Fonte: PHP.net).

Para ilustrar o uso de Fibers, o seu RFC usa este exemplo simples:

$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('fiber');
    echo "Value used to resume fiber: ", $value, "\n";
});
 
$value = $fiber->start();
 
echo "Value from fiber suspending: ", $value, "\n";
 
$fiber->resume('test');

Você está criando uma “Fiber” no código acima e suspendendo-a imediatamente com a fiber da string. A declaração de echo serve como um sinal visual para a retomada da Fiber .

Você pode recuperar o valor desta string a partir da chamada para $fiber-> start().

Em seguida, você retoma a Fiber com a string “test”, que é retornada da chamada para Fiber::suspend(). A execução completa do código resulta em uma saída que lê:

Value from fiber suspending: fiber
Value used to resume fiber: test

Esse é o exemplo de barebones textbook do PHP Fibers no trabalho. Aqui está outro exemplo de Fibers de realizar sete pedidos de GET assíncronos.

Com tudo o que foi dito e feito, a maioria dos desenvolvedores de PHP nunca irão lidar com Fibers diretamente. E a RFC até sugere o mesmo:

Fibers são um recurso avançado que a maioria dos usuários não irá usar diretamente. Este recurso é destinado principalmente aos autores de bibliotecas e framework para fornecer um loop de eventos e uma API de programação assíncrona. As Fibers permitem integrar perfeitamente a execução assíncrona de código em código síncrono em qualquer ponto sem a necessidade de modificar a call stack de aplicativo ou adicionar o código boilerplate.

Não se espera que o Fiber API seja usado diretamente no código em nível de aplicativo. Fibers fornecem um API básico de baixo nível de controle de fluxo para criar abstrações de nível superior que são então utilizadas em código de aplicativo.

Considerando seus benefícios de desempenho, você pode esperar que as bibliotecas e frameworks PHP aproveitem esta nova funcionalidade. Será interessante ver como elas implementam as Fibers dentro do seu ecossistema.

Novas propriedades readonly

O PHP 8.1 adiciona suporte para propriedades readonly. Elas só podem ser inicializadas uma vez a partir do escopo onde são declaradas. Uma vez inicializados, você não pode modificar o valor deles nunca. Fazendo isso, você pode lançar uma exceção de erro.

RFC diz:

Uma propriedade readonly só pode ser inicializada uma vez, e apenas a partir do âmbito onde foi declarada. Qualquer outra atribuição ou modificação da propriedade resultará em uma exceção de erro.

Aqui está um exemplo de como você pode usá-lo:

class Test {
    public readonly string $kinsta;
 
    public function __construct(string $kinsta) {
        // Legal initialization.
        $this->kinsta = $kinsta;
    }
}

Uma vez inicializado, não há volta a dar. Ter esta funcionalidade cozinhada em PHP reduz muito o código boilerplate que é frequentemente usada para ativar esta funcionalidade.

A propriedade readonly oferece uma forte garantia de imutabilidade, tanto dentro como fora da classe. Não importa o código que corre no meio. Chamando uma propriedade readonly irá sempre devolver o mesmo valor.

No entanto, o uso da propriedade readonly pode não ser o ideal em casos de uso específico. Por exemplo, você só pode usá-los ao lado de um bem digitado porque as declarações sem um tipo são implicitamente null e não podem ser readonly.

Além disso, definir uma propriedade readonly não torna os objetos imutáveis. A propriedade readonly irá segurar o mesmo objeto, mas esse objeto em si pode mudar.

Outra questão menor com esta propriedade é que não se pode cloná-la. Já há uma solução para este caso de uso em particular. Se for necessário, investigue isso.

Definir constantes de classe final

A partir do PHP 8.0, você pode sobrepor constantes de classe com suas child classes. É devido à forma como a herança é implementada no PHP.

Aqui está um exemplo de como você pode anular o valor de uma constante declarada anteriormente:

class Moo
{
    public const M = "moo";
}
 
class Meow extends Moo
{
    public const M = "meow";
}  

Agora, se as vacas querem ficar mais rígidas com o comportamento dos gatos (pelo menos com constantes), elas podem fazê-lo com o novo modificador final do PHP 8.1.

Uma vez declarada uma constante como final, isso significa que.

class Moo
{
    final public const M = "moo";
}
 
class Meow extends Moo
{
    public const M = "meow";
}
 
// Fatal error: Meow::M cannot override final constant Moo::M

Você pode ler mais sobre isso nas constantes finais da classe PHP RFC.

Novas funções fsync()fdatasync()

O PHP 8.1 adiciona duas novas funções de sistema de arquivos chamadas fsync() e fdatasync(). Eles vão parecer familiares para aqueles usados para funções Linux com o mesmo nome. Isso é porque elas são relacionadas, apenas implementadas para o PHP.

Na verdade, esta adição já devia ter sido feita há muito tempo. PHP é uma das poucas linguagens principais de programação que ainda não implementou fsync() e fdatasync() – ou seja, até o PHP 8.1.

A função fsync() é similar à função fflush() existente no PHP, mas ela difere significativamente de uma maneira. Enquanto fflush() descarrega os buffers internos da aplicativo para o SO, fsync() vai um passo além e assegura que os buffers internos sejam descarregados para o armazenamento físico. Isso garante uma escrita completa e persistente para que você possa recuperar os dados mesmo após um aplicativo ou falha do sistema.

Aqui está um exemplo de como você pode usá-lo.

$doc = 'kinsta.txt';

$kin = fopen($doc, 'ki');
fwrite($kin, 'doc info');
fwrite($kin, "\r\n");
fwrite($kin, 'more info');

fsync($kin);
fclose($kin);

Adicionar a chamada fsync() no final garante que qualquer dado armazenado no PHP ou no buffer interno do sistema operacional seja gravado no armazenamento. Todas as outras execuções de código são bloqueadas até lá.

Sua função relacionada é fdatasync(). Use-o para sincronizar dados, mas não necessariamente metadados. Para dados cujos metadados não são essenciais, esta chamada de função torna o processo de escrita um pouco mais rápido.

No entanto, você deve notar que o PHP 8.1 ainda não suporta fdatasync() totalmente no Windows. Ele simplesmente age como um pseudônimo de fsync(). No POSIX, fdatasync() é devidamente implementado.

Nova função array_is_list()

As arrays PHP podem conter tanto o integer como as teclas de string. Isso significa que você pode usá-las para várias coisas, incluindo listas, tabelas de hash, dicionários, coleções, pilhas, filas, e muito mais. Você pode até mesmo ter arrays dentro de arrays, criando arrays multidimensionais.

Você pode verificar eficientemente se uma determinada entrada é um array, mas não é tão fácil verificar se ela tem algum offsets de array em falta, chaves fora de ordem, etc. Em resumo, você não pode verificar rapidamente se um array é uma lista.

A funçãoarray_is_list() verifica se as chaves de um array estão em ordem sequencial a partir de 0, e sem lacunas. Se todas as condições forem satisfeitas, ela retornará true. Por padrão, ela também retorna true para arrays vazios.

Aqui estão alguns exemplos de como usá-lo com condições true e false preenchidas:

// true array_is_list() examples
array_is_list([]); // true
array_is_list([1, 2, 3]); // true
array_is_list(['cats', 2, 3]); // true
array_is_list(['cats', 'dogs']); // true
array_is_list([0 => 'cats', 'dogs']); // true
array_is_list([0 => 'cats', 1 => 'dogs']); // true 

// false array_is_list() examples 
array_is_list([1 => 'cats', 'dogs']); // as first key isn't 0
array_is_list([1 => 'cats', 0 => 'dogs']); // keys are out of order
array_is_list([0 => 'cats', 'bark' => 'dogs']); // non-integer keys
array_is_list([0 => 'cats', 2 => 'dogs']); // gap in between keys 

Uma lista de array PHP com chaves fora de ordem é uma fonte potencial de bugs. Usar esta função para impor uma estrita adesão aos requisitos da lista antes de avançar com a execução do código é uma grande adição ao PHP.

Novas Funções Sodium XChaCha20

O Sodium é uma biblioteca criptográfica moderna e fácil de usar para criptografia, decodificação, hashing de senhas, assinaturas e muito mais. O pacote PECL libsodium adiciona um wrapper para o Sodium para que os desenvolvedores de PHP possam usá-lo.

Mesmo empresas líderes em tecnologia como Facebook, Discord, Malwarebytes e Valve usam libsodium para proteger seus usuários com conexões rápidas e seguras.

libsodium suporta o algoritmo de encriptação XChaCha20 para encriptar e desencriptar dados, especialmente para encriptação de fluxo. Da mesma forma, a extensão libsodium da PECL já suporta o XChaCha20, mas apenas com código de autenticação de mensagens Poly1305.

Muitas aplicações PHP usam o XChaCha20 diretamente para criptografia de fluxo. Para facilitar as coisas, começando com o PHP 8.1, você terá três novas funções para criptografar ou decodificar dados com o XChaCha20 sem autenticação envolvida. Este modo é chamado de “modo desconectado”.

As funções do XChaCha20 recentemente introduzidas são:

  • sodium_crypto_stream_xchacha20_keygen: Devolve uma chave aleatória segura para uso com sodium_crypto_stream_xchacha20.
  • sodium_crypto_stream_xchacha20: Expande o keystream e o nonce para um keystream de bytes pseudorandômicos.
  • sodium_crypto_stream_xchacha20_xor: Criptografa uma mensagem usando uma nonce e uma chave secreta (sem autenticação).

Adicionalmente, existem duas novas constantes PHP definidas no namespace global:

  • SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES (atribuído 32)
  • SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES (atribuído 24)

Use-o com cuidado, no entanto. Como é sem autenticação, a operação de desencriptação é vulnerável a ataques de texto criptografado comuns.

Você pode ler mais sobre seu uso e requisitos na página do GitHub.

Nova Classe IntlDatePatternGenerator

A biblioteca subjacente da UTI do PHP suporta a criação de formatos de data e hora localizados, mas não é totalmente personalizável.

Por exemplo, se você quiser criar formatos de dados e horários específicos até o PHP 8.0, você pode usar a constante IntlDateFormatter predefinida para fazê-lo de 6 maneiras:

  • IntlDateFormatter::LONG: Mais longo, como 10 de novembro de 2017 ou 23:22:33pm
  • IntlDateFormatter::MEDIUM: Um pouco mais curto, como 10 de novembro de 2017
  • IntlDateFormatter::SHORT: Apenas numérico, como 10/11/17 ou 23:22h

Cada uma delas também tem suas próprias variantes RELATIVE_, que define a formatação da data dentro de um intervalo limitado, antes ou depois da data atual. Em PHP, os valores são yesterdaytoday, e tomorrow.

Digamos que você queira usar a versão longa para o ano e a versão curta para o mês, como 10/11/2017. A partir do PHP 8.0, você não pode.

No PHP 8.1+, você pode especificar quais formatos usar para a data, mês e hora com a nova classe IntlDatePatternGenerator. Você pode deixar a ordem exata desses componentes para o formatador.

Você deve observar que embora esta classe tenha apenas a palavra Date, ela é consistente com o DateTimePatternGenerator da UTI. Isso significa que você também pode usá-lo para criar formatos de tempo flexíveis. Para simplificar a nomenclatura, a equipe PHP escolheu o termo mais curto IntlDatePatternGenerator.

Aqui está um exemplo direto do seu RFC:

$skeleton = "YYYYMMdd";
 
$today = \DateTimeImmutable::createFromFormat('Y-m-d', '2021-04-24');
 
$dtpg = new \IntlDatePatternGenerator("de_DE");
$pattern = $dtpg->getBestPattern($skeleton);
echo "de: ", \IntlDateFormatter::formatObject($today, $pattern, "de_DE"), "\n";
 
$dtpg = new \IntlDatePatternGenerator("en_US");
$pattern = $dtpg->getBestPattern($skeleton), "\n";
echo "en: ", \IntlDateFormatter::formatObject($today, $pattern, "en_US"), "\n";
 
/*
de: 24.04.2021
en: 04/24/2021
*/

No código acima, a variável skeleton define os formatos específicos de data ou hora a usar. No entanto, o formatador lida com a ordem do resultado final.

Suporte para o formato de imagem AVIF

AVIF, ou AV1 Image File Format, é um formato de imagem relativamente novo, livre de royalties, baseado no formato de codificação de vídeo AV1. Além de oferecer maior compressão (e, portanto, tamanhos de arquivo menores), ele também suporta vários recursos, como transparência, HDR e muito mais.

O formato AVIF só foi padronizado recentemente (8 de junho de 2021). Isso abriu caminho para navegadores, como o Chrome 85+ e Firefox 86+, adicionando suporte a imagens AVIF.

O processamento de imagens do PHP 8.1 e a extensão GD adicionam suporte a imagens AVIF.

No entanto, para incluir esta funcionalidade, você precisa compilar a extensão GD com suporte AVIF. Você pode fazer isso executando os comandos abaixo.

Para Debian/Ubuntu:

apt install libavif-dev

Para Fedora/RHEL:

dnf install libavif-devel

Isso vai instalar todas as últimas dependências. Em seguida, você pode compilar o suporte AVIF rodando a bandeira --with-avif com o script . /configure.

./buildconf --force
./configure --enable-gd --with-avif

Se você está iniciando um novo ambiente do zero, você também pode habilitar outras extensões do PHP aqui.

Uma vez instalado, você pode testar se o suporte a AVIF está habilitado executando o seguinte comando no seu terminal PHP:

php -i | grep AVIF

Se você instalou o AVIF corretamente, você verá o seguinte resultado:

AVIF Support => enabled

Você também pode usar a chamada gd_info() para obter uma lista de recursos GD, incluindo se a funcionalidade de suporte AVIF está habilitada.

Esta extensão atualizada do PHP 8.1 GD também adiciona duas novas funções para trabalhar com imagens AVIF: imagecreatefromavif e imageavif. Eles funcionam de forma similar aos seus equivalentes JPEG e PNG.

A função imagecreatefromavif retorna uma instância GdImage de uma determinada imagem AVIF. Você pode então usar esta instância para editar ou converter a imagem.

A outra função imageavif produz o ficheiro de imagem AVIF. Por exemplo, você pode usá-lo para converter um JPEG para AVIF:

$image = imagecreatefromjpeg('image.jpeg');
imageavif($image, 'image.avif');

Você pode ler mais sobre este novo recurso em sua página do GitHub.

Nova chave para uploads de diretório $_FILES: full_path

O PHP mantém um grande número de variáveis pré-definidas para rastrear várias coisas. Uma delas é a variável $_FILES que contém um array associativo de itens carregados através do método HTTP POST.

A maioria dos navegadores modernos suporta o upload de um diretório inteiro com campos de upload de arquivos HTML. Mesmo PHP <8.1 suportava esta funcionalidade, mas com uma grande advertência. Você não poderia carregar uma pasta com sua estrutura exata de diretórios ou caminhos relativos porque o PHP não passou essa informação para o array $_FILES.

Isso muda no PHP 8.1 com a adição de uma nova chave chamada full_path ao array $_FILES. Usando esses novos dados, você pode armazenar caminhos relativos ou duplicar a estrutura exata de diretórios no servidor.

Você pode testar esta informação ao emitir o array $FILES usando o comando var_dump($_FILES);.

No entanto, tenha cuidado se estiver a usar esta funcionalidade. Assegure-se de que você se protege contra ataques de upload de arquivos padrão.

Suporte de descompactação de arrays com string chave

O PHP 7.4 adicionou suporte para desempactar o array com o operador de spread array (... ). Ele age como uma alternativa mais rápida ao uso da função array_merge(). No entanto, este recurso foi limitado a arrays com chave numérica já que desempactar arrays com string chave causou conflitos enquanto mesclou arrays com chaves duplicadas.

No entanto, o PHP 8 adicionou suporte a argumentos nomeados, removendo essa limitação. Assim, o desempacotamento de array agora também suportará arrays com string-keyed usando a mesma sintaxe:

$array = [...$array1, ...$array2];

Este exemplo de RFC ilustra como é feita a fusão de arrays com chaves de string duplicadas no PHP 8.1:

$array1 = ["a" => 1];
$array2 = ["a" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump($array); // ["a" => 2]

Aqui, a tecla de string “a” aparece três vezes antes da fusão via desembalagem de array. Mas apenas o seu último valor pertencente a $array2 ganha.

Notação numérica octal explicita

O PHP suporta vários sistemas numéricos, incluindo decimal (base-10), binário (base-2), octal (base-8) e hexadecimal (base-16). O sistema de numerais decimais é o padrão.

Se você quiser usar qualquer outro sistema numérico, então você terá que prefixar cada número com um prefixo padrão:

  • Hex: 0x prefixo. (por exemplo, 17 = 0x11)
  • Binary: 0b prefixo. (por exemplo, 3 = 0b11)
  • Octal: 0 prefixo. (por exemplo, 9 = 011)

Você pode ver como o prefixo do sistema numérico octal varia em relação ao resto. Para padronizar esta preocupação, muitas linguagens de programação estão adicionando suporte a uma notação explícita de numeração octal: 0o ou 0O.

A partir do PHP 8.1, você pode escrever o exemplo mostrado acima (ou seja, o número 9 no base-10) no sistema numérico octal como 0o11 ou 0O11.

0o16 === 14; // true
0o123 === 83; // true
 
0O16 === 14; // true
0O123 === 83; // true
 
016 === 0o16; // true
016 === 0O16; // true

Além disso, esta nova funcionalidade também funciona com o separador numérico literal de sublinhado introduzido no PHP 7.4.

Leia mais sobre esta nova funcionalidade do PHP 8.1 em sua RFC.

Suporte para algoritmos de MurmurHash3 e xxHash hash

O PHP 8.1 adiciona suporte para algoritmos de hashing MurmurHash3 e xxHash. Eles não são projetados para uso criptográfico, mas ainda fornecem uma saída impressionante de aleatoriedade, dispersão e singularidade.

Estes novos algoritmos de hashing são mais rápidos que a maioria dos algoritmos de hashing existentes no PHP. Na verdade, algumas dessas variantes de algoritmos de hashing são mais rápidas do que a taxa de transferência da RAM.

Como o PHP 8.1 também adiciona suporte para declarar parâmetros de $options específicos do algoritmo, você pode fazer o mesmo com esses novos algoritmos. O valor padrão deste novo argumento é []. Então, ele não afetará nenhuma de nossas funções hash existentes.

Você pode ler mais sobre essas novas funcionalidades do PHP 8.1 em suas páginas do GitHub: MurmurHash3xxHashAlgorithm-specific $options.

Suporte DNS-over-HTTPS (DoH)

DNS-over-HTTPS (DoH) é um protocolo para resolução DNS através do protocolo HTTPS. Usando HTTTPS para criptografar dados entre o cliente e o resolvedor DNS, DoH aumenta a privacidade e segurança do usuário ao prevenir ataques MitM.

Começando com o PHP 8.1, você pode usar a extensão Curl para especificar um servidor DoH. Ele requer que o PHP seja compilado com as versões da libcurl 7.62+. Isso não é um problema para a maioria dos sistemas operacionais populares, incluindo as distros Linux, já que elas frequentemente incluem o Curl 7.68+.

Você pode configurar a URL do servidor DoH especificando a opção CURLOPT_DOH_URL.

$doh = curl_init('https://kinsta.com');
curl_setopt($doh, CURLOPT_DOH_URL, 'https://dns.google/dns-query');
curl_exec($doh);

No exemplo acima, nós usamos o servidor DNS público do Google. Note também o uso de https:// em todos os URLs utilizados. Certifique-se de configurar isso perfeitamente, pois não há um servidor DNS padrão para o qual cair no Curl.

Você também pode escolher entre uma lista de servidores públicos DoH incluídos na documentação do Curl.

Além disso, a referência CURLOPT_DOH_URL da documentação Curl explica como usar seus vários argumentos de forma completa.

Upload de arquivos a partir de Strings com CURLStringFile

A extensão PHP Curl suporta pedidos HTTP(S) com uploads de arquivos. Ela usa a classe CURLFile para conseguir isso, que aceita um URI ou um caminho de arquivo, um tipo mime, e o nome final do arquivo.

No entanto, com a classe CURLFile, você só pode aceitar o caminho do arquivo ou URI, mas não o conteúdo do arquivo em si. Nos casos em que você já tinha o arquivo sendo carregado na memória (por exemplo, imagens processadas, documentos XML, PDFs), você tinha que usar data:// URIs com codificação Base64.

Mas a libcurl já suporta uma maneira mais fácil de aceitar o conteúdo do arquivo. A nova classe CURLStringFile adiciona suporte precisamente para isso.

Você pode ler a página do GitHub para saber mais sobre como ele é implementado no PHP 8.1.

Nova Constante MYSQLI_REFRESH_REPLICA

A extensão mysqli do PHP 8.1 adiciona uma nova constante chamada MYSQLI_REFRESH_REPLICA. É equivalente à constante MYSQLI_REFRESH_SLAVE existente.

Esta mudança foi bem-vinda no MySQL 8.0.23 para abordar a insensibilidade racial no vocabulário técnico (os exemplos mais comuns incluem “escravo” e “mestre”).

Você deve observar que a constante mais antiga não está sendo removida ou depreciada. Desenvolvedores e aplicativos podem continuar usando-a. Esta nova constante é apenas uma opção para desenvolvedores e empresas que desejam deixar para trás tal terminologia.

Melhorias de desempenho com Inheritance Cache

Inheritance Cache é uma nova adição ao opcache que elimina o overhead da herança da classe PHP.

As classes PHP são compiladas e armazenadas em cache por opcache separadamente. No entanto, elas já estão ligadas em tempo de execução em cada requisição. Este processo pode envolver várias verificações de compatibilidade e métodos/propriedades/constantes de empréstimo das classes pai e características.

Como resultado, isso leva um tempo considerável para ser executado, mesmo que o resultado seja o mesmo para cada pedido.

Inheritance Cache liga todas as classes dependentes exclusivas (pai, interfaces, características, tipos de propriedades, métodos) e armazena os resultados na memória compartilhada opcache. Como isso acontece apenas uma vez agora, a herança requer menos instruções.

Além disso, remove limitações para classes imutáveis, tais como constantes não resolvidas, propriedades digitadas e verificações de tipo covariantes. Assim, todas as classes armazenadas no opcache são imutáveis, reduzindo ainda mais o número de instruções necessárias.

Em suma, promete benefícios de desempenho significativos. Dimitry Stogov, o autor deste patch, descobriu que ele mostrou uma melhoria de 8% na base do programa Symfony “Olá, Mundo! Nós mal podemos esperar para testá-lo em nossos seguintes benchmarks PHP.

Callable Syntax de Primeira Classe

O PHP 8.1 adiciona uma Callable Syntax de primeira classe para substituir codificações existentes usando strings e arrays. Além de criar um Closure mais limpo, esta nova sintaxe também é acessível por ferramentas de análise estática e respeita o escopo declarado.

Aqui estão alguns exemplos tirados da RFC:

$fn = Closure::fromCallable('strlen');
$fn = strlen(...);
 
$fn = Closure::fromCallable([$this, 'method']);
$fn = $this->method(...)
 
$fn = Closure::fromCallable([Foo::class, 'method']);
$fn = Foo::method(...);

Aqui, todos os pares de expressões são equivalentes. A sintaxe do ponto triplo () é semelhante ao argumento desempacotar a sintaxe (...$args). Exceto aqui, os argumentos ainda não estão preenchidos.

Mudanças no PHP 8.1

O PHP 8.1 também inclui alterações na sua sintaxe e características existentes. Vamos discuti-las:

PHP Interactive Shell requer extensão da linha de leitura

A extensão readline do PHP permite funcionalidades de interactive shell como navegação, autocompletar, edição e muito mais. Enquanto está descompactado com PHP, não está habilitado por padrão.

Você pode acessar a shell interactive PHP usando PHP CLI’s -a opção de linha de comando:

php -a

Interactive shell

php >
php > echo "Hello";
Hello
php > function test() {
php { echo "Hello";
php { }
php > test();
Hello

Antes do PHP 8.1, você podia abrir a shell interactive usando PHP CLI mesmo sem a extensão readline habilitada. Como esperado, os recursos interativos da shell não funcionavam, tornando a opção -a sem sentido.

No PHP 8.1 CLI, a shell interativa sai com uma mensagem de erro se você não ativou a extensão da linha de leitura.

php -a
Interactive shell (-a) requires the readline extension.

Modo de erro padrão do MySQLi definido para exceções

Antes do PHP 8.1, o MySQLi não tinha o padrão para silenciar os erros. Este comportamento muitas vezes levava a um código que não seguia um tratamento rigoroso de erros/exceções. Os desenvolvedores tinham que implementar suas próprias funções explícitas de tratamento de erros.

O PHP 8.1 altera este comportamento ao definir o modo de relatório de erros padrão do MySQLi para lançar uma exceção.

Fatal error: Uncaught mysqli_sql_exception: Connection refused in ...:...

Como esta é uma alteração de ruptura, para versões PHP <8.1, você deve definir explicitamente o modo de tratamento de erros usando a função mysqli_report antes de fazer a primeira conexão MySQLi. Alternativamente, você pode fazer o mesmo selecionando o valor do relatório de erro instanciando uma instância do mysqli_driver.

A RFC segue uma mudança similar introduzida no PHP 8.0.

Terminais de linha personalizáveis para funções de escrita CSV

Antes do PHP 8.1, as funções de escrita CSV embutidas do PHP, fputcsv e SplFileObject::fputcsv, eram codificadas para adicionar \n (ou o caractere Line-Feed) no final de cada linha.

O PHP 8.1 adiciona suporte para um novo parâmetro chamado eol a estas funções. Você pode usá-lo para passar um caractere configurável de fim de linha. Por padrão, ele ainda usa o caractere \n. Então, você pode continuar usando-o em seu código existente.

As regras padrão de fuga de caracteres aplicam-se ao uso de caracteres de fim de linha. Se você quiser usar \r, \n, ou \r\n como caracteres EOL, você deve colocá-los entre aspas duplas.

Aqui está a página do GitHub a acompanhar esta nova alteração.

Nova restrições do operador version_compare

A função version_compare() do PHP compara duas strings de números de versão. Esta função aceita um terceiro argumento opcional chamado operator para testar um relacionamento em particular.

Embora não coberto explicitamente na documentação, antes do PHP 8.1, você poderia definir este parâmetro para um valor parcial (por exemplo, g, l, n) sem enfrentar um erro.

O PHP 8.1 adiciona restrições mais rígidas ao argumento do operator da função version_compare() para superar esta situação. Os únicos operadores que você pode usar agora são:

  • ==, =, e eq
  • !=, <>, e ne
  • > e gt
  • >= e ge
  • < e lt
  • <= e le

Acabaram-se os valores parciais do operador.

Funções de codificação e decodificação HTML agora usam ENT_QUOTES | ENT_SUBSTITUTE

As entidades HTML são representações textuais de caracteres que de outra forma seriam interpretadas como HTML. Pense em caracteres como < e > usados para definir tags HTML (por exemplo <a>, <h3>, <script>).

A entidade HTML para < é <; (menor que o símbolo) e > é >; (maior que o símbolo). Você pode usar essas entidades HTML com segurança em um documento HTML sem acionar o mecanismo de renderização do navegador.

Por exemplo, <script> aparecerá como <script> no navegador, ao invés de ser interpretado como uma tag HTML.

Antes do PHP 8.1, as funções htmlspecialchars() e htmlentities() convertiam símbolos como ", < , > , e & para suas respectivas entidades HTML. Mas eles não converteram o único caractere de aspas (') para sua entidade HTML por padrão. Além disso, eles retornaram uma string vazia se houvesse um UTF-8 mal-formado no texto.

No PHP 8.1., essas funções de codificação e decodificação HTML (e suas funções relacionadas) também irão converter caracteres de aspas simples para sua entidade HTML por padrão.

E se o texto dado tiver caracteres inválidos, as funções irão substituí-los por um caractere de substituição Unicode (�) em vez de retornar uma string vazia. O PHP 8.1 realiza isso mudando as assinaturas dessas funções para ENT_QUOTES | ENT_SUBSTITUTE ao invés de ENT_COMPAT por padrão.

A maioria das frameworks já usa ENT_QUOTES como o valor padrão da bandeira. Portanto, você não verá muita diferença devido a esta mudança. Entretanto, o novo flag ENT_SUBSTITUTE não é muito utilizado. O PHP 8.1 irá fazer com que caracteres UTF-8 inválidos sejam substituídos pelo caracter � ao invés de retornar uma string vazia.

Advertência sobre Ilegais Function Calls compactas

A função compact() do PHP é super útil. Você pode usá-la para criar um array com variáveis usando seus nomes e valores.

Por exemplo, considere o seguinte código:

$animal = 'Cat';
$sound = 'Meow';
$region = 'Istanbul';
compact('animal', 'sound', 'region');
// ['animal' => "Cat", 'sound' => "Meow", 'region' => "Istanbul"]

A documentação da função compacta afirma que só aceitará parâmetros de string ou valores de array com valores de string. No entanto, antes do PHP 7.3, quaisquer strings que não sejam definidas seriam silenciosamente ignoradas.

O PHP 7.3 modificou a função compact() para vomitar um aviso se você usar variáveis indefinidas. O PHP 8.1 leva-o um passo adiante e lança um aviso.

Você pode ler sua página do GitHub para entender como essa mudança veio a ser.

Novas migrações de recursos para objetos de classe

Um dos objetivos do PHP a longo prazo é se afastar dos recursos em direção a objetos de classe padrão.

Devido a razões históricas, os objetos de recurso são usados extensivamente em aplicações PHP. Portanto, a migração de recursos para objetos de classe precisa ser o menos disruptiva possível. O PHP 8.1 migra cinco desses recursos:

O recurso file_info migrou para os objetos finfo

A classe finfo do PHP oferece uma interface orientada a objetos para as funções fileinfo. Entretanto, o uso das funções finfo retorna objetos de resource com o tipo file_info em vez de uma instância da própria classe finfo.

O PHP 8.1 corrige esta anomalia.

Os recursos do IMAP foram migrados para os objetos de classe IMAP\Connection

Em linha com o objetivo de migração recurso-a-objeto, a nova classe IMAP\Connection minimiza potenciais mudanças de ruptura quando o PHP eventualmente modifica os detalhes de implementação da classe.

Esta nova turma também é declarada final, por isso não é permitido extend-la.

Leia mais sobre sua implementação em sua página do GitHub.

Os recursos de conexão FTP são agora objetos de classe FTP\Connection

No PHP <8.1, se você criar uma conexão FTP com as funções ftp_connect() ou ftp_ssl_connect(), você receberá de volta um objeto de resource do tipo ftp.

PHP 8.1 adiciona a nova classe FTP\Connection para rectificar isso. E tal como com a classe IMAP\Connection, também é declarada final para evitar que seja estendida.

Leia mais sobre sua implementação em sua página do GitHub.

Os identificadores das fontes foram migrados para os objetos da classe GdFont

A extensão GD do PHP fornece a função imageloadfont (para carregar um bitmap definido pelo usuário e retornar seu ID de recurso identificador de fonte (um inteiro).

No PHP 8.1, esta função irá retornar uma instância da classe GdFont. Além disso, para fazer a migração sem problemas, todas as funções que anteriormente aceitavam um ID de recurso do imageloadfont() agora pegarão os novos objetos da classe GdFont.

Leia mais sobre esta migração em sua página do GitHub.

Recursos LDAP migrados para Objetos

O LDAP, ou Lightweight Directory Access Protocol, é usado para acessar “Servidores de Diretório”. Tal como uma estrutura de diretório do disco rígido, é uma base de dados única que contém dados numa estrutura em árvore.

O PHP inclui uma extensão LDAP que aceita ou devolve objetos de resource antes do PHP 8.1. No entanto, todos eles migraram sem problemas para novas instâncias de classe agora. Os tipos de resources que foram transicionados são:

  • ldap link recurso para o objeto de classe \LDAP\Connection
  • ldap result recurso para o objeto de classe \LDAP\Result
  • ldap result entry recurso para o objeto de classe \LDAP\ResultEntry

Vá através da sua página do GitHub para entender melhor esta migração.

Recursos ortográficos são agora objetos de classe

A extensão PHP Pspell permite que você verifique ortografias e sugestões de palavras.

PHP <8.1 usou pspellpspell config tipos de objetos de recursos com um identificador inteiro. Estes dois objetos de recurso são agora substituídos por objetos de classe PSpell\DictionaryPSpell\Config .

Como migrações anteriores, todas as funções Pspell que anteriormente aceitavam ou devolviam identificadores de objetos de recurso tomarão as novas instâncias de objetos de classe.

Consulte a página do GitHub para obter mais informações.

Depreciações no PHP 8.1

O PHP 8.1 deprecia muitas de suas funcionalidades anteriores. A lista seguinte fornece uma breve visão geral das funcionalidades que o PHP 8.1 deprecia:

Não pode passar de parâmetros de função null para non-nulled

A partir do PHP 8.0, suas funções internas aceitam silenciosamente valores null mesmo para argumentos não-nulos. O mesmo não se aplica às funções definidas pelo usuário – elas só aceitam valores null para argumentos não nulos.

Por exemplo, considere este uso:

var_dump(str_contains("foobar", null));
// bool(true)

Aqui, o valor null é silenciosamente convertido para uma string vazia. Assim, o resultado retorna true.

Esta RFC visa sincronizar o comportamento das funções internas lançando um aviso de depreciação no PHP 8.1.

var_dump(str_contains("foobar", null));
// Deprecated: Passing null to argument of type string is deprecated

A depreciação se tornará um TypeError na próxima grande versão do PHP (ou seja, PHP >=9.0), tornando o comportamento das funções internas consistente com as funções definidas pelo usuário.

Uso restrito de $GLOBALS

A variável $GLOBALS do PHP fornece uma referência direta à sua tabela de símbolos internos. O suporte a esta funcionalidade é complexo e afeta o desempenho das operações de array. Além disso, ela foi raramente utilizada.

De acordo com a RFC, a modificação indireta de $GLOBALS não é mais permitida. Esta alteração é retrocompatível.

O impacto desta mudança é relativamente baixo:

Nos pacotes de compositores 2k encontrei 23 caixas que usam $GLOBALS sem desreferenciá-los diretamente. Baseado em uma inspeção superficial, existem apenas dois casos em que o $GLOBALS não é utilizado de forma somente leitura.

Entretanto, o uso de $GLOBALS apenas para leitura continua a funcionar como de costume. O que não é mais suportado é escrever para o $GLOBALS como um todo. Como resultado, você pode esperar um ligeiro aumento de desempenho, especialmente quando se trabalha com arrays PHP comuns.

Declarações do tipo retorno para funções internas

O PHP 8.0 permitiu que os desenvolvedores declarassem parâmetros e tipos de retorno para a maioria das funções e métodos internos. Isso foi possível graças a várias RFCs, como erros de tipo consistentes para funções internas, Union Types 2.0, e Mixed Type v2.

No entanto, há muitos casos em que a informação do tipo pode estar faltando. Alguns deles incluem um tipo com recursos, parâmetros de passagem por reflexo, tipo de retorno de métodos não-final e funções ou métodos que não analisam parâmetros de acordo com as regras gerais. Você pode ler os detalhes exatos em sua RFC.

Esta RFC só aborda o problema com o tipo de retorno de métodos não-final. No entanto, ao invés de eliminá-la imediatamente, a equipe PHP fornece um caminho de migração gradual para atualizar suas bases de código com os tipos de retorno dos métodos relevantes.

Tipos de retorno de método interno não-final – quando possível – são declarados provisoriamente no PHP 8.1, e eles serão aplicados no PHP 9.0. Isso significa que nas versões do PHP 8.x, um aviso “depreciado” é levantado durante verificações de herança quando um método interno é sobreposto de uma forma que os tipos de retorno são incompatíveis, e o PHP 9.0 tornará esses tipos um erro fatal.

Se você vir este aviso de depreciação após a atualização para o PHP 8.1, certifique-se de atualizar os tipos de retorno dos seus métodos.

Interface serializável depreciável

O PHP 7.4 introduziu o mecanismo de objetos serializávelde personalizados com dois novos métodos mágicos: __serialize() e __unserialize(). Estes novos métodos visam substituir a interface Serializable quebrada eventualmente.

Este RFC propõe finalizar essa decisão, estabelecendo um plano para a eventual remoção do Serializable.

No PHP 8.1, se você implementar a interface Serializable sem implementar os métodos __serialize() e __unserialize(), o PHP irá lançar um aviso de “Deprecated”.

Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in ... on line ...

Se você está suportando PHP <7.4 e PHP >=7.4, você deve implementar tanto a interface Serializável quanto os novos métodos mágicos. Nas versões PHP >=7.4, os métodos mágicos terão precedência.

Conversões depreciadas não compatíveis do Float para int

PHP é uma linguagem dinamicamente tipada. Como tal, há muitos casos em que a coerção do tipo ocorre naturalmente. A maioria dessas coerciões são inofensivas e super convenientes.

Entretanto, quando um número de float é convertido em um integer, muitas vezes envolve perda de dados. Por exemplo, quando a margem de flutuação 3.14 é convertida em um integer 3, ela perde seu valor fracionário.

O mesmo acontece quando o float está fora da faixa inteira da plataforma, ou quando uma seqüência de floats é convertida em um integer .

O PHP 8.1 retifica este comportamento e traz seu tipo dinâmico coercing mais alinhado com a maioria das linguagens de programação modernas. O objetivo é tornar tais coercões previsíveis e intuitivas.

No PHP 8.1, você verá um aviso de depreciação quando um float não compatível é implicitamente coagido a uma int. Mas o que constitui uma flutuação não compatível com um integer ? A RFC responde a isto:

Diz-se que um float é compatível com um integer se possuir as seguintes características:

  • É um número (ou seja, não NaN ou Infinity)
  • Está no alcance de um integer PHP (dependente da plataforma)
  • Não tem parte fracionária

Este aviso de depreciação irá actualizar para um TypeError na próxima versão principal do PHP (i.e. PHP 9.0).

Os métodos mysqli::get_client_infoe mysqli_get_client_info($param) são depreciados 

A API do cliente MySQL define duas constantes: client_info (uma string) e client_version (uma int). O MySQL Native Driver (MySQLnd) faz parte da fonte PHP oficial e associa estas constantes à versão PHP. Na libmysql, elas representam a versão da biblioteca cliente no momento da compilação.

Antes do PHP 8.1, mysqli expunha estas constantes de 4 maneiras: mysqli_driver properties, mysqli properties, mysqli_get_client_info() function, e mysqli::get_client_info method. No entanto, não há método para client_version.

MySQLnd expõe estas constantes de 2 maneiras ao PHP: uma constante e uma chamada de função. Para unificar os métodos de acesso mysqli com estas duas mesmas opções, o PHP 8.1 está depreciando estas outras duas opções:

  • get_client_info método na classe mysqli. Em vez disso, você pode simplesmente usar a função mysqli_get_client_info().
  • mysqli_get_client_info() com parâmetros. Chame a função sem nenhum parâmetro para evitar o aviso de depreciação.

Leia mais sobre esta desvalorização em sua página do GitHub.

Todas as funções mhash*()(extensão hash) são depreciadas

O PHP 5.3 integra funções mhash*() em ext/hash como uma camada de compatibilidade para ext/mhash. Mais tarde, o PHP 7.0 removeu o ext/mhash.

Ao contrário das funções hash_*(), as funções mhash*() nem sempre estão disponíveis. Você tem que habilitá-las separadamente enquanto configura o PHP.

No PHP 7.4, a extensão hash foi empacotada junto com o PHP, tornando-a uma extensão padrão para o PHP. Entretanto, ela ainda suportava a opção --enable-mhash por razões de compatibilidade.

A equipe PHP decidiu depreciar as funções mhash*() no PHP 8.1, e removê-las completamente no PHP 9.0. As funções depreciadas são mhash(), mhash_keygen_s2k(), mhash_count(), mhash_get_block_size() e mhash_get_hash_name(). Você pode usar a funcionalidade padrão ext/hash no lugar deles.

Os parâmetros filter.default e filter.default_options são depreciadosd

As configurações padrão do PHP filter.default INI permitem que você aplique um filtro a todos os super-globais do PHP – ou seja, dados GPCRS ($_GET, $_POST, $_COOKIE, $_REQUEST, e $_SERVER).

Por exemplo, você pode definir filter.default=magic_quotes ou filter.default=add_slashes (baseado na versão do PHP) para ressuscitar o recurso de citações mágicas controversas e inseguras do PHP (removido no PHP 5.4).

A configuração padrão do filter.default INI fornece funcionalidade adicional, permitindo muitos mais filtros, tornando-o ainda pior. Por exemplo, sua outra opção – filter.default=special_chars – permite citações mágicas apenas para HTML. Há muito menos consciência destas configurações.

O PHP 8.1 irá lançar um aviso de depreciação se o filter.default estiver definido para qualquer valor diferente de unsafe_raw (o padrão). Você não verá um aviso de depreciação separado para filter.default_options, mas o PHP 9.0 removerá essas duas configurações INI.

Como alternativa, você pode começar a usar a função filter_var(). Ela filtra variáveis com o filtro especificado.

Depreciar a autovivification em falso

O PHP permite a autocriação (autocriação de arrays a partir de valores falsos). Esta característica é super útil se a variável é indefinida.

No entanto, não é ideal criar automaticamente um array quando o valor é falso ou nulo.

Este RFC desabilita a autovivificação a partir de valores falsos. Entretanto, note que a autovivificação a partir de variáveis indefinidas e nulas ainda é permitida.

No PHP 8.1, anexando a uma variável do tipo false irá emitir um aviso de depreciação:

Deprecated: Automatic conversion of false to array is deprecated in

O PHP 9.0 vai lançar um erro fatal para o mesmo, que é idêntico a outros tipos escalares.

A propriedade mysqli_driver->driver_version é depreciada

A propriedade mysqli_driver->driver_version da extensão MySQLi não é atualizada há 13 anos. Apesar de muitas mudanças no driver desde então, ele ainda retorna o valor da versão antiga do driver, tornando esta propriedade sem sentido.

No PHP 8.1, a propriedade mysqli_driver->driver_version é depreciada.

Outras alterações menores

muito mais depreciações no PHP 8.1. Listar todas elas aqui será um exercício exaustivo. Nós recomendamos que você verifique diretamente a RFC para estas pequenas depreciações.4

A página GitHub do PHP também inclui um guia PHP 8.1 UPGRADE NOTES. Ele lista todas as mudanças que você deve considerar antes de atualizar para o PHP 8.1.

Resumo

O PHP 8.1 é melhor que o seu antecessor, o que não é uma pequena proeza. Achamos que as funcionalidades mais interessantes do PHP 8.1 são Enums, Fibers, Pure Intersection Types, e suas muitas melhorias de desempenho. Além disso, mal podemos esperar para colocar o PHP 8.1 através de seus ritmos e comparar várias frameworks PHP e CMSs.

Certifique-se de marcar este artigo no blog para sua referência futura.

Qual PHP 8.1 é o seu recurso favorito? Compartilhe suas idéias com a comunidade na seção de comentários abaixo.

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.