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.
Curso Amazon Web Services (AWS) - S3 - Fundamentos
Conhecer o cursoQuando 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.
<?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):
<?php
$hash = password_hash('4&4*Q?_2c*rFPW+jj^KAxnBQ9+Q5X@ep', PASSWORD_ARGON2I);
Uma documentação completa da libsodium você encontra aqui.
Dica de leitura: Checklist de segurança para autenticação
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:
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.
Teste você mesmo: https://3v4l.org/hCYKo
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"
.
Teste você mesmo: https://3v4l.org/HFDZk
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:
object(stdClass)#1 (3) {
["0"]=> int(1)
["1"]=> int(2)
["2"]=> int(3)
}
Teste você mesmo: https://3v4l.org/4V2Ha
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
Teste você mesmo: https://3v4l.org/IA9QJ
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:
<?php
$nome = "TreinaWeb";
echo count($nome);
No PHP 7.2 o retorno também é 1, no entanto, um warning é gerado:
Warning: count(): Parameter must be an array or an object that implements Countable
Teste você mesmo: https://3v4l.org/c2LTT
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:
<?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:
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:
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.
Teste você mesmo: https://3v4l.org/J9JXR
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:
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);
Teste você mesmo: https://3v4l.org/7qhb3
Curso Laravel - Eloquent ORM
Conhecer o cursoDescontinuações
Os seguintes recursos foram descontinuados:
-
__autoload
(prefira usarspl_autoload_register
) -
$php_errormsg
(prefira usarerror_get_last()
) -
create_function()
-
mbstring.func_overload
-
(unset)
cast -
parse_str()
sem um segundo argumento -
gmp_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.
Foi um prazer ter a sua companhia e até o final de 2018, quando estaremos aqui, novamente, falando sobre a futura nova versão do PHP.
Um abraço!