PHPerKaigi 2024

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

Lançamento de exceção ao passar menos argumentos do que uma função espera

Anterioremente, um alerta seria emitido ao chamar funções definidas pelo usuário com parâmetros insuficientes. Agora, este alerta foi promovido a uma exceção da classe Error. Esta alteração aplica-se somente a funções definidas pelo usuário, e não a funções internas. Por exemplo:

<?php
function test($param){}
test();

O exemplo acima produzirá algo semelhante a:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Proibição de chamadas dinâmicas de funções de introspecção de escopo

Chamadas dinâmicas para certas funções estão proibidas (na forma de $func() ou array_map('extract', ...), etc). Estas funções inspecionam ou modificam outro escopo, e apresentam comportamento ambíguo e não confiável. Estas funções são as seguintes:

<?php
(function () {
$func = 'func_num_args';
$func();
})();

O exemplo acima produzirá:

Warning: Cannot call func_num_args() dynamically in %s on line %d

Nomes inválidos de class, interface e trait

Os nomes a seguir não podem ser usados para dar nome a classes, interfaces ou traits:

Conversão de string numérica agora respeita notação científica

Operacões de números inteiros e conversões de strings numéricas agora respeitam a notação científica. Isto também inclui a operação de conversão (int), e as seguintes funções: intval() (onde a base é 10), settype(), decbin(), decoct() e dechex().

Correções ao algoritmo da função mt_rand()

mt_rand() agora usa por padrão a versão fixa do algoritmo Mersenne Twister. Se exsite dependência de uma saída determinística de mt_rand(), MT_RAND_PHP pode ser usada como segundo parâmetro opcional para que mt_srand() preserve a implementação antiga (incorreta).

rand() aliased to mt_rand() and srand() aliased to mt_srand()

rand() e srand() agora são apelidos para mt_rand() e mt_srand(), respectivamente. Isto significa que a saída das funções a seguir foi alterada: rand(), shuffle(), str_shuffle() e array_rand().

Não permitir o caractere de controle 'delete' ASCII em identificadores

O caractere de controle 'delete' ASCII (0x7F) não pode mais ser usado em identificadores que não estejam entre aspas.

Alterações em error_log com o valor syslog

Se a configuração ini error_log for definida para syslog, os níveis de erro do PHP são mapeados para os níveis de erro dos registros do sistema. Isto traz uma diferenciação mais fina nos registros de erros ao contrário da abordagem anterior onde todos os erros eram registrados somente com o nível de erro de aviso.

Destruidores não são mais chamados em objetos incompletos

Destruidores agora não são mais chamados para objetos que lançam uma exceção durante a execução do seu construtor. Em versões anteriores, este comportamento dependia se o objeto era referenciado fora do construtor (ex.: por um rastreamento de exceção).

call_user_func() lidando com argumentos por referência

call_user_func() agora sempre irá gerar um alerta em chamadas a funções que esperam referências como argumentos. Anteriormente isto dependia se a chamada era totalmente qualificada.

Adicionalmente, call_user_func() e call_user_func_array() não mais irão abortar a chamada à função neste caso. O alerta de "referência esperada" será emitido, mas a chamada irá proceder normalmente.

O operador de índice vazio não é mais suportado para strings

Aplicar o operador de índice vazio para uma string (ex.: $str[] = $x) lança um erro fatal ao invés de converter a string silenciosamente para um array.

Atribuição via acesso ao índice de string em uma string vazia

Modificação de string por caractere em uma string vazia agora funciona como para strings não vazias, isto é, escrever em um deslocamento fora dos limites preenche a string com espaços à esquerda, onde tipos não inteiros são convertidos para inteiros, e apenas o primeiro caractere da string atribuída é usado. Anteriormente, strings vazias eram silenciosamente tratadas como um array vazio.

<?php
$a
= '';
$a[10] = 'foo';
var_dump($a);
?>

Saída do exemplo acima no PHP 7.0:

array(1) {
  [10]=>
  string(3) "foo"
}

Saída do exemplo acima no PHP 7.1:

string(11) "          f"

Diretivas ini removidas

As seguintes diretivas ini foram removidas:

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

Alterado o ordenamento de array quando elementos são criados automaticamente durante atribuições por referência

A ordem dos elementos em um array foi alterada quando esses elementos tiverem sido criados automaticamente através de uma atribuição por referência. Por exemplo:

<?php
$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Saída do exemplo acima no PHP 7.0:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

Saída do exemplo acima no PHP 7.1:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Ordenação de elementos iguais

O algoritmo interno de ordenação foi melhorado, o que pode resultar em uma ordem diferente de elementos, que se comparam como iguais.

Nota:

Não deve-se confiar na ordem dos elementos que se comparam como iguais; ela pode mudar a qualquer momento.

Mensagem de erros do tipo E_RECOVERABLE

A mensagem de erro para o tipo E_RECOVERABLE foi alterada de "Catchable fatal error" (erro fatal capturável) para "Recoverable fatal error" (erro fatal recuperável).

Parâmetro $options da função unserialize()

O elemento allowed_classes do parâmetro $options da função unserialize() agora é estritamente tipada, isto é, se algo além de um array ou um bool for fornecido, unserialize() retorna false e emite um E_WARNING.

Construtor DateTime incorpora microssegundos

DateTime e DateTimeImmutable agora incorportam adequadamente microssegundos quando construídos com o horário atual, tanto explicitamente quanto com uma string relativa (ex.: "first day of next month"). Isto significa que as comparações nativas de duas novas instâncias criadas agora irão muito provavelmente retornar false ao invés de true:

<?php
new DateTime() == new DateTime();
?>

Conversões de erros fatais para exceções Error

Na extensão Date, dados de serialização inválidos para as classes DateTime ou DatePeriod, ou falha de inicialização de fuso horário a partir de dados serializados, agora irão lançar uma exceção Error pelos métodos __wakeup() ou __set_state(), ao invés de resultar em um erro fatal.

Na extensão DBA, funções de modificação de dados (como dba_insert()) agora irão lançar uma exceção Error ao invés de disparar um erro fatal capturável se a chave não contiver exatamente dois elementos.

Na extensão DOM, esquema inválido ou contextos de validação RelaxNG agora irão lançar uma exceção Error ao invés de resultar em um erro fatal. Da mesma forma, a tentativa de registrar uma classe de nó que não estende a classe base apropriada, ou a tentativa de ler uma propriedade inválida ou de escrever em um propriedade somente-leitura, irão também lançar uma exceção Error.

Na extensão IMAP, endereços de e-mail maiores que 16385 bytes irão lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão Intl, a falha ao chamar o construtor pai em uma classe que estende Collator antes de chamar os métodos da classe pai irão lançar uma exceção Error ao invés de resultar em um erro fatal recuperável. Além disso, clonar um objeto Transliterator agora irá lançar uma exceção Error na falha ao clonar o transliterador interno ao invés de resultar em um erro fatal.

Na extesão LDAP, fornecer um tipo de modificação desconhecido a ldap_batch_modify() agora irá lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão mbstring, as funções mb_ereg() e mb_eregi() agora irão lançar uma exceção ParseError se uma expressão PHP inválida for fornecida e a opção 'e' for usada.

Na extensão Mcrypt, as funções mcrypt_encrypt() e mcrypt_decrypt() agora irão lançar uma exceção Error ao invés de resultar em um erro fatal se mcrypt não puder ser inicializada.

Na extensão mysqli, a tentativa de se ler uma propriedade inválida ou de escrever em uma propriedade somente-leitura irá agora lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão Reflection, falha em receber um objeto de reflexão ou receber uma propriedade de objeto agora irá lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão Session, manipuladores de sessão customizados que não retornem strings para IDs de sessão agora irão lançar uma exceção Error ao invés de resultar em um erro fatal quando uma função que deveria gerar um ID de sessão for chamada.

Na extensão SimpleXML, criar um atributo sem nome ou duplicado irá agora lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão SPL, tentar clonar um objeto SplDirectory object agora irá lançar uma exceção Error ao invés de resultar em um erro fatal. Da mesma forma, chamar ArrayIterator::append() ao iterar sobre um objeto também irá lançar uma exceção Error.

Na extensão standard, a função assert(), quando alimentada por um argumento string como seu primeiro parâmetro, agora irá lançar uma exceção ParseError ao invés de resultar em um erro fatal recuperável se o código PHP for inválido. Da mesma forma, chamar forward_static_call() for de um escopo de classe agora irá lançar uma exceção Error.

Na extensão Tidy, criar um tidyNode manualmente agora irá lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão WDDX, uma referência circular durante seralização agora irá lançar uma exceção Error ao invés de resultar em um erro fatal.

Na extensão XML-RPC, uma referência circular durante seralização agora irá lançar uma instância da exceção Error ao invés de resultar em um erro fatal.

Na extensão Zip, o método ZipArchive::addGlob() agora irá lançar uma exceção Error ao invés de resultar em um erro fatal se o suporte a glob não estiver disponível.

Variáveis ​​vinculadas lexicamente não podem reutilizar nomes

Variáveis vinculadas a uma função anônima através do construtor de linguagem use não podem usar o mesmo nome de nenhuma das variáveis superglobals, $this, ou de qualquer parâmetro. Por exemplo, todas estas definições de funções irão resultar em um erro fatal:

<?php
$f
= function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

Alteração no tipo do parâmetro de long2ip()

long2ip() agora espera um int ao invés de uma string.

Codificação e decodificação JSON

A configuração ini serialize_precision agora controla a precisão de serialização ao codificar valores do tipo float.

Decodificar uma chave vazia agora resulta em um nome de propriedade vazio, ao invés de _empty_ como nome de propriedade.

<?php
var_dump
(json_decode(json_encode(['' => 1])));

O exemplo acima produzirá algo semelhante a:

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

A fornecer a opção JSON_UNESCAPED_UNICODE para json_encode(), as sequências U+2028 e U+2029 agora são escapadas.

Alteração na semântica de parâmetros de mb_ereg() e mb_eregi()

O terceiro parâmetro das funções mb_ereg() e mb_eregi() (regs) agora será definido para um array vazio se nada tiver sido correspondido. Anteriormente, o parâmetro não teria sido modificado.

Fim do suporte ao fluxo sslv2

O fluxo sslv2 agora foi removido do OpenSSL.

Proibição de "return;" para retornos tipados já em tempo de compilação

Instruções de retorno sem nenhum argumento em funções que declaram um tipo para o retorno agora disparam um erro do tipo E_COMPILE_ERROR (a menos que o tipo do retorno seja declarado como void), mesmo que a instrução de retorno nunca seja alcançada.

add a note

User Contributed Notes 5 notes

up
45
love at sickpeople dot se
7 years ago
For anyone migrating from 5.x to 7.1:

About "Array ordering when elements are automatically created during by reference assignments has changed" on this page

(http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.array-order)

The behaviour of 7.1 is THE SAME as of PHP 5. It is only 7.0 that differs.

See https://3v4l.org/frbUc

<?php

$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
up
35
kees at twekaers dot net
6 years ago
The backwards incompatible change 'The empty index operator is not supported for strings anymore' has a lot more implications than just a fatal error on the following code

<?php
$a
= "";
$a[] = "hello world";
var_dump($a);
?>

This will give a fatal error in 7.1 but will work as expected in 7.0 or below and give you: (no notice, no warning)

array(1) {
[0]=>
string(11) "hello world"
}

However, the following is also changed:

<?php
$a
= "";
$a[0] = "hello world";
var_dump($a);
// 7.1: string(1) "h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

$a = "";
$a[5] = "hello world";
var_dump($a);
// 7.1: string(6) " h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

?>
up
17
m dot r dot sopacua at gmail dot com
7 years ago
"OMFG! Why was session.hash_function removed?!? Dude!"

https://wiki.php.net/rfc/session-id-without-hashing

There. Saved ya a search.
up
1
mikem at gmail dot com
6 years ago
ArgumentCountError - this modification is the main reason to avoid this version on older projects.
up
1
david at artefactual dot com
4 years ago
Regarding the ArgumentCountError, PHP 7.1+ does still support user functions with a variable number of arguments, using the "func(...$args) {}" syntax, see: https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list
To Top