## Alterações incompatíveis com versões anteriores

### Núcleo do PHP

#### Comparação entre String e Número

Comparações não estritas entre números e strings não numéricas, agora funcionam convertendo o número em string e comparando as strings. As comparações entre números e strings numéricas continuam funcionando como antes. Notavelmente, isso significa que a comparação: `0 == "not-a-number"` agora é considerada falsa.

Comparação | Antes | Depois
--- | --- | ---
`0 == "0"` | `true` | `true`
`0 == "0.0"` | `true` | `true`
`0 == "foo"` | `true` | `false`
`0 == ""` | `true` | `false`
`42 == " 42"` | `true` | `true`
`42 == "42foo"` | `true` | `false`

#### Outras mudanças incompatíveis

- `match` agora é uma palavra reservada.

- `mixed` agora é uma palavra reservada, portanto, não pode ser usado para nomear uma classe, interface ou trait, e também é proibido de ser usado em namespaces.

- As falhas de asserção agora são lançadas por padrão. Se o comportamento antigo é desejado, `assert.exception=0` pode ser definido nas configurações INI.

- Métodos com o mesmo nome de classe não são mais interpretados como construtores. O método __construct() deve ser utilizado em seu lugar.

- A capacidade de chamar métodos não estáticos estaticamente foi removida. Por isso a função is_callable() irá falhar ao verificar um método não estático com um nome de classe (deve se realizar uma verificação com uma instância de objeto).

- Foram removidas as conversões de tipos, `(real)` e `(unset)`.

- A diretiva do php.ini track_errors foi removida. Isto significa que a variável php_errormsg não está mais disponível. A função error_get_last() deve ser utilizada em seu lugar.

- A capacidade de definir constantes que não diferenciam maiúsculas de minúsculas foi removida. O terceiro argumento para a função define() não pode ser mais `true`.

- A capacidade de especificar um auto carregamento utilizando a função __autoload() foi removida. A função spl_autoload_register() deve ser utilizada em seu lugar.

- O argumento `errcontext` não será mais usado para manipulação de erros personalizados definido com a função set_error_handler().

- A função create_function() foi removida. Ao invés disso, funções anônimas devem ser utilizadas.

- A função each() foi removida. `foreach` ou ArrayIterator devem ser utilizados em seu lugar.

- Foi removida a capacidade de desvincular this de closures que foram criadas a partir de um método, usando Closure::fromCallable() ou ReflectionMethod::getClosure().

- A habilidade de desvincular this de closures que contêm usos de this também foi removida.

- A habilidade de utilizar a função array_key_exists() com objetos foi removida. as funções isset() ou property_exists() devem ser usadas em seu lugar.

- O comportamento da função array_key_exists() com relação ao tipo do parâmetro `key` agora é consistente com a função isset() e acesso normal à arrays. Todos os tipos de chave agora usam as coerções usuais e as chaves de array/objeto lançam um TypeError.

- Qualquer array com número n em sua primeira posição utilizará n+1 em sua próxima chave implícita mesmo se n for negativo.

- O nível de error_reporting padrão agora é `E_ALL`. Anteriormente excluía `E_NOTICE` e `E_DEPRECATED`.

- display_startup_errors agora é habilitado por padrão.

- Usar parent dentro de uma classe sem pai agora produzirá um erro fatal em tempo de execução.

- O operador `@` não irá mais silenciar erros fatais (`E_ERROR`, `E_CORE_ERROR`, `E_COMPILE_ERROR`, `E_USER_ERROR`, `E_RECOVERABLE_ERROR`, `E_PARSE`). Manipuladores de erros que esperam que error_reporting seja `0` quando `@` é usado, devem ser ajustados para usar uma verificação de máscara:

      <?php
      // Substituir isso ...
      function my_error_handler($err_no, $err_msg, $filename, $linenum) {
          if (error_reporting() == 0) {
              return false;
          }
          // ...
      }

      // ... por isso:
      function my_error_handler($err_no, $err_msg, $filename, $linenum) {
          if (!(error_reporting() & $err_no)) {
              return false;
          }
          // ...
      }
      ?>

  Adicionalmente, cuidados devem ser tomados para que mensagens de erro não sejam mostradas no ambiente de produção, o que pode resultar em vazamento de informações. Certifique-se de que a diretiva `display_errors=Off` seja usada em conjunto com o log de erros.

- `#[` não é mais interpretado como o início de um comentário, já que esta sintaxe é utilizada agora para atributos.

- Erros de herança devido a assinaturas de métodos incompatíveis (violações de LSP) agora sempre gerarão um erro fatal. Antes, um aviso era gerado em alguns casos.

- A precedência dos operadores de concatenação foi modificada em relação ao bitshifts tanto na adição como na subtração.

      <?php
      echo "Sum: " . $a + $b;
      // Era interpretado como:
      echo ("Sum: " . $a) + $b;
      // e passa a ser interpretado como:
      echo "Sum:" . ($a + $b);
      ?>

- Argumentos com um valor padrão que avaliam `null` em tempo de execução, não irão mais marcar o tipo do parâmetro como implícito. Um tipo explícito nulo, ou explicitamente `null` como argumento padrão deve ser usado em seu lugar.

      <?php
      // Subistituir
      function test(int $arg = CONST_RESOLVING_TO_NULL) {}
      // Por isso
      function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
      // Ou isso
      function test(int $arg = null) {}
      ?>

- Uma série de avisos foram convertidos para exceções do tipo Error:

  - A tentativa de escrita em uma propriedade de um não-objeto. Anteriormente isso criava implicitamente um objeto stdClass para strings nulas, falsas e vazias.
  - A tentativa de anexar um elemento a um array para a qual a chave PHP_INT_MAX já está em uso.
  - Tentar usar um tipo inválido (array ou objeto) como uma chave de array ou deslocamento de string.
  - A tentativa de escrever em um índice de array de um valor escalar.
  - Tentar descompactar um não-array/Traversable.
  - Tentar acessar constantes não qualificadas que são indefinidas. Anteriormente, os acessos constantes não qualificados resultavam em um aviso e eram interpretados como strings.
  - Passar o número errado de argumentos para uma função sem argumento variadic ira lançar uma exceção ArgumentCountError.
  - Passar tipos contáveis inválidos para count() irá lançar uma exceção TypeError.

  Uma série de notificações foram convertidas em avisos:

  - A tentativa de leitura em uma variável não definida.
  - A tentativa de leitura em uma propriedade não definida.
  - A tentativa de leitura em uma chave de array não definido.
  - A tentativa de leitura em uma propriedade de um não-objeto.
  - A tentativa de acesso em um índice de array em um não-array.
  - A tentativa de conversão de um array para uma string.
  - A tentativa de usar um resource como uma chave de array.
  - A tentativa de usar null, um booleano ou um número de ponto flutuante(float) como uma posição em uma string.
  - A tentativa de leitura em uma posição fora dos limites de uma string.
  - A tentativa de atribuir uma string vazia a uma posição de uma string.

- A tentativa de atribuir múltiplos bytes em uma posição de uma string agora emite um aviso.

- Caracteres inesperados no código fonte (como bytes NUL fora de strings) agora irá resultar em uma exceção ParseError em vez de um aviso do compilador.

- As exceções não capturadas agora passam por "desligamento limpo", o que significa que os destrutores são chamados após uma exceção não detectada.

- O erro fatal em tempo de compilação "Only variables can be passed by reference" foi adiado até o tempo de execução, e convertido em uma exceção de Error "Argument cannot be passed by reference".

- Alguns alertas do tipo "Only variables should be passed by reference" foram convertidas para exceções do tipo "Argument cannot be passed by reference"

- O nome gerado para classes anônimas foi modificado. Agora, inclui o nome da primeira classe ou interface:

      <?php
      new class extends ParentClass {};
      // -> ParentClass@anonymous
      new class implements FirstInterface, SecondInterface {};
      // -> FirstInterface@anonymous
      new class {};
      // -> class@anonymous
      ?>

  O nome mostrado acima ainda é seguido por um byte NUL e um sufixo único.

- As referências de método de traits não absolutas em adaptações de alias de traits agora precisam ser inequívocas:

      <?php
      class X {
          use T1, T2 {
              func as otherFunc;
          }
          function func() {}
      }
      ?>

  Se `T1::func()` e `T2::func()` existem, este código anteriormente era aceito de forma silenciosa e func assumia referência a `T1::func`. Agora irá gerar um erro fatal, e `T1::func` ou `T2::func` precisam ser escritos explicitamente.

- A assinatura de métodos abstratos definido nas características agora é verificada no método de implementação da classe:

      <?php
      trait MyTrait {
          abstract private function neededByTrait(): string;
      }

      class MyClass {
          use MyTrait;

          // Erro por conta do retorno desalinhado.
          private function neededByTrait(): int { return 42; }
      }
      ?>

- Funções desabilitadas agora são tratadas da mesma forma que funções não existentes. Ao chamar uma função desabilitada será informado que ela é desconhecida, e redefinir uma função desabilitada agora é possível.

- Os empacotadores de fluxo `data://` não podem mais ser writable (gravável), indo de encontro ao comportamento documentado.

- Os operadores aritméticos e bitwise (bit a bit) `+`, `-`, `*`, `/`, `**`, `%`, `<<`, `>>`, `&`, `|`, `^`, `~`, `++`, `--` irão agora apresentar um TypeError quando um dos operandos estiver em um array, resource ou em um object não sobrecarregado (non-overloaded). A única exceção a isto é a operação de mesclagem de array com `+`, que permanece suportada.

- A conversão de float para string agora sempre terá o mesmo comportamento, independentemente da localidade.

      <?php
      setlocale(LC_ALL, "de_DE");
      $f = 3.14;
      echo $f, "\n";
      // Anteriormente: 3,14
      // Agora:         3.14
      ?>

  Veja as funções printf(), number_format() e NumberFormatter() para customizar a formatação de números.

- O suporte para chaves (curly braces), cujo uso para acesso de deslocamento estava descontinuado, foi removido.

      <?php
      // Ao invés de:
      $array{0};
      $array{"key"};
      // Usar:
      $array[0];
      $array["key"];
      ?>

- Aplicar o modificador final ou método privado agora irá produzir um aviso, a menos que o método seja o construtor.

- Se um objeto construtor chama a função exit(), o objeto destrutor não será chamado. Isto vai de encontro ao comportamento que o construtor lança.

- Nomes de Namespace não podem mais conter espaços em branco: Enquanto `Foo\Bar` será reconhecido como um nome de Namespace, `Foo \ Bar` não será. Por outro lado, as palavras-chave agora serão permitidas como segmentos de um namespace, o que permite a mudança na interpretação do código: `new\x` agora é o mesmo que `constant('new\x')`, e não `new \x()`.

- Os ternários aninhados agora exigem parênteses explícitos.

- debug_backtrace() e Exception::getTrace() agora não mais apresentam referências aos argumentos. Não será possível mudar os argumentos de uma função através de um backtrace.

- O uso de strings numéricas foi modificado para ser mais intuitivo e menos sujeito a erros. Seguindo os espaços em branco, é permitido agora strings numéricas para tratamento de consistência contendo espaços em branco. Isso afeta principalmente:

  - A função is_numeric()
  - Comparações string a string
  - Declaração de tipos
  - Operações de incremento e decremento

  O conceito de um "leading-numeric string" foi praticamente abandonado; os casos onde permanecem são para facilitar a migração. Strings que emitem um `E_NOTICE` "A non well-formed numeric value encountered" agora emitirão um `E_WARNING` "A non-numeric value encountered" e todas as strings que emitiram um `E_WARNING` "A non-numeric value encountered" agora lançarão um erro TypeError. Isso afeta principalmente:

  - Operações aritméticas
  - Operações bit a bit

  Esta mudança do `E_WARNING` para TypeError também afeta o `E_WARNING` "Illegal string offset 'string'" para o posicionamento ilegal de strings. O comportamento de conversões explícitas de strings para int/float não foi alterado.

- Métodos mágicos agora podem ter argumentos e retornar tipos verificados se eles foram declarados. As assinaturas devem corresponder à seguinte lista:

  - `__call(string $name, array $arguments): mixed`
  - `__callStatic(string $name, array $arguments): mixed`
  - `__clone(): void`
  - `__debugInfo(): ?array`
  - `__get(string $name): mixed`
  - `__invoke(mixed $arguments): mixed`
  - `__isset(string $name): bool`
  - `__serialize(): array`
  - `__set(string $name, mixed $value): void`
  - `__set_state(array $properties): object`
  - `__sleep(): array`
  - `__unserialize(array $data): void`
  - `__unset(string $name): void`
  - `__wakeup(): void`

- As chaves do array passados para a função call_user_func_array() agora podem ser interpretadas como nomes de parâmetros, em vez de serem silenciosamente ignoradas.

- A declaração da função chamada `assert()` dentro de um namespace não é mais permitida e gera um `E_COMPILE_ERROR`. A função assert() recebe um tratamento especial pelo motor do PHP, o que pode levar a comportamentos inconsistentes quando definido como uma função de namespace com o mesmo nome.

### Migração de Resource para Objeto

Diversos resources foram migrados para objects. Verificações de valor de retorno usando a função is_resource() devem ser substituídas por checagens para `false`.

- A função curl_init() agora retornará um objeto CurlHandle ao invés de um resource. A função curl_close() não tem mais efeito, em vez disso a instância da classe CurlHandle é destruída automaticamente se não for mais referenciada.

- A função curl_multi_init() agora retornará um objeto CurlMultiHandle ao invés de um resource. A função curl_multi_close() não tem mais efeito, em vez disso a instância da classe CurlMultiHandle é destruída automaticamente se não for mais referenciada.

- curl_share_init() agora retornará um objeto CurlShareHandle em vez de um resource. A função curl_share_close() não tem mais efeito, em vez disso a instância da classe CurlShareHandle é destruída automaticamente se não for mais referenciada.

- enchant_broker_init() agora retornará um objeto EnchantBroker em vez de um resource.

- enchant_broker_request_dict() e enchant_broker_request_pwl_dict() agora retornarão um objeto EnchantDictionary em vez de um resource.

- A extensão GD agora usa objetos GdImage como a estrutura de dados interna para imagens, em vez de resources. A função imagedestroy() não tem mais efeito; em vez disso a instância GdImage é destruída automaticmanete se não for mais referenciada.

- openssl_x509_read() e openssl_csr_sign() agora retornarão um objeto OpenSSLCertificate em vez de um resource. A função openssl_x509_free() está descontinuada e não tem mais efeito, em vez disso a instância OpenSSLCertificate é destruída automaticamente se não for mais referenciada.

- openssl_csr_new() agora retornará um objeto OpenSSLCertificateSigningRequest em vez de um resource.

- openssl_pkey_new() agora retornará um objeto OpenSSLAsymmetricKey em vez de um resource. A função openssl_pkey_free() está descontinuada e não tem mais efeito, em vez disso a instância OpenSSLAsymmetricKey é destruída automaticamente se não for mais referenciada.

- shmop_open() irá agora retornar um objeto Shmop ao invés de um resource. A função shmop_close() não tem mais efeitos, e foi descontinuada. A instância de Shmop será automaticamente destruída quando não seja mais referenciada.

- socket_create(), socket_create_listen(), socket_accept(), socket_import_stream(), socket_addrinfo_connect(), socket_addrinfo_bind(), e socket_wsaprotocol_info_import() agora retornarão um objeto Socket em vez de um resource. socket_addrinfo_lookup() agora retornará um array de objetos AddressInfo em vez de resources.

- msg_get_queue() agora retornará um objeto SysvMessageQueue em vez de um resource.

- sem_get() agora retornará um objeto SysvSemaphore em vez de um resource.

- shm_attach() agora retornará um objeto SysvSharedMemory em vez de um resource.

- xml_parser_create() e xml_parser_create_ns() agora retornarão um objeto XMLParser em vez de um resource. A função xml_parser_free() não tem mais efeito, em vez disso a instância XMLParser é automaticamente destruída se não for mais referenciada.

- A função XMLWriter agora aceita e retorna, respectivamente, objetos XMLWriter em vez de resources.

- inflate_init() agora retornará um objeto InflateContext em vez de um resource.

- deflate_init() agora retornará um objeto DeflateContext em vez de um resource.

### COM e .Net (Windows)

A capacidade de importar constantes que não diferenciam maiúsculas de minúsculas de bibliotecas de tipos foi removida. O segundo argumento para com_load_typelib() não pode mais ser falso; com.autoregister_casesensitive não pode mais ser desabilitado; marcadores que não diferenciam maiúsculas de minúsculas em com.typelib_file são ignorados.

### CURL

`CURLOPT_POSTFIELDS` não aceita mais objetos como arrays. Para interpretar um objeto como um array, executar uma conversão explícita de `(array)`. O mesmo se aplica a outras opções que aceitam arrays também.

### Data e hora

mktime() e gmmktime() agora requer pelo menos um argumento. time() pode ser usado para obter o registro de data e hora atual.

### DOM

Classes não implementadas da extensão DOM que não tinham comportamento e continham dados de teste foram removidos. Essas classes também foram removidas na versão mais recente do DOM padrão:

- DOMNameList
- DomImplementationList
- DOMConfiguration
- DomError
- DomErrorHandler
- DOMImplementationSource
- DOMLocator
- DOMUserDataHandler
- DOMTypeInfo
- DOMStringExtend

Métodos não implementados da extensão DOM que não tinham comportamento foram removidos:

- DOMNamedNodeMap::setNamedItem()
- DOMNamedNodeMap::removeNamedItem()
- DOMNamedNodeMap::setNamedItemNS()
- DOMNamedNodeMap::removeNamedItemNS()
- DOMText::replaceWholeText()
- DOMNode::compareDocumentPosition()
- DOMNode::isEqualNode()
- DOMNode::getFeature()
- DOMNode::setUserData()
- DOMNode::getUserData()
- DOMDocument::renameNode()

### Enchant

- enchant_broker_list_dicts(), enchant_broker_describe() e enchant_dict_suggest() agora retornam um array vazio no lugar de `null`.

### Exif

read_exif_data() foi removido; exif_read_data() deve ser usado em seu lugar.

### Filter

- A `FILTER_FLAG_SCHEME_REQUIRED` e `FILTER_FLAG_HOST_REQUIRED` sinalizadores para o filtro `FILTER_VALIDATE_URL` foram removidas. O `scheme` e `host` são (e foram) sempre necessários.

- A fonte `INPUT_REQUEST` e `INPUT_SESSION` para filter_input() etc. foram removidos. Estes nunca foram implementados e seu uso sempre gerou um warning.d

### GD

- A função descontinuada image2wbmp() foi removida.

- As funções descontinuadas png2wbmp() e jpeg2wbmp() foram removidas.

- O parametro padrão `mode` de imagecropauto() não aceita mais `-1`. `IMG_CROP_DEFAULT` deve ser usado no lugar.

- No Windows, php_gd2.dll foi renomeado para php_gd.dll.

### GMP

gmp_random() foi removida. Uma das gmp_random_range() ou gmp_random_bits() deve ser usado no lugar.

### Iconv

implementações de iconv que não definem corretamente errno em caso de erros não são mais suportadas.

### IMAP

- O argumento `default_host` não utilizado de imap_headerinfo() foi removido.

- A função imap_header() que é um alias de imap_headerinfo() foi removida.

### Funções de Internacionalização

- A constante descontinuada `INTL_IDNA_VARIANT_2003` foi removida.

- A constante descontinuada `Normalizer::NONE` foi removida.

### LDAP

- As funções descontinuadas ldap_sort(), ldap_control_paged_result() e ldap_control_paged_result_response() foram removidas.

- A interface deldap_set_rebind_proc() foi mudada; o parâmetro `callback` não aceita strings vazias; `null` deve ser usado no lugar.

### MBString

- A diretiva mbstring.func_overload foi removida. As constantes relacionadas `MB_OVERLOAD_MAIL`, `MB_OVERLOAD_STRING`, e `MB_OVERLOAD_REGEX` também foram removidas. Finalmente, a `"func_overload"` e a `"func_overload_list"` entradas mb_get_info() foram removidas.

- mb_parse_str() não pode mais ser usado sem especificar um array de resultados.

- Vários sinônimos mbregex descontinuados foram removidos. Veja a seguinte lista para quais funções devem ser usadas:

  - mbregex_encoding() → mb_regex_encoding()
  - mbereg() → mb_ereg()
  - mberegi() → mb_eregi()
  - mbereg_replace() → mb_ereg_replace()
  - mberegi_replace() → mb_eregi_replace()
  - mbsplit() → mb_split()
  - mbereg_match() → mb_ereg_match()
  - mbereg_search() → mb_ereg_search()
  - mbereg_search_pos() → mb_ereg_search_pos()
  - mbereg_search_regs() → mb_ereg_search_regs()
  - mbereg_search_init() → mb_ereg_search_init()
  - mbereg_search_getregs() → mb_ereg_search_getregs()
  - mbereg_search_getpos() → mb_ereg_search_getpos()
  - mbereg_search_setpos() → mb_ereg_search_setpos()

- O modificador `e` para mb_ereg_replace() foi removido. mb_ereg_replace_callback() deve ser usado em seu lugar.

- Um argumento de padrão não string para mb_ereg_replace() agora será interpretado como uma string em vez de um ponto de código ASCII. O comportamento anterior pode ser restaurado com uma chamada explícita para chr().

- O argumento `needle` para mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), mb_strstr(), mb_stristr(), mb_strrchr() e mb_strrichr() agora pode estar vazio.

- O parâmetro `is_hex`, que não era usado internamente, foi removido de mb_decode_numericentity().

- O comportamento herdado de passar a codificação como o terceiro argumento em vez de um deslocamento para a função mb_strrpos() foi removida; um `0` explícito offset com a codificação deve ser fornecido como o quarto argumento.

- Os aliases de codificação de caracteres `ISO_8859-*` foram substituídos por Aliases `ISO8859-*` para melhor interoperabilidade com a extensão iconv. os aliases mbregex ISO 8859 com sublinhados (`ISO_8859_*` e `ISO8859_*`) também foram removidos.

- mb_ereg() e mb_eregi() agora retornarão valores booleanos `true` sobre uma partida de sucesso. Anteriormente, eles retornavam inteiro `1` se `matches` não foi passado, ou `max(1, strlen($matches[0]))` se `matches` foi passado.

### OCI8

- A classe OCI-Lob agora é chamada de OCILob, e a a classe OCI-Collection agora se chama OCICollection para conformidade de nome imposta pelas ferramentas de anotação de tipo PHP 8 arginfo.

- Várias funções de alias foram marcadas como descontinuadas.

- oci_internal_debug() e seu alias ociinternaldebug() foram removidos.

### ODBC

- odbc_connect() não reutiliza mais conexões.

- O parâmetro `flags` não usado de odbc_exec() foi removido.

### OpenSSL

- openssl_seal() e openssl_open() agora requerem `method` a ser passado, como o padrão anterior de `"RC4"` é considerado inseguro.

### Expressões regulares (Compatíveis com Perl)

Ao passar sequências de escape inválidas, elas não são mais interpretadas como literais. Esse comportamento anteriormente exigia o modificador `X` – que agora é ignorado.

### Objetos de dados do PHP

- O modo padrão de manipulação de erro foi alterado de "silent" para "exceptions". Consulte Erros e manipulação de erros para detalhes.

- As assinaturas de alguns métodos PDO foram alteradas:

  - `PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs)`
  - `PDOStatement::setFetchMode(int $mode, mixed ...$args)`

### PDO ODBC

A diretiva pdo_odbc.db2_instance_name do php.ini foi removida.

### PDO MySQL

PDO::inTransaction() agora relata o estado real da transação da conexão, em vez de uma aproximação mantida pelo PDO. Se uma consulta que é sujeito para "confirmação implícita" é executado, PDO::inTransaction() posteriormente retornará `false`, pois uma transação não está mais ativa.

### PostgreSQL

- A sintaxe descontinuada de pg_connect() usando vários parâmetros em vez de uma string de conexão não é mais suportada.

- As assinaturas descontinuadas de pg_lo_import() e pg_lo_export() que passam a conexão como o último argumento não são mais suportadas. A conexão deve ser passada como primeiro argumento.

- pg_fetch_all() agora retornará um array vazio em vez de `false` para resultado conjuntos com zero linha.

### Phar

Os metadados associados a um phar não serão mais serializados automaticamente, para corrigir possíveis vulnerabilidades de segurança devido à instanciação de objetos, carregamento automático etc.

### Reflection

- As assinaturas do método

  - `ReflectionClass::newInstance($args)`
  - `ReflectionFunction::invoke($args)`
  - `ReflectionMethod::invoke($object, $args)`

  foram alterados para:

  - `ReflectionClass::newInstance(...$args)`
  - `ReflectionFunction::invoke(...$args)`
  - `ReflectionMethod::invoke($object, ...$args)`

  O código que deve ser compatível com PHP 7 e PHP 8 pode usar as seguintes assinaturas para serem compatíveis com ambas as versões:

  - `ReflectionClass::newInstance($arg = null, ...$args)`
  - `ReflectionFunction::invoke($arg = null, ...$args)`
  - `ReflectionMethod::invoke($object, $arg = null, ...$args)`

- O método ReflectionType::__toString() agora retornará uma completa representação de depuração do tipo, e não está mais descontinuada. Em particular, o resultado incluirá um indicador de nulidade para tipos anuláveis. O formato do valor de retorno não é estável e pode mudar entre as versões do PHP.

- Métodos export() de reflexão foram removidos. Em vez disso, os objetos de reflexão podem ser convertidos em string.

- ReflectionMethod::isConstructor() e ReflectionMethod::isDestructor() agora também retorna `true` por __construct() e __destruct() métodos de interfaces. Anteriormente, isso só seria verdade para métodos de classes e traits.

- O método ReflectionType::isBuiltin() foi movido para ReflectionNamedType. ReflectionUnionType não possui esse método.

### Sockets

- As constantes descontinuadas `AI_IDN_ALLOW_UNASSIGNED` e `AI_IDN_USE_STD3_ASCII_RULES` `flags` para socket_addrinfo_lookup() foram removidas.

### Biblioteca PHP padrão (SPL)

- SplFileObject::fgetss() foi removido.

- SplFileObject::seek() agora sempre posiciona no começo da linha. Anteriormente, posições `>=1` resultavam no começo da linha seguinte.

- SplHeap::compare() agora especifica uma assinatura de método. Herdando classes, implementar este método agora terá que usar uma assinatura de método compatível.

- SplDoublyLinkedList::push(), SplDoublyLinkedList::unshift() e SplQueue::enqueue() agora retornam void no lugar de `true`.

- spl_autoload_register() agora sempre lançará um TypeError em argumentos inválidos, portanto, o segundo argumento `do_throw` é ignorado e um aviso será emitido se for definido como `false`.

- SplFixedArray agora é um IteratorAggregate e não um Iterator. SplFixedArray::rewind(), SplFixedArray::current(), SplFixedArray::key(), SplFixedArray::next() e SplFixedArray::valid() foram removidos. Em seu lugar, SplFixedArray::getIterator() foi adicionado. Qualquer código que usa explicitamente iteração sobre SplFixedArray agora deve obter um Iterator até SplFixedArray::getIterator(). Isso significa que SplFixedArray agora é seguro para uso em loops aninhados.

### Biblioteca padrão

- assert() não avaliará mais argumentos de string, em vez disso, eles serão tratados como qualquer outro argumento. `assert($a == $b)` deve ser usado em vez de `assert('$a == $b')`. O assert.quiet_eval diretiva ini e as constantes `ASSERT_QUIET_EVAL` também foram removidas, pois não seriam mais ter qualquer efeito.

- parse_str() não pode mais ser usado sem especificar um array de resultados.

- O filtro string.strip_tags foi removido.

- O argumento `needle` de strpos(), strrpos(), stripos(), strripos(), strstr(), strchr(), strrchr() e stristr() agora sempre será interpretado como uma string. Anteriormente agulhas não-string foram interpretadas como um ponto de código ASCII. Uma chamada explícita para chr() pode ser usado para restaurar o comportamento anterior.

- O argumento `needle` para strpos(), strrpos(), stripos(), strripos(), strstr(), stristr() e strrchr() podem agora estar vazios.

- O argumento `length` para substr(), substr_count(), substr_compare() e iconv_substr() agora pode ser `null`. `null` os valores se comportarão como se não houvesse argumento de comprimento fornecido e, portanto, retornará o restante da string em vez de uma string vazia.

- O argumento `length` para array_splice() agora pode ser `null`. `null` os valores se comportarão de forma idêntica à omissão do argumento, removendo assim tudo do `offset` até o final do array.

- O argumento `args` de vsprintf(), vfprintf() e vprintf() agora devem ser um array. Anteriormente qualquer tipo era aceito.

- A opção `'salt'` de password_hash() não é mais suportado. Se a opção `'salt'` for usada, um aviso será gerado, o salt é ignorado e um salt gerado é usado em seu lugar.

- A função quotemeta() agora retornará uma string vazia se uma string vazia foi passada. Anteriormente `false` era devolvido.

- As seguintes funções foram removidas.

  - hebrevc()
  - convert_cyr_string()
  - money_format()
  - ezmlm_hash()
  - restore_include_path()
  - get_magic_quotes_gpc()
  - get_magic_quotes_runtime()
  - fgetss()

- `FILTER_SANITIZE_MAGIC_QUOTES` foi removida.

- Chamar implode() com parâmetros na ordem inversa `($pieces, $glue)` não é mais suportado.

- parse_url() agora distinguirá consultas e fragmentos ausentes e vazios:

  - `http://example.com/foo → query = null, fragment = null`
  - `http://example.com/foo? → query = "", fragment = null`
  - `http://example.com/foo# → query = null, fragment = ""`
  - `http://example.com/foo?# → query = "", fragment = ""`
  Anteriormente, todos os casos resultavam em consultas e fragmentos `null`.

- var_dump() e debug_zval_dump() agora serão números de ponto flutuante usando serialize_precision em vez de precisão. Em uma configuração padrão, isto significa que os números de ponto flutuante agora são impressos com total precisão por essas funções depuradoras.

- Se o array retornado por __sleep() contiver propriedades inexistentes, estas agora são silenciosamente ignoradas. Anteriormente, tais propriedades teriam sido serializadas como se tivessem o valor `null`.

- A localidade padrão na inicialização agora é sempre `"C"`. Nenhuma localidade é herdada do ambiente por padrão. Anteriormente, `LC_ALL` era definida como `"C"`, enquanto `LC_CTYPE` era herdada do ambiente. No entanto, algumas funções não respeitavam a localidade herdada sem uma chamada explícita setlocale(). Uma chamada setlocale() explícita agora é sempre necessária se um componente de localidade deve ser alterado do padrão.

- O fallback DES descontinuado em crypt() foi removido. Se um desconhecido formato salt for passado para crypt(), a função falhará com `*0` em vez de voltar para um hash DES fraco agora.

- A especificação de rodadas fora do intervalo para SHA256/SHA512 crypt() agora falhará com `*0` em vez de fixar no limite mais próximo. Isso corresponde ao comportamento da glibc.

- O resultado das funções de classificação pode ter mudado, se o array contiver elementos que comparam como igual.

- Quaisquer funções que aceitam retornos de chamada que não são explicitamente especificados para aceitar parâmetros por referência agora avisará se um retorno de chamada com parâmetros de referência for usado. Exemplos incluem array_filter() e array_reduce(). Este já era o caso para a maioria, mas não para todas as funções anteriormente.

- O empacotador de fluxo HTTP usado por funções como file_get_contents() agora anuncia HTTP/1.1 em vez de HTTP/1.0 por padrão. Isso não muda o comportamento do cliente, mas pode fazer com que os servidores respondam de forma diferente. Para manter o comportamento antigo, defina a opção de contexto de fluxo `'protocol_version'`, por exemplo

      <?php
      $ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]);
      echo file_get_contents('http://example.org', false, $ctx);
      ?>

- Chamar crypt() sem um salt explícito não é mais suportado. Se você gostaria de produzir um hash forte com salt gerado automaticamente, use password_hash() em vez disso.

- substr(), mb_substr(), iconv_substr() e grapheme_substr() agora fixa consistentemente os deslocamentos fora dos limites à string fronteira. Anteriormente, `false` era retornado em vez da string vazia em alguns casos.

- No Windows, as funções de execução do programa (proc_open(), exec(), popen() etc.) usando o shell, agora execute consistentemente %comspec% /s /c "$commandline", que tem o mesmo efeito que executar $commandline (sem aspas adicionais).

### Sysvsem

- O parâmetro `auto_release` de sem_get() foi alterado para aceitar valores booleanos em vez de int.

### Tidy

- O parâmetro `use_include_path`, que não era usado internamente, foi removido de tidy_repair_string().

- tidy::repairString() e tidy::repairFile() se tornaram métodos estáticos.

### Tokenizer

- Tokens `T_COMMENT` não incluirão mais uma quebra de linha à direita. Em vez disso, a quebra de linha será parte de um token `T_WHITESPACE` seguinte. Deve-se notar que `T_COMMENT` nem sempre é seguido de espaço em branco, Ele também pode ser seguido de `T_CLOSE_TAG` ou o fim do arquivo (end-of-file).

- Nomes com agora são representados usando os tokens `T_NAME_QUALIFIED` (`Foo\Bar`), `T_NAME_FULLY_QUALIFIED` (`\Foo\Bar`) e `T_NAME_RELATIVE` (`namespace\Foo\Bar`). `T_NS_SEPARATOR` é usado apenas para separadores de namespace independentes, e só é sintaticamente válido em conjuncão com declarações de uso de grupo.

### XMLReader

XMLReader::open() e XMLReader::XML() agora são métodos estáticos. Eles ainda podem ser chamados como métodos de instância, mas classes herdadas precisam declará-los como estáticos se elas sobrescrevem esses métodos.

### XML-RPC

A extensão XML-RPC foi movida para PECL e não é mais parte da distribuição PHP.

### Zip

`ZipArchive::OPSYS_Z_CPM` foi removida (esse nome era um erro de digitação). Em vez dela, use `ZipArchive::OPSYS_CPM`.

### Zlib

- gzgetss() foi removida.

- zlib.output_compression não é mais desabilitado automaticamente para o `Content-Type: image/*`.

### Pacotes de teste para PHP no Windows

O executor de testes foi renomeado de run-test.php para run-tests.php, para coincidir com seu nome em php-src.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open