Novidades do PHP 7.2
Novidades do PHP 7.2 – No final do ano passado eu escrevi sobre as novidades do php 7.1. Quase um ano depois, é hora de voltar à tona o assunto, mas dessa vez sobre a próxima minor version, a 7.2.
Se você ainda não teve a oportunidade de ler, eu também escrevi sobre a força do PHP e do seu ecosistema e, nesse artigo, eu desconstruo alguns mitos e preconceitos que ainda permeiam a linguagem.
Quando o PHP 7.2 estará disponível para uso em produção?
O cronograma é de que tenhamos a versão final do PHP 7.2 no dia 30 de novembro (Daqui um mês e alguns dias).
Atualmente estamos na Release Candidate 5 (RC5). O caminho a ser percorrido até o lançamento:
Date | Release |
---|---|
Oct 26 2017 | RC 5 |
Nov 7 2017 | PHP 7.2.0 branched |
Nov 9 2017 | RC 6 |
Nov 30 2017 | GA |
O que posso esperar do PHP 7.2?
Essa não será uma versão com uma grande variedade de inclusões e novas features. O foco ficou em melhorar a estabilidade e consistência e também em descontinuar algumas coisas que há tempo estavam no radar da “exclusão”.
Melhorias no core continuam sendo aplicadas e a linguagem segue um rumo para ficar cada vez mais rápida, como pode ser visto nesse estudo:
No teste realizado pelo Sebastian Bergmann (criador do PHPUnit) o PHP 7.2 também foi bem:
O principal destaque, no entanto, refere-se à inclusão da libsodium na standard library do PHP.
#PHP 7.2 will be the first programming language to accept modern cryptography into its standard library.https://t.co/mNDK9zxcw5— Scott Arciszewski (@CiPHPerCoder) February 10, 2017
A libsodium é uma completa toolkit de segurança. Moderna, com boa auditoria e recomendada por grandes nomes da comunidade de especialistas em segurança.
Entre todas as features da libsodium, talvez a que mais toca a grande maioria dos desenvolvedores PHP, refere-se ao algoritmo de hashing de passwords, o Argon2i.
Desde a implementação da API de hashing de password no PHP 5.5 a adoção foi grande, principalmente por parte dos frameworks. No entanto, o algoritmo padrão utilizado por ela é o bcrypt.Copiar
<?php
$hash = password_hash('4&4*Q?_2c*rFPW+jj^KAxnBQ9+Q5X@ep');
Nesse exemplo, o password 4&4*Q?_2c*rFPW+jj^KAxnBQ9+Q5X@ep
será transformado usando o algoritmo bcrypt.
Agora, no PHP 7.2, será possível informar o Argon2i como algoritmo de hashing (no segundo parâmetro da função):Copiar
<?php
$hash = password_hash('4&4*Q?_2c*rFPW+jj^KAxnBQ9+Q5X@ep', PASSWORD_ARGON2I);
Melhorias de consistência
A lista completa das alterações do PHP 7.2 pode ser encontrada no hotsite de RFC’s. Sugiro que você olhe cada uma.
Vou destacar abaixo as que eu considero de maior importância / relevância.
Sobrescrita de métodos abstratos
Esse código nas versões anteriores ao PHP 7.2 gera um erro fatal:
<?php
abstract class A
{
abstract public function bar(\stdClass $x);
}
abstract class B extends A
{
abstract public function bar($x) : \stdClass;
}
O erro que é gerado:Copiar
Fatal error: Can't inherit abstract function A::bar() (previously declared abstract in B)
Até então não era possível sobrescrever métodos abstratos. No PHP 7.2 tornou-se possível.
Previnir que number_format() retorne zero negativo
Essa é mais uma daquelas alterações para dar mais consistência pra linguagem.
Por exemplo, o código abaixo retorna uma string "-0"
:
<?php
echo number_format(-0.01); // "-0" (PHP <= 7.1)
No PHP 7.2 passa a retornar "0"
.
Conversão de chaves numéricas no casting de arrays/objetos
Um problema que ocorre nas versões anteriores à 7.2:
<?php
$arr = [
0 => 1,
1 => 2,
2 => 3,
];
$obj = (object) $arr;
var_dump($obj);
Nessas versões, o retorno é:
object(stdClass)#1 (3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
Veja que é um retorno discrepante. O casting do array para objeto faz com que os índices numéricos se percam.
No PHP 7.2 o retorno será o esperado:Copiar
object(stdClass)#1 (3) {
["0"]=> int(1)
["1"]=> int(2)
["2"]=> int(3)
}
Outras variantes do mesmo problema você encontra na RFC dessa alteração.
Emitir warning se um valor null for passado para get_class()
Um valor nulo pode levar a get_class()
a produzir resultados inesperados.
Por exemplo:
<?php
class MyRepo
{
public function find($id)
{
return null;
}
}
class Foo
{
function bar($repository)
{
$result = $repository->find(100);
echo get_class($result);
}
}
$foo = new Foo();
$foo->bar(new MyRepo);
Espera-se que a função bar()
imprima o nome da classe do objeto contido em $result
. Entretanto, $result
sendo nulo, é retornado o nome da classe do objeto no contexto em que get_class()
foi chamada. O exemplo acima retorna Foo
nas versões inferiores ao PHP 7.2
No PHP 7.2 esse exemplo retorna um warning:
Warning: get_class() expects parameter 1 to be object, null given
Contar apenas coisas contáveis
Chamar a função count()
em valores escalares ou objetos que não implementem a interface Countable
resulta em 1. O que é um resultado não lógico e é preciso ter cuidado com o que se faz com ele.
Um exemplo:Copiar
<?php
$nome = "cafecodificado";
echo count($nome);
No PHP 7.2 o retorno também é 1, no entanto, um warning é gerado:Copiar
Warning: count(): Parameter must be an array or an object that implements Countable
Parameter Type Widening
Nas versões inferiores ao PHP 7.2 os parâmetros de um método estendido precisam ser compatíveis com os da classe pai. Eles precisam ser fiéis à assinatura (consequentemente também aos tipos explicitamente solicitados).
Por exemplo:Copiar
<?php
class ArrayClass
{
public function foo(array $foo)
{
// TODO
}
}
class EverythingClass extends ArrayClass
{
public function foo($foo)
{
// TODO
}
}
O método foo()
da classe EverythingClass
nas versões anteriores gera um warning:Copiar
Warning: Declaration of EverythingClass::foo($foo) should be compatible with ArrayClass::foo(array $foo)
Ele pede que seja declarado de acordo com a classe pai:Copiar
class EverythingClass extends ArrayClass
{
public function foo(array $foo)
{
// TODO
}
}
No PHP 7.2 esse warning não mais existe. Fica flexível para quem estende se vai exigir aquele tipo declarado no parâmetro ou não. Isso favorece a aplicação de contravariância e covariância.
Melhoria no suporte ao uso de vírgulas
Um padrão de estilo de código muito usado em PHP é usar uma vírgula no último item de um array, assim:
$array = [
'foo',
'bar',
];
Muitos desenvolvedores são a favor da extensão desse suporte (da vírgula) para outros contextos, mas existe uma certa resistência.
O que conseguiram na versão 7.2 foi trazer isso para a instrução use:Copiar
use Test {
Foo,
Bar,
Baz,
};
$foo = new Foo();
$bar = new Bar();
$baz = new Baz();
Nas versões anteriores ao PHP 7.2 essa vírgula na class “Baz” gera um erro fatal.
Object Type Hinting
Essa foi uma adição muito aguardada por aqueles que passaram a usar Scalar Type Declarations, adicionado na versão 7 do PHP.
Que basicamente é uma forma do desenvolvedor conseguir exigir um tipo escalar no parâmetro de uma função e de também informar qual será o tipo do retorno dela.
No PHP 7.2 adicionaram o tipo genérico object
. Quando utilizado no parâmetro de um método ou função, indica que um objeto deve ser passado. Não importa de que tipo. Precisa ser um objeto.
Exemplo:
<?php
class Foo
{
// TODO
}
function bar(object $object) {
// TODO
}
bar(new Foo);
Descontinuações
Os seguintes recursos foram descontinuados:
__autoload
(prefira usarspl_autoload_register
)$php_errormsg
(prefira usarerror_get_last()
)create_function()
mbstring.func_overload
(unset)
castparse_str()
sem um segundo argumentogmp_random()
(prefira usargmp_random_bits()
egmp_random_rage()
)each()
assert()
com uma string no argumento- O argumento
$errcontext
deset_error_handler()
foi descontinuado.
A descrição e a proposta pra cada uma desses itens você pode ver na https://wiki.php.net/rfc/deprecations_php_7_2 que foi criada pra esse objetivo.
Concluindo
O PHP 7 segue sua jornada, enquanto o suporte ao PHP5 está próximo de ser encerrado por completo.
Ainda não migrou o seu projeto para PHP 7? Essa é a hora. Todos os frameworks modernos já o suportam com maestria em suas últimas versões.