Acesso ao array $GLOBALS agora está sujeito a
    uma série de restrições.
    Acesso de leitura e escrita a elementos individuais de array como
    $GLOBALS['var'] continuam funcionando como estão.
    Acesso somente leitura para todo o array $GLOBALS também
    continua a ser suportado.
    No entanto, o acesso de escrita para todo o array $GLOBALS
    não é mais suportado. Por exemplo, array_pop($GLOBALS)
    resultará em um erro.
   
Quando um método usando variáveis estáticas é herdado (mas não sobreposto), o método herdado agora irá compartilhar variáveis estáticas com o método pai.
<?php
class A {
    public static function counter() {
        static $counter = 0;
        $counter++;
        return $counter;
    }
}
class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3), anteriormente int(1)
var_dump(B::counter()); // int(4), anteriormente int(2)
?>Um parâmetro opcional especificado antes de parâmetros obrigatórios agora é sempre tratado como obrigatório, mesmo ao chamar usando argumentos nomeados. A partir do PHP 8.0.0, mas antes do PHP 8.1.0, a função abaixo emite um aviso de descontinuação na definição, mas executa com sucesso quando chamada. A partir do PHP 8.1.0, um erro da classe ArgumentCountError é lançado, assim como seria lançado ao chamar argumentos posicionais.
<?php
function fazeriogurte($recipiente = "tigela", $sabor)
{
    return "Fazendo um(a) $recipiente de iogurte de $sabor.\n";
}
try
{
    echo fazeriogurte(sabor: "framboesa");
}
catch (Error $e)
{
    echo get_class($e), ' - ', $e->getMessage(), "\n";
}
?>Saída do exemplo acima no PHP 8.0:
Deprecated: Required parameter $sabor follows optional parameter $recipiente in example.php on line 3 Fazendo um(a) tigela de iogurte de framboesa.
Saída do exemplo acima no PHP 8.1:
Deprecated: Optional parameter $recepiente declared before required parameter $sabor is implicitly treated as a required parameter in example.php on line 3 ArgumentCountError - fazeriogurte(): Argument #1 ($recepiente) not passed
    Note que um valor padrão de null pode ser usado antes de parâmetros obrigatórios para
    especificar um tipo anulável,
    mas o parâmetro ainda será obrigatório.
   
A maioria dos métodos internos não-finais agora obrigam métodos que fazem sobrescrita a declarar um tipo de retorno compatível, do contrário um aviso de descontinuação é emitido durante a validação de herança. Caso o tipo de retorno não possa ser declarado para um método que faz sobrescrita devido a questões de compatilidade entre versões PHP, um atributo ReturnTypeWillChange pode ser adicionado para silenciar o aviso de descontinuação.
    readonly agora é uma palavra-chave. No entanto, ela ainda pode ser usada
    como nome de função.
   
    never agora é uma palavra reservada, então ela não pode ser usada para nomear uma classe,
    interface ou trait, e também é proibida de ser usada em namespaces.
   
   Diversos resources foram migrados para objects.
   Checagens de valor de retorno usando is_resource() devem ser trocadas para checagens por false.
  
     As funções FileInfo agora aceitam e retornam
     objetos finfo em vez de
     resources fileinfo.
    
     As funções FTP agora aceitam e retornam
     objetos FTP\Connection em vez de
     resources ftp.
    
     As funções IMAP agora aceitam e retornam
     objetos IMAP\Connection em vez de
     resources imap.
    
     As funções LDAP agora aceitam e retornam
     objetos LDAP\Connection em vez de
     resources ldap link.
    
     As funções LDAP agora aceitam e retornam
     objetos LDAP\Result em vez de
     resources ldap result.
    
     As funções LDAP agora aceitam e retornam
     objetos LDAP\ResultEntry em vez de
     resources ldap result entry.
    
     As funções PgSQL agora aceitam e retornam
     objetos PgSql\Connection em vez de
     resources pgsql link.
    
     As funções PgSQL agora aceitam e retornam
     objetos PgSql\Result em vez de
     resources pgsql result.
    
     As funções PgSQL agora aceitam e retornam
     objetos PgSql\Lob em vez de
     resources pgsql large object.
    
     As funções PSpell agora aceitam e retornam
     objetos PSpell\Dictionary em vez de
     resources pspell.
    
     As funções PSpell agora aceitam e retornam
     objetos PSpell\Config em vez de
     resources pspell config.
    
   mysqli_fetch_fields(), e
   mysqli_fetch_field_direct() agora irão sempre retornar
   0 para a max_length.
   Essa informação pode ser computada iterando sobre o conjunto de resultados,
   e obtendo o tamanho máximo. Era isso que o PHP estava fazendo
   internamente anteriormente.
  
   A opção MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH
   não tem mais efeito.
  
   A opção MYSQLI_STORE_RESULT_COPY_DATA
   não tem mais efeito. Passar qualquer valor para o
   parâmetro mode do
   mysqli::store_result() não tem mais efeito.
  
   mysqli::connect() agora retorna true em vez de null em caso de sucesso.
  
   O modo de manipulação de erros padrão foi alterado de "silent" para "exceptions"
   Veja a página Modo de relatório do MySQLi
   para mais detalhes sobre o que isso implica,
   e como definir esse atributo explicitamente.
   Para restaurar o comportamento anterior use:
   mysqli_report(MYSQLI_REPORT_OFF);
  
Classes estendendo mysqli_stmt::execute() agora são obrigadas a especificar o parâmetro opcional adicional.
A diretiva INI mysqlnd.fetch_data_copy foi removida. Isso não deve resultar em mudanças comportamentais visíveis pelo usuário.
Chaves privadas EC agora serão exportadas no formato PKCS#8 em vez de formatos tradicionais, assim como todas as outras chaves.
openssl_pkcs7_encrypt() e openssl_cms_encrypt() agora irão por padrão usar AES-128-CBC em vez de RC2-40. O cifrador RC2-40 é considerado inseguro e não é habilitado por padrão pelo OpenSSL 3.
   PDO::ATTR_STRINGIFY_FETCHES agora stringifica valores
   de tipo bool para "0" iy
   "1". Anteriormente bools não eram stringificados.
  
   Chamar PDOStatement::bindColumn() com
   PDO::PARAM_LOB agora irá constantemente vincular um resultado de fluxo
   quando PDO::ATTR_STRINGIFY_FETCHES não está habilitado.
   Anteriormente, o resultado seria um fluxo ou string dependendo do
   driver de banco de dados utilizado e a hora que a vinculação é realizada.
  
    Inteiros e floats em conjuntos de resultados agora serão retornados usando
    tipos nativos do PHP em vez de strings ao usar declarações preparadas emuladas.
    Isso corresponde ao comportamento das declarações preparadas nativas.
    O comportamento anterior pode ser restaurado habilitando a
    opção PDO::ATTR_STRINGIFY_FETCHES.
   
    Inteiros e floats em conjuntos de resultados agora serão retornados usando
    tipos nativos do PHP.
    O comportamento anterior pode ser restaurado habilitando a
    opção PDO::ATTR_STRINGIFY_FETCHES.
   
Para cumprir com a interface ArrayAccess, Phar::offsetUnset() e PharData::offsetUnset() não retorna mais um bool.
version_compare() não aceita mais abreviações de operadores não documentados.
   htmlspecialchars(),
   htmlentities(),
   htmlspecialchars_decode(),
   html_entity_decode(),
   e get_html_translation_table()
   agora usam ENT_QUOTES | ENT_SUBSTITUTE em vez de
   ENT_COMPAT por padrão.
   Isso significa que ' é escapada para
   ' enquanto antes nada era feito.
   Adicionalmente, UTF-8 malformado será substituído por um caractere de substituição
   Unicode, ao invés de resultar em uma string vazia.
  
   debug_zval_dump() agora imprime a contagem de referência de empacotadores de
   referência com a sua contagem, em vez de apenas prefixar
   & ao valor.
   Isso modela de forma mais precisa a representação de referência desde o PHP 7.0.
  
   debug_zval_dump() agora imprime interned
   em vez de uma contagem de referência falsa para strings internalizadas e arrays imutáveis.
  
SplFixedArray, agora será codificado em JSON como um array
