- PHP 8 finalmente foi lançado
- Compilador JIT
- Named Arguments
- Attributes
- Union Types
- Constructor Property Promotion
- Match Expressions
- NullSafe Operator
- Outras melhorias
- Conclusão
PHP 8 finalmente foi lançado
O PHP 8 finalmente foi lançado, em sua versão estável no dia 26 de maio de 2021, e com ele veio uma série de mudanças e melhorias, confira cada uma delas no decorrer deste post.
Se você não conhece o PHP 7, nós temos um curso na Udemy que vai te ensinar desde o básico até o mais avançado, criando um e-commerce. Conheça no curso Curso Artesão de Software PHP 7 – do Padawan ao Jedi.
Compilador JIT
Sem sombra de dúvidas um dos recursos mais aguardados foi o compilador JIT (Just-IN-Time) nesta versão do PHP 8, que torna a linguagem muito mais performática a nível de processamento.
Na época do desenvolvimento deste recurso o co-autor Zeev Surasky publicou um vídeo com um teste de performance exibindo a diferença de renderização entre o PHP 7 e o PHP 8 com o JIT. Confira o vídeo abaixo:
Segundo a documentação oficial do PHP, eles disseram o seguinte:
PHP 8 apresenta dois motores de compilação JIT. Tracing JIT, o mais promissor dos dois, mostra desempenho cerca de 3 vezes melhor em benchmarks sintéticos e melhoria de 1,5 a 2 vezes em alguns aplicativos específicos de longa execução. O desempenho típico das aplicações está no mesmo nível do PHP 7.4.
Fonte: https://www.php.net/releases/8.0/pt_BR.php
Named Arguments
Resumidamente, Named Arguments permite que você especifique apenas os parâmetros obrigatórios, pulando os opcionais. No exemplo abaixo que podemos passar o argumento para a função nomeada como double_encode, isso permite que os argumentos sejam independentes e auto documentados, portanto facilitando a leitura e entendimento.
// PHP 7 htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false); // PHP 8 htmlspecialchars($string, double_encode: false);
Note outro exemplo onde os argumentos são usados baseando-se apenas nas posições e outro exemplo baseando-se em argumentos nomeados. Veja que a ordem na importa
// Usando os argumentos em suas devidas posições: array_fill(0, 100, 50); // Usando argumentos nomeados: array_fill(start_index: 0, count: 100, value: 50); // Outro exemplo com argumentos nomeados mas em qualquer ordem. array_fill(value: 50, num: 100, start_index: 0);
Attributes
Attributes nos deixam adicionar metadados de maneira estruturada e de fácil leitura pelas máquinas à funções, classes, métodos, parâmetros, propriedades e constantes. E com Reflection API é possível inspecionar attributes em tempo de execução (run-time).
No PHP 7 era utilizado PHPDoc, mas agora, no PHP 8, você pode usar metadados estruturados com a sintaxe nativa do PHP.
// PHP 7 class PostsController { /** * @Route("/api/posts/{id}", methods={"GET"}) */ public function get($id) { /* ... */ } } // PHP 8 class PostsController { #[Route("/api/posts/{id}", methods: ["GET"])] public function get($id) { /* ... */ } }
Union Types
Union types permitem que você passe declarações com multiplos tipos, por exemplo, private int|boolean $type onde $type pode receber tanto int quanto boolean. No PHP 7 era possível apenas documentar em comentário os tipos de dados daquela variável, com Union Type a linguagem verifica o tipo em tempo de execução (run-time).
// PHP 8 class Number { public function __construct( private int|float $number ) {} } new Number('NaN'); // TypeError - NaN não é int ou float.
É possível usar Union Types em declarações de atributos, declaração de parâmetros e em retorno de métodos.
// PHP 8 class Number { private int|float $number; // Union Types // Union Types public function setNumber(int|float $number): void { $this->number = $number; } // Union Types public function getNumber(): int|float { return $this->number; } }
Constructor Property Promotion
Se você já utiliza typescript no seu dia a dia, certamente já tem familiaridade com o Constructor Property Promotion.
Este recurso permite que você escreva menos código uma vez que é possível declarar e instanciar as propriedades de um objeto utilizando apenas o método construtor.
O exemplo abaixo foi feito com PHP 7 e você deve conhecer muito bem, onde são declarados os atributos $x, $y, e $z, estes também são declarados no método construtor e depois passados para seus respectivos atributos. Contudo, note como o código boilerplate fica bem extenso se comparado com a mesma versão escrita com PHP 8.
// PHP 7 class Point { public float $x; public float $y; public float $z; public function __construct( float $x = 0.0, float $y = 0.0, float $z = 0.0 ) { $this->x = $x; $this->y = $y; $this->z = $z; } }
Repare que precisamos apenas de 7 linhas de código para produzir a mesma classe Point utilizando Constructor Property Promotion.
Pra quem ainda não entendeu nós declaramos os atributos da classe e os atribuimos apenas no constructor com a palavra reservada public.
// PHP 8 class Point { public function __construct( public float $x = 0.0, public float $y = 0.0, public float $z = 0.0, ) {} } $a = new Point(1, 2, 3); echo $a->x; // Ouput: 1 echo $a->y; // Ouput: 2 echo $a->z; // Ouput: 3
Match Expressions
De maneira bem resumida match expressions é uma nova estrutura muito parecida com o switch, no entanto, como o nome diz Match Expressions é uma expressão, isso significa que pode o seu resultado pode ser retornado ou armazenado em variáveis.
Match Expressions suportam apenas linhas simples e não precisa de break.
Match Expressions fazem comparação restritas, isso quer dizer além de comparar o valor/conteúdo da variável, também faz a comparação pelo tipo.
// PHP 7 switch (8.0) { case '8.0': $result = "Oh no!"; break; case 8.0: $result = "This is what I expected"; break; } echo $result; //> Oh no! // PHP 8 echo match (8.0) { '8.0' => "Oh no!", 8.0 => "This is what I expected", }; //> This is what I expected
NullSafe Operator
Eu particularmente amei esse recurso novo NullSafe Operator, isso porque nos permite escrever bem menos código para verificações que são necessárias mas que agora o PHP pode tomar conta, isso só mostra o quanto a linguagem evoluiu e está longe de morrer como muitos desenvolvedores ainda dizem por ai.
Por outro lado, no PHP 7 precisamos realizar várias verificações afim de garantir que objetos não venha vazios e evitar o temido erro: Error: Call to a member function getName() on null.
// PHP 7 $country = null; if ($session !== null) { $user = $session->user; if ($user !== null) { $address = $user->getAddress(); if ($address !== null) { $country = $address->country; } } }
No exemplo acima, precisamos criar vários encadeamentos para garantir o sucesso da rotina. Mas veja que o NullSafe Operator faz isso de maneira bem simples e com apenas uma linha:
// PHP 8 $country = $session?->user?->getAddress()?->country;
Outras Melhorias
Saner string to number comparisons
Consistent type errors for internal functions
Type system and error handling improvements
Conclusão
Em resumo, o PHP 8 trouxe, sem sombra de dúvidas, melhorias na performance com JIT, novos recursos na estrutura e codificação da linguagem, no entanto, devemos deixar claro que atualizações futuras sempre surgem para corrigir bugs da nova versão, embora esta seja uma versão já estável.
Você já usa o PHP 8 no seu ambiente de trabalho? Gostou das melhorias que aconteceram nessa versão do PHP 8? Comente abaixo o que achou dessas melhorias e para saber mais sobre o assunto consulte a documentação oficial do PHP.