Referência do PHP 7.2
Referência do PHP 7.1
O PHP 7 foi lançado em 3 de dezembro de 2015. Ele vem com uma série de novos recursos, alterações e quebras de compatibilidade com versões anteriores descritas abaixo.
Desempenho
Características
Operador de comparação combinado
Operador de coalescência nulo
Declarações de tipo escalar
Declarações de tipo de retorno
Aulas anônimas
Sintaxe de escape de ponto de código Unicode
Método de call()
unserialize()
Classe IntlChar
Expectativas
Declarações use
de grupo
Expressões de retorno do gerador
Delegação do Gerador
Divisão Inteira com intdiv()
session_start()
Opções
Função preg_replace_callback_array()
Funções CSPRNG
Suporte para constantes de array em define()
Adições de reflexão
Mudanças
Afrouxando restrições de palavras reservadas
Sintaxe de Variável Uniforme
Exceções no motor
Interface lançável
Semântica Inteira
Extensão JSON substituída por JSOND
Falha de ZPP no estouro
Correções no comportamento de foreach()
Mudanças no comportamento de list()
Mudanças na Divisão por Semântica Zero
Correções nos valores de retorno do manipulador de sessão personalizado
Descontinuação de construtores PHP estilo 4
Remoção do aviso date.timezone
Remoção de tags PHP alternativas
Remoção de vários blocos padrão em instruções Switch
Remoção de Redefinição de Parâmetros com Nomes Duplicados
Remoção de APIs de servidores mortos
Remoção de suporte hexadecimal em strings numéricas
Remoção de funcionalidade obsoleta
Reclassificação e remoção de avisos E_STRICT
Descontinuação da opção Salt para password_hash()
Erro em literais octais inválidos
substr()
Alteração do valor de retorno
Perguntas frequentes
O que aconteceu com o PHP 6?
Indiscutivelmente, a maior parte do PHP 7 é o incrível aumento de desempenho que ele fornece aos aplicativos. Isso é resultado da refatoração do Zend Engine para usar estruturas de dados mais compactas e menos alocações/desalocações de heap.
Os ganhos de desempenho em aplicativos do mundo real variam, embora muitos aplicativos pareçam receber um aumento de desempenho de aproximadamente 100% - com menor consumo de memória também!
A base de código refatorada também oferece mais oportunidades para otimizações futuras (como compilação JIT). Portanto, parece que as futuras versões do PHP também continuarão a ver melhorias de desempenho.
Comparações de gráficos de desempenho do PHP 7:
Turbinando a Web com PHP 7
Referências da palestra de Rasmus em Sydney
O operador de comparação combinado (ou operador de nave espacial) é uma notação abreviada para realizar comparações de três vias a partir de dois operandos. Possui um valor de retorno inteiro que pode ser:
um número inteiro positivo (se o operando esquerdo for maior que o operando direito)
0 (se ambos os operandos forem iguais)
um número inteiro negativo (se o operando à direita for maior que o operando à esquerda)
O operador tem a mesma precedência que os operadores de igualdade ( ==
, !=
, ===
, !==
) e tem exatamente o mesmo comportamento que os outros operadores de comparação soltos ( <
, >=
, etc). Também é não associativo como eles, portanto o encadeamento dos operandos (como 1 <=> 2 <=> 3
) não é permitido.
// compara strings lexicallyvar_dump('PHP' <=> 'Node'); // int(1)// compara números por sizevar_dump(123 <=> 456); // int(-1)// compara os elementos correspondentes do array com one-anothervar_dump(['a', 'b'] <=> ['a', 'b']); //int(0)
Os objetos não são comparáveis e, portanto, usá-los como operandos com este operador resultará em um comportamento indefinido.
RFC: Operador de comparação combinado
O operador coalesce nulo (ou operador ternário isset) é uma notação abreviada para realizar verificações isset()
no operador ternário. Isso é algo comum em aplicativos e, portanto, uma nova sintaxe foi introduzida exatamente para esse propósito.
// Código pré PHP 7$route = isset($_GET['route']) ? $_GET['route'] : 'index';// PHP 7+ código$route = $_GET['route'] ?? 'índice';
RFC: Operador de coalescência nulo
As declarações de tipo escalar vêm em dois tipos: coercive (padrão) e strict . Os seguintes tipos de parâmetros agora podem ser aplicados (de forma coercitiva ou estrita): strings ( string
), inteiros ( int
), números de ponto flutuante ( float
) e booleanos ( bool
). Eles aumentam os outros tipos introduzidos nas versões do PHP 5.x: nomes de classes, interfaces, array
e callable
.
// Modo coercitivofunção sumOfInts(int ...$ints) { return array_sum($ints); }var_dump(sumOfInts(2, '3', 4.1)); //int(9)
Para ativar o modo estrito, uma única diretiva declare()
deve ser colocada no topo do arquivo. Isso significa que o rigor da digitação dos escalares é configurado por arquivo. Esta diretiva não afeta apenas as declarações de tipo de parâmetros, mas também o tipo de retorno de uma função (consulte Declarações de tipo de retorno), funções PHP integradas e funções de extensões carregadas.
Se a verificação de tipo falhar, uma exceção TypeError
(consulte Exceções no mecanismo) será lançada. A única leniência presente na digitação estrita é a conversão automática de números inteiros em pontos flutuantes (mas não vice-versa) quando um número inteiro é fornecido em um contexto flutuante.
declarar(strict_types=1);função multiplicar(float $x, float $y) {retorna $x * $y; }função add(int $x, int $y) {retorna $x + $y; }var_dump(multiplicar(2, 3,5)); // float(7)var_dump(add('2', 3)); // Erro fatal: TypeError não capturado: o argumento 1 passado para add() deve ser do tipo inteiro, string fornecida...
Observe que apenas o contexto de invocação se aplica quando a verificação de tipo é executada. Isso significa que a digitação estrita se aplica apenas a chamadas de função/método, e não às definições de função/método. No exemplo acima, as duas funções poderiam ter sido declaradas em um arquivo estrito ou coercitivo, mas desde que sejam chamadas em um arquivo estrito, as regras de digitação estritas serão aplicadas.
Quebras de BC
Classes com nomes int
, string
, float
e bool
agora são proibidas.
RFC: Declarações de tipo escalar
As declarações de tipo de retorno permitem que o tipo de retorno de uma função, método ou encerramento seja especificado. Os seguintes tipos de retorno são suportados: string
, int
, float
, bool
, array
, callable
, self
(somente métodos), parent
(somente métodos), Closure
, o nome de uma classe e o nome de uma interface.
function arraysSoma(array ...$arrays): array{ return array_map(function(array $array): int { return array_sum($array); }, $matrizes); }print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));/* OutputArray( [0] => 6 [1] => 15 [2] => 24)*/
Com relação à subtipagem, a invariância foi escolhida para os tipos de retorno. Isso significa simplesmente que quando um método é substituído em uma classe subtipada ou implementado conforme definido em um contrato, seu tipo de retorno deve corresponder exatamente ao método que ele está (re)implementando.
classe A {}classe B estende A {}classe C {teste de função pública(): A { retornar novo A; } }classe D estende C { // substituindo o método C::test() : Uma função pública test() : B // Erro fatal devido à incompatibilidade de variância { retornar novo B; } }
O método de substituição D::test() : B
causa um E_COMPILE_ERROR
porque a covariância não é permitida. Para que isso funcione, o método D::test()
deve ter um tipo de retorno A
.
classe A {}interface SomeInterface {teste de função pública(): A; }classe B implementa SomeInterface { public function test() : A // tudo bem! {retornar nulo; // Erro fatal: TypeError não capturado: O valor de retorno de B::test() deve ser uma instância de A, nulo retornado... } }
Desta vez, o método implementado faz com que uma exceção TypeError
(consulte Exceções no mecanismo) seja lançada quando executado. Isso ocorre porque null
não é um tipo de retorno válido – apenas uma instância da classe A
pode ser retornada.
RFC: declarações de tipo de retorno
Classes anônimas são úteis quando objetos simples e únicos precisam ser criados.
// Registrador de classe de código pré PHP 7 {log de função pública($msg) { echo $msg; } }$util->setLogger(new Logger());// código PHP 7+$util->setLogger(new class { public function log($msg) { echo $msg; } });
Eles podem passar argumentos para seus construtores, estender outras classes, implementar interfaces e usar características exatamente como uma classe normal pode:
class SomeClass {}interface SomeInterface {}trait SomeTrait {}var_dump(new class(10) estende SomeClass implements SomeInterface { private $num; public function __construct($num) { $this->num = $num; } use SomeTrait; });/** Saída:object(class@anonymous)#1 (1) { ["Código da linha de comando0x104c5b612":"class@anonymous":private]=> int(10)}*/
Aninhar uma classe anônima dentro de outra classe não dá acesso a nenhum método ou propriedade privada ou protegida dessa classe externa. Para usar as propriedades ou métodos protegidos da classe externa, a classe anônima pode estender a classe externa. Para usar as propriedades privadas ou protegidas da classe externa na classe anônima, elas devem ser passadas através do seu construtor:
<?phpclass Externo {privado $prop = 1; protegido $prop2 = 2; função protegida func1() {retorno 3; } função pública func2() { return new class($this->prop) extends Outer { private $prop3; função pública __construct($prop) { $this->prop3 = $prop; } função pública func3() { return $this->prop2 + $this->prop3 + $this->func1(); } }; } }echo (novo Exterior)->func2()->func3(); //6
RFC: aulas anônimas
Isso permite que um codepoint unicode codificado em UTF-8 seja gerado em uma string entre aspas duplas ou em um heredoc. Qualquer ponto de código válido é aceito, sendo os 0
iniciais opcionais.
eco "u{aa}"; // ªecho "u{0000aa}"; // ª (o mesmo que antes, mas com 0s iniciais opcionais)echo "u{9999}"; // 香
RFC: Sintaxe de escape de ponto de código Unicode
O novo método call()
para encerramentos é usado como uma forma abreviada de invocar um encerramento enquanto vincula um escopo de objeto a ele. Isso cria um código mais compacto e de desempenho, eliminando a necessidade de criar um fechamento intermediário antes de invocá-lo.
classe A {private $x = 1;}// Código pré PHP 7$getXCB = function() {return $this->x;};$getX = $getXCB->bindTo(new A, 'A'); // fechamento intermediárioecho $getX(); // 1// PHP 7+ código$getX = function() {return $this->x;};echo $getX->call(new A); //1
RFC: Encerramento::chamada
unserialize()
Este recurso busca fornecer melhor segurança ao desserializar objetos em dados não confiáveis. Ele evita possíveis injeções de código, permitindo que o desenvolvedor coloque na lista de permissões classes que podem ser desserializadas.
// converte todos os objetos em __PHP_Incomplete_Class object$data = unserialize($foo, ["allowed_classes" => false]);// converte todos os objetos em objeto __PHP_Incomplete_Class exceto aqueles de MyClass e MyClass2$data = unserialize($foo, [" permitido_classes" => ["MyClass", "MyClass2"]]);// comportamento padrão (o mesmo que omitir o segundo argumento) que aceita todas as classes$data = unserialize($foo, ["allowed_classes" => true]);
RFC: Unserialize filtrado()
IntlChar
A nova classe IntlChar
procura expor funcionalidades adicionais do ICU. A própria classe define vários métodos estáticos e constantes que podem ser usados para manipular caracteres Unicode.
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffffecho IntlChar::charName('@'); // COMERCIAL ATvar_dump(IntlChar::ispunct('!')); //bool(verdadeiro)
Para usar esta classe, a extensão Intl
deve estar instalada.
Quebras de BC
As classes no namespace global não devem ser chamadas IntlChar
.
RFC: classe IntlChar
As expectativas são um aprimoramento compatível com versões anteriores da função assert()
mais antiga. Eles permitem asserções de custo zero no código de produção e fornecem a capacidade de lançar exceções personalizadas em caso de erro.
O protótipo da função assert()
é o seguinte:
void assert (mixed $expression [, mixed $message]);
Tal como acontece com a API antiga, se $expression
for uma string, ela será avaliada. Se o primeiro argumento for falso, a afirmação falhará. O segundo argumento pode ser uma string simples (fazendo com que um AssertionError seja acionado) ou um objeto de exceção personalizado contendo uma mensagem de erro.
ini_set('assert.exception', 1);class CustomError estende AssertionError {}assert(false, new CustomError('Alguma mensagem de erro'));
Com esse recurso vêm duas configurações do PHP.ini (junto com seus valores padrão):
zend.asserções = 1
assert.exception = 0
zend.assertions tem três valores:
1 = gerar e executar código (modo de desenvolvimento)
0 = gerar código e pular nele em tempo de execução
-1 = não gera nenhum código (custo zero, modo de produção)
assert.exception significa que uma exceção é lançada quando uma asserção falha. Isso está desativado por padrão para permanecer compatível com a antiga função assert()
.
RFC: Expectativas
use
de grupo Isso permite agrupar várias declarações use
de acordo com o namespace pai. Isso busca remover a verbosidade do código ao importar várias classes, funções ou constantes que estão no mesmo namespace.
// Código pré PHP 7use somenamespaceClassA;use somenamespaceClassB;use somenamespaceClassC as C;use function somenamespacefn_a;use function somenamespacefn_b;use function somenamespace fn_c;use const somenamespaceConstA;use const somenamespaceConstB;use const somenamespaceConstC;// PHP 7+ codeuse algumnamespace{ClassA, ClassB, ClassC como C};use a função somenamespace{fn_a, fn_b, fn_c};use const somenamespace{ConstA, ConstB, ConstC};
RFC: Declarações de uso de grupo
Este recurso se baseia na funcionalidade do gerador introduzida no PHP 5.5. Ele permite que uma instrução return
seja usada dentro de um gerador para permitir o retorno de uma expressão final (retorno por referência não é permitido). Este valor pode ser obtido usando o novo método Generator::getReturn()
, que só pode ser usado quando o gerador terminar de produzir valores.
// Sintaxe IIFE agora possível - veja a subseção Sintaxe de Variável Uniforme na seção Mudanças$gen = (function() { yield 1; yield 2; return 3; })();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn(), PHP_EOL;// saída:// 1// 2// 3
Ser capaz de retornar explicitamente um valor final de um gerador é uma capacidade útil de se ter. Isso ocorre porque permite que um valor final seja retornado por um gerador (talvez de alguma forma de computação de co-rotina) que pode ser tratado especificamente pelo código do cliente que executa o gerador. Isso é muito mais simples do que forçar o código do cliente a verificar primeiro se o valor final foi gerado e, em caso afirmativo, tratar esse valor especificamente.
RFC: Expressões de Retorno do Gerador
A delegação do gerador baseia-se na capacidade de retornar expressões dos geradores. Isso é feito usando uma nova sintaxe de yield from <expr>
, onde pode ser qualquer objeto ou array Traversable
. Isso será avançado até não ser mais válido e então a execução continuará no gerador de chamada. Esse recurso permite que as declarações yield
sejam divididas em operações menores, promovendo assim um código mais limpo e com maior capacidade de reutilização.
função geração() {rendimento 1; rendimento 2; retorna o rendimento de gen2(); }função gen2() {rendimento 3; retornar 4; }$gen = gen();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn();// saída // 1 // 2 // 3 // 4
RFC: Delegação do Gerador
intdiv()
A função intdiv()
foi introduzida para lidar com a divisão onde um número inteiro deve ser retornado.
var_dump(intdiv(10, 3)); //int(3)
Quebras de BC
Funções no namespace global não devem ser chamadas intdiv
.
RFC: intdiv()
session_start()
Opções Este recurso permite passar uma série de opções para a função session_start()
. Isso é usado para definir opções do php.ini baseadas em sessão:
session_start(['cache_limiter' => 'privado']); // define a opção session.cache_limiter como privada
Este recurso também introduz uma nova configuração do php.ini ( session.lazy_write
) que é, por padrão, definida como true e significa que os dados da sessão só serão reescritos se forem alterados.
RFC: Introduzir opções session_start()
preg_replace_callback_array()
Esta nova função permite que o código seja escrito de forma mais limpa ao usar a função preg_replace_callback()
. Antes do PHP 7, os retornos de chamada que precisavam ser executados por expressão regular exigiam que a função de retorno de chamada (segundo parâmetro de preg_replace_callback()
) fosse poluída com muitas ramificações (na melhor das hipóteses, um método hacky).
Agora, os retornos de chamada podem ser registrados para cada expressão regular usando uma matriz associativa, onde a chave é uma expressão regular e o valor é um retorno de chamada.
Assinatura da Função:
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexema] pares$input = <<<'end'$a = 3; // variável inicializaçãoend;// Pré PHP 7 codepreg_replace_callback( [ '~$[a-z_][azd_]*~i', '~=~', '~[d]+~', '~;~', '~//.*~' ], função ($match) use (&$tokenStream) { if (strpos($match[0], '$') === 0) { $tokenStream[] = ['T_VARIABLE', $match[0]] ; } elseif (strpos($match[0], '=') === 0) { $tokenStream[] = ['T_ASSIGN', $match[0]]; } elseif (ctype_digit($match[0])) { $tokenStream[] = ['T_NUM', $match[0]]; } elseif (strpos($match[0], ';') === 0) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; } elseif (strpos($match[0], '//') === 0) { $tokenStream[] = ['T_COMMENT', $match[0]]; } }, $input);// PHP 7+ codepreg_replace_callback_array( [ '~$[a-z_][azd_]*~i' => função ($match) use (&$tokenStream) { $tokenStream[] = ['T_VARIABLE', $match[0]]; }, '~=~' => função ($match) use (&$tokenStream) { $tokenStream[] = ['T_ASSIGN', $match[0]]; }, '~[d]+~' => função ($match) use (&$tokenStream) { $tokenStream[] = ['T_NUM', $match[0]]; }, '~;~' => função ($match) use (&$tokenStream) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; }, '~//.*~' => função ($match) use (&$tokenStream) { $tokenStream[] = ['T_COMMENT', $match[0]]; } ], $entrada);
Quebras de BC
As funções no namespace global não devem ser chamadas preg_replace_callback_array
.
RFC: Adicionar função preg_replace_callback_array
Este recurso introduz duas novas funções para gerar inteiros e strings criptograficamente seguros. Eles expõem APIs simples e são independentes de plataforma.
Assinaturas de função:
string random_bytes(int length); int random_int(int min, int max);
Ambas as funções emitirão uma exceção Error
se uma fonte de aleatoriedade suficiente não puder ser encontrada.
Quebras de BC
As funções no namespace global não devem ser chamadas random_int
ou random_bytes
.
RFC: CSPRNG de usuário fácil
define()
A capacidade de definir constantes de array foi introduzida no PHP 5.6 usando a palavra-chave const
. Esta habilidade agora também foi aplicada à função define()
:
define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
RFC: nenhuma RFC disponível
Duas novas classes de reflexão foram introduzidas no PHP 7. A primeira é ReflectionGenerator
, que é usada para introspecção em geradores:
classe ReflectionGenerator { public __construct(Gerador $gen) matriz pública getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) público int getExecutingLine(void) string pública getExecutingFile(void) public ReflectionFunctionAbstract getFunction(void) objeto público getThis(void) Gerador público getExecutingGenerator(void) }
O segundo é ReflectionType
para melhor suportar os recursos de declaração de tipo escalar e de retorno:
classe ReflectionType { public bool permiteNull(void) public bool isBuiltin(void) string pública __toString(void) }
Além disso, dois novos métodos foram introduzidos em ReflectionParameter
:
classe ReflectionParameter { // ... public bool hasType(void) public ReflectionType getType(void) }
Bem como dois novos métodos em ReflectionFunctionAbstract
:
classe ReflectionFunctionAbstract { // ... public bool hasReturnType(void) public ReflectionType getReturnType(void) }
Quebras de BC
As classes no namespace global não devem ser chamadas de ReflectionGenerator
ou ReflectionType
.
RFC: nenhuma RFC disponível
Palavras reservadas globalmente como nomes de propriedades, constantes e métodos dentro de classes, interfaces e características agora são permitidas. Isso reduz a superfície de quebras de BC quando novas palavras-chave são introduzidas e evita restrições de nomenclatura em APIs.
Isto é particularmente útil ao criar DSLs internas com interfaces fluentes:
// 'new', 'private' e 'for' eram anteriormente inutilizáveisProject::new('Nome do projeto')->private()->for('propósito aqui')->with('nome de usuário aqui');
A única limitação é que a palavra-chave class
ainda não pode ser usada como um nome constante, caso contrário entraria em conflito com a sintaxe de resolução de nome de classe ( ClassName::class
).
RFC: Lexer sensível ao contexto
Essa mudança traz uma ortogonalidade muito maior aos operadores de variáveis no PHP. Ele permite uma série de novas combinações de operadores que anteriormente não eram permitidas e, assim, introduz novas maneiras de realizar operações antigas em código conciso.
// aninhamento ::$foo::$bar::$baz // acessa a propriedade $baz da propriedade $foo::$bar // aninhamento ()foo()() // invoca o retorno de foo() // operadores em expressões entre ()(function () {})() // sintaxe IIFE de JS
A capacidade de combinar arbitrariamente operadores de variáveis veio da reversão da semântica de avaliação de variáveis indiretas, propriedades e referências de métodos. O novo comportamento é mais intuitivo e segue sempre uma ordem de avaliação da esquerda para a direita:
// significado antigo // novo significado$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz' ]$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']$foo->$bar['baz']( ) $foo->{$bar['baz']}() ($foo->$bar)['baz']() Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()
Quebras de BC
O código que dependia da ordem de avaliação antiga deve ser reescrito para usar explicitamente essa ordem de avaliação com chaves (veja a coluna do meio acima). Isso tornará o código compatível com PHP 7.x e compatível com PHP 5.x.
RFC: Sintaxe de Variável Uniforme
As exceções no mecanismo convertem muitos erros fatais e recuperáveis em exceções. Isso permite a degradação normal de aplicativos por meio de procedimentos personalizados de tratamento de erros. Isso também significa que os recursos orientados à limpeza, como a cláusula finally
e os destruidores de objetos, serão agora executados. Além disso, ao usar exceções para erros de aplicação, serão produzidos rastreamentos de pilha para informações adicionais de depuração.
função soma(float ...$números): float{ return array_sum($números); }tentar { $total = soma(3, 4, nulo); } catch (TypeError $typeErr) { // trata o erro de tipo aqui}
A nova hierarquia de exceções é a seguinte:
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Consulte a subseção Throwable Interface na seção Changes para obter mais informações sobre essa nova hierarquia de exceções.
Quebras de BC
Manipuladores de erros personalizados usados para tratar (e normalmente ignorar) erros fatais recuperáveis não funcionarão mais, pois agora serão lançadas exceções
Erros de análise que ocorrem no código eval()
ed agora se tornarão exceções, exigindo que sejam agrupados em um bloco try...catch
RFC: Exceções no mecanismo
Esta mudança afeta a hierarquia de exceções do PHP devido à introdução de exceções no mecanismo. Em vez de colocar erros fatais e recuperáveis sob a hierarquia de classes Exception
pré-existente, foi decidido implementar uma nova hierarquia de exceções para evitar que o código PHP 5.x capture essas novas exceções com catch-all ( catch (Exception $e)
) cláusulas.
A nova hierarquia de exceções é a seguinte:
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
A interface Throwable
é implementada pelas hierarquias de classe base Exception
e Error
e define o seguinte contrato:
interface Throwable { final public string getMessage ( void ) final public mixed getCode ( void ) final public string getFile ( void ) final public int getLine ( void ) final public array getTrace ( void ) final public string getTraceAsString ( void ) public string __toString ( void ) }
Throwable
não pode ser implementado por classes definidas pelo usuário - em vez disso, uma classe de exceção personalizada deve estender uma das classes de exceções pré-existentes em PHP.
RFC: Interface que pode ser lançada
A semântica de alguns comportamentos baseados em números inteiros mudou em um esforço para torná-los mais intuitivos e independentes de plataforma. Aqui está uma lista dessas mudanças:
Converter NAN
e INF
para um número inteiro sempre resultará em 0
A mudança bit a bit por um número negativo de bits agora não é permitida (causa um retorno bool(false) e emite um E_WARNING)
Deslocamentos bit a bit à esquerda em um número de bits além da largura de bits de um número inteiro sempre resultarão em 0
Deslocamentos bit a bit para a direita em um número de bits além da largura de bits de um número inteiro sempre resultarão em 0 ou -1 (dependente do sinal)
Quebras de BC
Qualquer confiança na semântica antiga para o que foi dito acima não funcionará mais
RFC: Semântica Inteira
O licenciamento da antiga extensão JSON era considerado não gratuito, causando problemas para muitas distribuições baseadas em Linux. Desde então, a extensão foi substituída por JSOND e vem com alguns ganhos de desempenho e quebras de compatibilidade com versões anteriores.
Quebras de BC
Um número não deve terminar em ponto decimal (ou seja, 34.
deve ser alterado para 34.0
ou apenas 34
)
O expoente e
não deve seguir imediatamente o ponto decimal (ou seja, 3.e3
deve ser alterado para 3.0e3
ou apenas 3e3
)
RFC: Substitua a extensão JSON atual por JSOND
A coerção entre floats e inteiros pode ocorrer quando um float é passado para uma função interna esperando um inteiro. Se o float for muito grande para ser representado como um número inteiro, o valor será truncado silenciosamente (o que pode resultar em perda de magnitude e sinal). Isso pode introduzir bugs difíceis de encontrar. Esta mudança, portanto, busca notificar o desenvolvedor quando uma conversão implícita de um float para um inteiro ocorreu e falhou, retornando null
e emitindo um E_WARNING.
Quebras de BC
O código que antes funcionava silenciosamente agora emitirá um E_WARNING e poderá falhar se o resultado da invocação da função for passado diretamente para outra função (já que null
agora será passado).
RFC: Falha de ZPP no estouro
foreach()
O loop foreach()
do PHP tinha vários casos estranhos. Todos eles foram orientados pela implementação e causaram muitos comportamentos indefinidos e inconsistentes ao iterar entre cópias e referências de um array, ao usar manipuladores de iteradores como current()
e reset()
, ao modificar o array atualmente sendo iterado e assim por diante.
Essa mudança elimina o comportamento indefinido desses casos extremos e torna a semântica mais previsível e intuitiva.
foreach()
por valor em arrays
$array = [1,2,3];$array2 = &$array;foreach($array as $val) { não definido($array[1]); // modifica o array sendo iterado sobre echo "{$val} - ", current($array), PHP_EOL; }// Pré PHP 7 resultado1 - 33 // PHP 7+ resultado1 - 12 - 13 - 1
Quando a semântica por valor é usada, o array que está sendo iterado agora não é modificado no local. current()
também agora tem um comportamento definido, onde sempre começará no início do array.
foreach()
por referência em arrays e objetos e por valor em objetos
$array = [1,2,3];foreach($array as &$val) { echo "{$val} - ", current($array), PHP_EOL; }// Pré PHP 7 resultado1 - 22 - 33 -// PHP 7+ resultado1 - 12 - 13 - 1
A função current()
não é mais afetada pela iteração de foreach()
no array. Além disso, foreach()
aninhados usando semântica por referência funcionam independentemente um do outro agora:
$array = [1,2,3];foreach($array as &$val) { echo $val, PHP_EOL; foreach ($array as &$val2) { não definido($array[1]); eco $val, PHP_EOL; } }// Pré PHP 7 resultado111// PHP 7+ resultado111333
Quebras de BC
Qualquer confiança na semântica antiga (peculiar e não documentada) não funcionará mais.
RFC: Corrija o comportamento "foreach"
list()
A função list()
foi documentada como não suportando strings, porém em alguns casos strings poderiam ter sido usadas:
// desreferenciação do array$str[0] = 'ab';list($a, $b) = $str[0];echo $a; //echo $b; // b// desreferenciação de objeto$obj = new StdClass();$obj->prop = 'ab';list($a, $b) = $obj->prop;echo $a; //echo $b; // b // função returnfunction func() {retornar 'ab'; }lista($a, $b) = func();var_dump($a, $b);echo $a; //echo $b; // b
Isso agora foi alterado, tornando o uso de strings com list()
proibido em todos os casos.
Além disso, list()
vazios agora são um erro fatal, e a ordem de atribuição de variáveis foi alterada para da esquerda para a direita:
$a = [1, 2];list($a, $b) = $a;// ANTIGO: $a = 1, $b = 2// NOVO: $a = 1, $b = null + "Indefinido índice 1"$b = [1, 2];lista($a, $b) = $b;// ANTIGO: $a = null + "Índice indefinido 0", $b = 2// NOVO: $a = 1, $ b = 2
Quebras de BC
Tornar list()
igual a qualquer valor de string não direto não é mais possível. null
agora será o valor da variável $a
e $b
nos exemplos acima
Invocar list()
sem nenhuma variável causará um erro fatal
A dependência da antiga ordem de atribuição da direita para a esquerda não funcionará mais
RFC: Corrigir inconsistência de comportamento de list()
RFC: árvore de sintaxe abstrata
Antes do PHP 7, quando um divisor era 0 para os operadores de divisão (/) ou módulo (%), um E_WARNING seria emitido e false
seria retornado. Isso não fazia sentido para uma operação aritmética retornar um booleano em alguns casos e, portanto, o comportamento foi corrigido no PHP 7.
O novo comportamento faz com que o operador de divisão retorne um ponto flutuante como +INF, -INF ou NAN. O operador de módulo E_WARNING foi removido e (juntamente com a nova função intdiv()
) lançará uma exceção DivisionByZeroError
. Além disso, a função intdiv()
também pode gerar um ArithmeticError
quando argumentos inteiros válidos são fornecidos e causam um resultado incorreto (devido ao estouro de número inteiro).
var_dump(3/0); // float(INF) + E_WARNINGvar_dump(0/0); // float(NAN) + E_WARNINGvar_dump(0%0); //DivisãoByZeroErrorintdiv(PHP_INT_MIN, -1); //Erro Aritmético
Quebras de BC
O operador de divisão não retornará mais false
(que poderia ter sido coagido silenciosamente para 0 em uma operação aritmética)
O operador de módulo agora lançará uma exceção com um divisor 0 em vez de retornar false
RFC: Nenhum RFC disponível
Ao implementar manipuladores de sessão customizados, as funções de predicado do SessionHandlerInterface
que esperam um valor de retorno true
ou false
não se comportaram conforme o esperado. Devido a um erro na implementação anterior, apenas um valor de retorno -1
foi considerado falso - o que significa que mesmo que o booleano false
tenha sido usado para denotar uma falha, ele foi considerado um sucesso:
<?phpclass FileSessionHandler implementa SessionHandlerInterface {privado $savePath; função aberta($savePath, $sessionName) {retornar falso; // sempre falha } função fechar(){retornar verdadeiro;} função ler($id){} função escrever($id, $data){} função destruir($id){} função gc($maxlifetime){} }session_set_save_handler(new FileSessionHandler());session_start(); // não causa erro no código pré-PHP 7
Agora, o procedimento acima falhará com um erro fatal. Ter um valor de retorno -1
também continuará falhando, enquanto 0
e true
continuarão significando sucesso. Qualquer outro valor retornado causará uma falha e emitirá um E_WARNING.
Quebras de BC
Se boolean false
for retornado, ele irá falhar agora
Se algo diferente de booleano, 0
ou -1
for retornado, ele falhará e causará a emissão de um aviso
RFC: correção do tratamento de valores de retorno do manipulador de sessão personalizado
Os construtores do PHP 4 foram preservados no PHP 5 junto com o novo __construct()
. Agora, os construtores do estilo PHP 4 estão sendo descontinuados em favor de ter apenas um único método ( __construct()
) para ser invocado na criação do objeto. Isso ocorre porque as condições para a invocação do construtor no estilo PHP 4 causaram sobrecarga cognitiva adicional para os desenvolvedores, o que também poderia ser confuso para os inexperientes.
Por exemplo, se a classe for definida em um espaço para nome ou se um método __construct()
existia, um construtor de estilo PHP 4 foi reconhecido como um método simples. Se fosse definido acima de um método __construct()
, um aviso E_Strict seria emitido, mas ainda reconhecido como um método simples.
Agora, no Php 7, se a classe não estiver em um espaço para nome e não houver método __construct()
presente, o construtor de estilo PHP 4 será usado como construtor, mas um E_Deprecated será emitido. No Php 8, o construtor de estilo PHP 4 sempre será reconhecido como um método simples e o aviso e_deprecado desaparecerá.
BC quebra
Os manipuladores de erros personalizados podem ser afetados pelo aumento de avisos e_deprecated. Para corrigir isso, basta atualizar o nome do construtor da classe para __construct
.
RFC: Remova os construtores PHP 4
Quando quaisquer funções baseadas em data ou tempo foram invocadas e um fuso horário padrão não foi definido, um aviso foi emitido. A correção era simplesmente definir a date.timezone
INI Configuração para um fuso horário válido, mas isso forçou os usuários a ter um arquivo php.ini e configurá -lo com antecedência. Como esse era o único cenário que teve um aviso anexado a ele e, de qualquer maneira, o Aviso foi removido.
RFC: Remova a data.TimeZone Aviso
As tags php alternativas <%
(e <%=
), %>
, <script language="php">
e </script>
foram removidas agora.
BC quebra
O código que confiava nessas tags alternativas precisa ser atualizado para as tags de abertura e fechamento normais ou curtas. Isso pode ser feito manualmente ou automatizado com este script de portamento.
RFC: Remova tags php alternativas
Anteriormente, era possível especificar várias instruções de bloco default
dentro de uma instrução Switch (onde o último bloco default
foi executado apenas). Essa habilidade (inútil) agora foi removida e causa um erro fatal.
BC quebra
Qualquer código escrito (ou mais provavelmente gerado) que criou instruções de switch com vários blocos default
agora se tornará um erro fatal.
RFC: faça definir vários casos padrão em um erro de sintaxe
Anteriormente, era possível especificar parâmetros com nomes duplicados em uma definição de função. Essa habilidade agora foi removida e causa um erro fatal.
function foo ($ versão, $ versão) {return $ versão; } echo foo (5, 7); // pré-php 7 resulte7 // php 7+ Resultado Fatal Erro: Redefinição do parâmetro $ versão em /definition-of-parameters.php
BC quebra
Os parâmetros da função com nome duplicado agora se tornarão um erro fatal.
Os seguintes SAPIS foram removidos do núcleo (a maioria dos quais foi movida para PECL):
SAPI/AOLSERVER
SAPI/APACHE
SAPI/APACHE_HOOKS
SAPI/APACHE2FILTER
SAPI/CAUDIUM
SAPI/continuidade
SAPI/ISAPI
SAPI/MILTER
SAPI/NSAPI
SAPI/PHTTPD
SAPI/PI3WEB
SAPI/ROXEN
SAPI/THTTPD
SAPI/TUX
SAPI/Webjames
ext/msSQL
ext/mysql
ext/sybase_ct
ext/ereg
RFC: Remoção de mortos ou ainda não portados php7 SAPIS e extensões
Um número hexadecimal pegajoso não é mais reconhecido como numérico.
var_dump (is_numeric ('0x123')); var_dump ('0x123' == '291'); echo '0x123' + '0x123'; // pré -php 7 Resultbool (true) bool (true) 582 // php 7+ ResultBool (falso) bool (false) 0
A razão para essa mudança é promover uma melhor consistência entre o manuseio de números de hexadec pela linguagem. Por exemplo, elencos explícitos não reconhecem números hexadecimais pegajosos:
var_dump ((int) '0x123'); // int (0)
Em vez disso, os números hexadecimais sedentos devem ser validados e convertidos usando a função filter_var()
:
var_dump (filtro_var ('0x123', filter_validate_int, filtro_flag_allow_hex)); // int (291)
BC quebra
Essa mudança afeta a função is_numeric()
e vários operadores, incluindo ==
, +
, -
, *
, /
, %
, **
, ++
e --
RFC: Remova o suporte hexadecimal em strings numéricos
Toda funcionalidade descontinuada foi removida, principalmente:
A extensão MySQL original (ext/mysql)
A extensão Ereg (ext/ereg)
Atribuindo new
por referência
Chamadas escopitas de métodos não estáticos de um $this
contexto (como Foo::bar()
de fora de uma aula, onde bar()
não é um método estático)
BC quebra
Qualquer código que executado com avisos de depreciação no Php 5 não funcionará mais (você foi avisado!)
RFC: Remova a funcionalidade depreciada no Php 7
Os avisos E_Strict sempre foram uma área cinza em seu significado. Essa alteração remove completamente essa categoria de erro e: remove o aviso E_Strict, altera -o para um E_Deprecated se a funcionalidade será removida no futuro, altere -a para uma e_Notice ou a promover para um e_warning.
BC quebra
Como o E_STRITT está na categoria de erro de gravidade mais baixa, qualquer promoção de erros para um e_warning pode quebrar os manipuladores de erro personalizados
RFC: Reclassificar avisos E_STRITT
password_hash()
Com a introdução da nova API de hash de senha no PHP 5.5, muitos começaram a implementá -la e gerar seus próprios sais. Infelizmente, muitos desses sais foram gerados a partir de funções criptograficamente inseguras como mt_rand (), tornando o sal muito mais fraco do que o que seria gerado por padrão. (Sim, um sal é sempre usado quando as senhas de hash com esta nova API!)
RFC: nenhum RFC disponível
Os literais octais inválidos agora causarão um erro de análise, em vez de serem truncados e silenciosamente ignorados.
eco 0678; // Erro de análise: Litetal numérico inválido em ...
BC quebra
Quaisquer literais octais inválidos no código agora causarão erros de análise
RFC: nenhum RFC disponível
substr()
Alterar valor de retorno substr()
agora retornará uma string vazia em vez de false
quando a posição inicial do truncamento for igual ao comprimento da string:
var_dump (substr ('a', 1)); // pré -php 7 resultBool (false) // php 7+ Resulting retring (0) "" "
substr()
ainda pode retornar false
em outros casos, no entanto.
BC quebra
Código que verificou estritamente um valor de retorno bool(false)
pode agora ser semanticamente inválido
RFC: nenhum RFC disponível
O PHP 6 foi a principal versão do PHP que nunca veio à tona. Era para apresentar suporte total ao Unicode no núcleo, mas esse esforço foi ambicioso demais, com muitas complicações surgindo. As razões predominantes pelas quais a versão 6 foi ignorada para esta nova versão principal são as seguintes:
Para evitar confusão . Muitos recursos foram escritos sobre o Php 6 e grande parte da comunidade sabia o que foi apresentado nele. O PHP 7 é um animal completamente diferente, com focos totalmente diferentes (especificamente no desempenho) e conjuntos de recursos totalmente diferentes. Assim, uma versão foi ignorada para evitar qualquer confusão ou conceitos errôneos em torno do que é o PHP 7.
Para deixar cães adormecidos mentirem . O PHP 6 foi visto como uma falha e uma grande quantidade de código PHP 6 ainda permanece no repositório PHP. Portanto, foi visto como melhor passar pela versão 6 e começar de novo na próxima versão principal, versão
RFC: Nome do próximo lançamento do PHP