Alterações Incompatíveis com Versões Anteriores

Embora não seja explicitamente citado nesta seção, cada nova função, classe, interface, enumeração, ou constante pode fazer com que um Error de redeclaração seja lançado.

Núcleo do PHP

Alteração de comportamento de exit()

As construções de linguagem exit() (e die()) agora se comportam mais como uma função. Isso significa que elas agora podem ser passadas ​​como callables, são afetadas pela instrução declare strict_types e agora executam as coerções de tipo usuais em vez de converter qualquer valor não inteiro para uma string.

Sendo assim, passar tipos inválidos para exit() e die() agora resultam, consistentemente, no lançamento de um TypeError.

Recursão durante comparação

Encontrar recursão durante uma comparação agora resulta em exceção Error ao invés de erro fatal E_ERROR.

Modificação indireta de propriedades somente leitura

A modificação indireta de propriedades somente leitura em __clone() não é mais permitida, por exemplo, $ref = &$this->somente_leitura. Isso já era proibido para inicialização somente leitura e foi um descuido na implementação de "reinicialização somente leitura durante a clonagem".

Alteração de Tipo de Constantes

As constantes PHP_DEBUG e PHP_ZTS agora são do tipo bool. Anteriormente eram do tipo int.

Comprimento de nome de arquivo temporário

O nome dos arquivos enviados e criados pela função tempnam() agora tem 13 bytes a mais. O comprimento total ainda depende da plataforma.

Remoção do nível de erro E_STRICT

O nível de erro E_STRICT foi removido, pois não estava mais em uso no mecanismo PHP. A constante E_STRICT foi descontinuada.

Constantes de classe de extensão que agora são tipadas

As seguintes classes de extensões agora declaram um tipo em suas constantes:

Migração de recurso para objeto

Vários resources migraram para objects. As verificações do valor de retorno usando is_resource() devem ser substituídas por verificações de false, a menos que especificado de outra forma.

DBA

As funções DBA agora aceitam e retornam objetos Dba\Connection ao invés de resources dba_connection.

ODBC

As funções ODBC agora aceitam e retornam objetos Odbc\Result ao invés de resources odbc_result.

As funções ODBC agora aceitam e retornam objetos Odbc\Connection ao invés de resources odbc_connection.

SOAP

A propriedade SoapClient::$httpurl agora é um objeto Soap\Url ao invés de um resource soap_url. Verificações que usam is_resource() (ou seja, is_resource($client->httpurl)) devem ser substituídas por verificações de null (isto é, $client->httpurl !== null).

A propriedade SoapClient::$sdl agora é um objeto Soap\Sdl ao invés de um resource soap_sdl. Verificações que usam is_resource() (ou seja, is_resource($client->sdl)) devem ser substituídas por verificações de null (i.e. $client->sdl !== null).

Novos alertas e exceções

Foram adicionados novos alertas e exceções que são acionados em erros de programação, ou seja, valores inválidos fornecidos como argumentos.

Curl

curl_multi_select() agora lança um ValueError se o parâmetro timeout for menor que 0 ou maior que PHP_INT_MAX.

Gd

imagejpeg(), imagewebp(), imagepng(), imageavif() agora lançam um ValueError quando um parâmetro quality inválido for passado.

imageavif() agora lança um ValueError se um parâmetro speed inválido for passado.

imagescale() agora lança um ValueError se os parâmetros width ou height ultrapassarem os limites inferiores ou superiores.

imagescale() agora lança um ValueError se um valor de parâmetro mode inválido for passado.

imagefilter() agora lança um ValueError com o filtro IMG_FILTER_SCATTER se os parâmetros sub ou plus ultrapassarem os limites inferiores ou superiores.

Gettext

bind_textdomain_codeset(), textdomain(), d()*gettext() agora lançam um ValueError se domain for uma string vazia.

Intl

resourcebundle_get(), ResourceBundle::get(), e acessar deslocamentos em um objeto ResourceBundle agora lançam:

  • TypeError para tipos de deslocamento inválidos
  • ValueError para uma string vazia
  • ValueError se o índice inteiro não couber em uma representação de inteiro de 32 bits com sinal

IntlDateFormatter::__construct() lança um ValueError se locale for inválido.

NumberFormatter::__construct() lança um ValueError se locale for inválido.

MBString

mb_encode_numericentity() e mb_decode_numericentity() agora verificam se map consiste somente de ints, senão um ValueError é lançado.

mb_http_input() agora sempre lança um ValueError se type for inválido.

mb_http_output() agora verifica se encoding não contém nenhum byte nulo, se contiver, um ValueError será lançado.

ODBC

odbc_fetch_row() retorna false quando row for menor ou igual a 0. Um alerta agora é emitido neste caso.

PCNTL

As funções pcntl_sigprocmask(), pcntl_sigwaitinfo() e pcntl_sigtimedwait() agora lançam:

A função pcntl_sigprocmask() agora lança um ValueError se mode não for uma das constantes SIG_BLOCK, SIG_UNBLOCK ou SIG_SETMASK.

A função pcntl_sigtimedwait() agora lança:

  • Um ValueError se seconds for menor que 0
  • Um ValueError se nanoseconds for menor que 0 ou maior que 1e9
  • Um ValueError se ambos seconds e nanoseconds forem 0

SimpleXML

Chamar simplexml_import_dom() com um objeto não-XML agora lança um TypeError ao invés de um ValueError.

Standard

A função round() agora valida o valor de mode e lança um ValueError para modos inválidos. Anteriormente, modos inválidos seria interpretados como PHP_ROUND_HALF_UP.

A função str_getcsv() agora lança ValueErrors quando os argumentos separator e enclosure não tiverem comprimento de um byte, ou se o argumento escape não tiver um byte de comprimento e nem for uma string vazia. Isto alinha o comportamento para ficar idêntico ao de fputcsv() e fgetcsv().

A função php_uname() agora lança um ValueError se mode for inválido.

A opção "allowed_classes" para unserialize() agora lança TypeErrors e ValueErrors se não for um array de nomes de classe.

XMLReader

Passar uma codificação de caracteres inválidos para XMLReader::open() ou XMLReader::XML() agora lança um ValueError.

Passar uma string contendo bytes nulos anteriormente emitia um alerta, e agora lança um ValueError.

XMLWriter

Passar uma string contendo bytes nulos anteriormente emitia um alerta, e agora lança um ValueError.

XSL

XSLTProcessor::setParameter() agora lança um ValueError quando seus argumentos contiverem bytes nulos. Isto nunca funcionou corretamente na verdade, e é por isso que agora lança uma exceção.

Chamar XSLTProcessor::importStyleSheet() com um objeto não-XML agora lança um TypeError ao invés de um ValueError.

Falha ao chamar uma função de retorno do PHP durante uma avaliação agora lança uma exceção ao invés de emitir um alerta.

DOM

Alguns métodos DOM anteriormente retornavam false ou uma exceção DOMException com código DOM_PHP_ERR se um novo nó não pudesse ser alocado. Eles agora lançam consistentemente uma exceção DOMException com código DOM_INVALID_STATE_ERR. Esta situação é extremamente improvável e a probabilidade de ser afetado é baixa. Como resultado, DOMImplementation::createDocument() agora tem um tipo de retorno provisório de DOMDocument em vez de DOMDocument|false.

Anteriormente, os objetos DOMXPath podiam ser clonados, mas resultavam em um objeto inutilizável. Isso não é mais possível, e clonar um objeto DOMXPath agora lança um Error.

O método DOMImplementation::getFeature() foi removido.

GMP

A classe GMP agora é final e não pode mais ser estendida.

MBString

Em strings inválidas (aquelas com erros de codificação), mb_substr() agora interpreta índices de caracteres da mesma maneira que a maioria das outras funções mbstring. Isto significa que os índices de caracteres retornados por mb_strpos() podem ser passados ​​para mb_substr().

Para strings SJIS-Mac (Mac japonês), os índices de caracteres passados ​​para mb_substr() agora se referem aos índices dos pontos de código Unicode que são produzidos quando a string é convertida para Unicode. Isso é significativo porque cerca de 40 caracteres SJIS-Mac são convertidos em uma sequência de vários pontos de código Unicode.

MySQLi

A constante não utilizada e não documentada MYSQLI_SET_CHARSET_DIR foi removida.

A constante MYSQLI_STMT_ATTR_PREFETCH_ROWS foi removida. O recurso não está disponível no mysqlnd.

As constantes MYSQLI_CURSOR_TYPE_FOR_UPDATE e MYSQLI_CURSOR_TYPE_SCROLLABLE foram removidas. Esta funcionalidade nunca foi implementada, nem com mysqlnd nem com libmysql.

A constante MYSQLI_TYPE_INTERVAL não utilizada, que atualmente é um esboço e um apelido para MYSQLI_TYPE_ENUM, foi removida.

MySQLnd

O código de erro relatado para os tempos limite de espera do servidor MySQL foi alterado de 2006 para 4031 nas versões 8.0.24 e superiores do servidor MySQL.

Opcache

O valor máximo da configuração opcache.interned_strings_buffer em arquiteturas de 64 bits agora é 32767. Anteriormente era 4095.

JIT

Os valores de configuração padrão para o JIT foram alterados de opcache.jit=tracing e opcache.jit_buffer_size=0 para opcache.jit=disable e opcache.jit_buffer_size=64M, respectivamente.

Isso não afeta o comportamento observável padrão, pois o JIT ainda está desabilitado por padrão. No entanto, agora ele está desativado por meio da configuração opcache.jit, em vez de opcache.jit_buffer_size. Isso pode afetar usuários que anteriormente ativaram o JIT exclusivamente por meio de opcache.jit_buffer_size, sem também especificar um modo JIT usando opcache.jit. Para ativar a compilação JIT, defina o valor de configuração opcache.jit adequadamente.

Se a compilação JIT estiver habilitada, o PHP irá agora sair com um erro fatal na inicialização se a inicialização do compilador JIT falhar por qualquer motivo.

PCNTL

As funções pcntl_sigprocmask(), pcntl_sigwaitinfo() e pcntl_sigtimedwait() agora sempre retornam false em caso de falha. Em alguns casos anteriores poderia retornar o valor -1.

PCRE

O pacote pcre2lib foi atualizado para a versão 10.44. Como consequência, isso significa que {,3} agora é reconhecido como um quantificador em vez de texto. Além disso, o significado de algumas classes de caracteres no modo UCP mudou. Consulte o » Registro de alterações do PCRE2 um registro de alterações completo.

PDO_DBLIB

Os atributos Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER e Pdo\Dblib::ATTR_DATETIME_CONVERT agora atuam como atributos booleanos em vez de atributos inteiros. Assim, definir o atributo via PDO::setAttribute() e recuperá-lo via PDO::getAttribute() espera e/ou retorna um bool.

PDO_FIREBIRD

O atributo PDO::ATTR_AUTOCOMMIT agora atua como atributos booleanos em vez de atributos inteiros. Assim, definir o atributo via PDO::setAttribute() e recuperá-lo via PDO::getAttribute() espera e/ou retorna um bool.

A extensão agora expõe algumas APIs Firebird C++, portanto construir esta extensão agora requer um compilador C++. Além disso, a extensão agora deve ser compilada com fbclient 3.0 ou superior.

PDO_MYSQL

Os atributos PDO::ATTR_AUTOCOMMIT, PDO::ATTR_EMULATE_PREPARES e PDO::MYSQL_ATTR_DIRECT_QUERY agora atuam como atributos booleanos em vez de atributos inteiros. Assim, definir o atributo via PDO::setAttribute() e recuperá-lo via PDO::getAttribute() espera e/ou retorna um bool.

PDO_PGSQL

As credenciais do DSN, quando definidas, têm prioridade sobre as contrapartes do construtor PDO, estando mais próximas dos estados da documentação.

SimpleXML

SimpleXMLElement não é apenas uma representação de um elemento XML, mas também é um RecursiveIterator. Antes do PHP 8.4.0, alguns de seus métodos (por exemplo, SimpleXMLElement::asXML() ou SimpleXMLElement::getName()) e a conversão de tais instâncias para string redefiniria implicitamente o iterador.

Isso poderia causar repetições infinitas inesperados à medida que o iterador fosse retrocedido para o início. Por exemplo:

<?php

$xmlString = "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);

$nodes = $xml->a->b;
foreach ($nodes as $nodeData) {
    echo "nodeData: " . $nodeData . "\n";

    $xml = $nodes->asXml();
}

resultaria em uma repetição infinita.

nodeData: 1
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
// ...

No entanto, esse comportamento foi corrigido e um SimpleXMLElement não redefinirá mais implicitamente os dados do iterador, a menos que seja retrocedido explicitamente. O que significa que o exemplo anterior agora resultaria em:

nodeData: 1
nodeData: 2
nodeData: 3

SOAP

SoapClient::$typemap agora é um array em vez de um resource. Verificações usando is_resource() (ou seja, is_resource($client->typemap)) devem ser substituídas por verificações de null (ou seja, $client->typemap !== null).

A extensão SOAP ganhou uma dependência opcional da extensão session. Se o PHP for compilado sem a extensão "session" e com o sinalizador de configuração --enable-rtld-now ativado, erros de inicialização ocorrerão agora se a extensão SOAP também for usada. Para resolver isso, não use rtld-now nem carregue a extensão "session".

Standard

Ao usar strcspn() com characters sendo uma string vazia, o comprimento da string agora é retornado em vez de parar incorretamente no primeiro byte nulo.

http_build_query() agora lida corretamente com enumerações apoiadas.

stream_bucket_make_writeable() e stream_bucket_new() agora irão retornar uma instância de StreamBucket ao invés de uma instância de stdClass.

Tidy

Falhas no construtor agora lançam exceções em vez de emitir alertas e ter um objeto quebrado.

XML

As funções xml_set_()*_handler() agora declaram e verificam uma assinatura efetiva de callable|string|null para os parâmetros handler. Além disso, os valores do tipo string que correspondem aos nomes dos métodos do objeto definido com xml_set_object() agora são verificados para ver se o método existe na classe do objeto passado anteriormente. Isso significa que xml_set_object() agora sempre deve ser chamada antes de definir nomes de métodos como callables. Passar uma string vazia para desabilitar o manipulador ainda é permitido, mas foi descontinuado.

No entanto, como xml_set_object() e a passagem de strings não callables foram descontinuadas, é recomendado alterar tais instâncias com um callable referindo-se diretamente ao método.