Embora não seja explicitamente citado nesta seção, cada nova função, classe, interface, enumeração, ou constante pode fazer com que uma exceção de redeclaração do tipo Error seja lançada.
    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.
    Encontrar recursão durante uma comparação agora resulta em
    exceção Error ao invés de
    erro fatal E_ERROR.
   
    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".
   
    As constantes PHP_DEBUG e PHP_ZTS
    agora são do tipo bool.
    Anteriormente eram do tipo int.
   
O nome dos arquivos enviados e criados pela função tempnam() agora tem 13 bytes a mais. O comprimento total ainda depende da plataforma.
As seguintes classes de extensões agora declaram um tipo em suas constantes:
   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.
  
    As funções DBA agora aceitam e retornam
    objetos Dba\Connection ao invés de
    resources dba_connection.
   
    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.
   
    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).
   
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_multi_select() agora lança um
    ValueError se o
    parâmetro timeout for menor que
    0 ou maior que PHP_INT_MAX.
   
    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.
   
    bind_textdomain_codeset(), textdomain(), d()*gettext()
    agora lançam um ValueError se
    domain for uma string vazia.
   
resourcebundle_get(), ResourceBundle::get(), e acessar deslocamentos em um objeto ResourceBundle agora lançam:
    IntlDateFormatter::__construct() lança um
    ValueError se
    locale for inválido.
   
    NumberFormatter::__construct() lança um
    ValueError se
    locale for inválido.
   
    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_fetch_row() retorna false quando
    row for menor ou igual a 0.
    Um alerta agora é emitido neste caso.
   
As funções pcntl_sigprocmask(), pcntl_sigwaitinfo() e pcntl_sigtimedwait() agora lançam:
signals estiver vazio
      (exceto para pcntl_sigprocmask() se
      mode for igual a SIG_SETMASK)
     signals não for um int
     signals não for um número de sinal válido.
     
    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:
seconds for menor que 0
     nanoseconds for menor que 0
      ou maior que 1e9
     seconds e nanoseconds
      forem 0
     Definir um valor não positivo para session.gc_divisor ou um valor negativo para session.gc_probability agora emite um alerta.
Chamar simplexml_import_dom() com um objeto não-XML agora lança um TypeError ao invés de um ValueError.
    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.
   
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.
Passar uma string contendo bytes nulos anteriormente emitia um alerta, e agora lança um ValueError.
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.
   Símbolos de number em formatos relativos
   novamente aceitam múltiplos sinais, por exemplo, +-2.
  
   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.
A classe GMP agora é final e não pode mais ser estendida.
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.
   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.
   
  
   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.
  
   O valor máximo da configuração
   opcache.interned_strings_buffer
   em arquiteturas de 64 bits agora é 32767.
   Anteriormente era 4095.
  
    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.
   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.
  
   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
   para um registro de alterações completo.
  
   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.
  
   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.
   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.
  
As credenciais do DSN, quando definidas, têm prioridade sobre as contrapartes do construtor PDO, estando mais próximas dos estados da documentação.
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 inesperadas à 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
   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".
   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.
Falhas no construtor agora lançam exceções em vez de emitir alertas e ter um objeto quebrado.
   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.
