Principais mudanças e melhorias que ocorreram no PHP 7
O PHP sofreu uma grande mudança recentemente com a nova atualização do PHP 5.6 para o PHP 7. Com isso tivemos novos recursos, melhorias e , ganhos significativos em performance se comparado a versões anteriores.
- Breve História por trás do PHP 7
- Desempenho, duas vezes mais rápido
- Novos Recursos
- Diferenças entre os PHP 7 e PHP 5.6
- Porque usar o PHP 7?
Breve História por trás do PHP 7
Muito antes do PHP 7 ser lançado, houve bastante discussão na comunidade sobre uma nova atualização do PHP que seria a versão 6. No entanto o PHP 6 foi uma tentativa de atualizar a versão da linguagem e teve seu lançamento na metade de 2010 mas infelizmente não conseguiu andar.
O que deu errado?
Um dos objetivos do PHP 6 era a adição ao suporte nativo para Unicode. Isso representou uma grande mudança e muitos novos recursos deixaram de ser implementados na versão 5.x do PHP porquê o suporte a Unicode deveria ser adicionado primeiro.
Então desde o começo, muito coisa deu errado tais como a decisão logo no início (2005) de usar internamente UTF-16, o que também teve impacto negativo na performance da linguagem, a adoção generalizada de UTF-8 que ajudou em muitos problemas internos mas deixou os objetivos da atualização irrelevantes, desenvolvedores cadas vez mais menos interessados no projeto.
E entre os anos 2009/2010 ficou notório que o projeto PHP 6 nunca iria acontecer.
Desempenho duas vezes mais rápido
Uma das atualizações mais empolgantes do PHP 7 está no ganho significativo de performance da nova versão que chega o dobro da versão anterior PHP 5.x. Isso se deve a reescrita total da Zend Engine e a notável otimização no consumo de memória.
Estas são as melhorias que tivemos:
- Melhoria na performance: Duas vezes mais rápido do que o PHP 5.6
- Significativa redução no uso de memória
- Abstract Syntax Tree
- Suporte Consistente 64-bit
- Melhoria no lançamento de Exception’s hierárquicas
- Muitos erros fatais foram convertidos para Exception’s
- Gerador de números aleatórios mais seguro
- Antigas e Não suportadas Extensões SAPIS removidas
- The null coalescing operator (??)
- Return e Scalar Type Declarations
- Anonymous Classes
Novos Recursos
Declarações de tipos escalares
Tipos de dados escalares em parametros de funções podem ser forçados tais como strings, inteiros (int), números com ponto flutuante (float) e booleanos (bool). Os outros tipos que já existiam no PHP 5 foram incrementados: class names, interfaces, array and callable.
class C {} class D extends C {}; // This doesn't extend C. class E {} function f(C $c) { echo get_class($c)."\n"; } f(new C); f(new D); f(new E);
O exemplo acima irá imprimir
C D Fatal error: Uncaught TypeError: Argument 1 passed to f() must be an instance of C, instance of E given, called in – on line 14 and defined in -:8 Stack trace: #0 -(14): f(Object(E)) #1 {main} thrown in – on line 8
Por padrão o php irá realizar o parse de um tipo errado para o tipo esperado pela função. Por exemplo, uma função que esteja passando um inteiro para um parâmetro que deveria ser uma string a variável será uma string.
É possível também habilitar o modo rigoroso (strict mode) onde somente será aceita a variável do exato tipo que foi declarada na função. Para habilitar basta usar a declaração declare com o argumento strict_types assim: declare(strict_types=1);
declare(strict_types=1); function sum(int $a, int $b) { return $a + $b; } var_dump(sum(1, 2)); var_dump(sum(1.5, 2.5));
Declaração do tipo de retorno
Bem parecido com as declarações de tipos escalares a declaração do tipo de retorno especifica qual tipo de dado uma dada função deve retornar. Os tipos suportados são os mesmos da declaração de tipos.
function arraysSum(array ...$arrays): array { return array_map(function(array $array): int { return array_sum($array); }, $arrays); } print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
Null coalescing operator (??)
Este recurso surgiu com a necessidade de se usar o operador ternário junto com o a função isset(). Ele retorna o primeiro operando caso ele exista e seja diferente de nulo (NULL), do contrário retornará o segundo operando.
// Obtém o valor de $_GET['user'] e retorna 'nobody' // se ele não existir. $username = $_GET['user'] ?? 'nobody'; // Isto equivale a: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; // A coalescência pode ser encadeada: isto irá retornar o primeiro // valor definido entre $_GET['user'], $_POST['user'] e // 'nobody'. $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
Spaceship operator
Este novo operador é usado para comparar duas expressões. Retorna -1, 0, 1 quando $a for respectivamente menor que, igual ou maior que $b.
// Inteiros echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 // Números de ponto flutuante echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1 // Strings echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1
Arrays como Constants
Constantes do tipo array agora podem ser definidas com a função define(). No PHP 5.6 elas só poderiam ser definidas com const.
define('ANIMALS', [ 'dog', 'cat', 'bird' ]); echo ANIMALS[1]; // imprime "cat"
Classes anônimas
O suporte a classes anônimas foi adicionado utilizando o operador new class. O principal objetivo de se utilizar classe anônimas é quando desejamos substituir definições de classes completas para objetos descartáveis. Segue um exemplo detalhado:
interface Logger { public function log(string $msg); } class Application { private $logger; public function getLogger(): Logger { return $this->logger; } public function setLogger(Logger $logger) { $this->logger = $logger; } } $app = new Application; $app->setLogger(new class implements Logger { public function log(string $msg) { echo $msg; } }); var_dump($app->getLogger());
Porém tome muito cuidado ao usar este recurso, pois o seu mal uso causará dificuldades em ler e entender o seu código.
IntlChar
A classe IntlChar é responsável por disponibilizar alguns métodos de acesso a informações sobre caracteres Unicode e recebeu atualizações de funcionalidades adicionais, por exemplo:
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffff echo IntlChar::charName('@'); // COMMERCIAL AT var_dump(IntlChar::ispunct('!')); // bool(true)
Agrupamento de declarações use
Classes, funções e constantes importadas do mesmo namespace, agora podem ser agrupadas em uma única declaração use facilitando a sua leitura.
// Código anterior ao PHP 7 use some\namespace\ClassA; use some\namespace\ClassB; use some\namespace\ClassC as C; use function some\namespace\fn_a; use function some\namespace\fn_b; use function some\namespace\fn_c; use const some\namespace\ConstA; use const some\namespace\ConstB; use const some\namespace\ConstC; // Código do PHP 7+ use some\namespace\{ClassA, ClassB, ClassC as C}; use function some\namespace\{fn_a, fn_b, fn_c}; use const some\namespace\{ConstA, ConstB, ConstC};
Conclusão
Fica claro que o PHP evolui bastante em muitos pontos que antes eram considerados pontos fracos da linguagem. Melhorias na performance, adição de recursos úteis e facilidade de escrita de algumas estruturas facilita muito a vida de quem usa.
Por fim, estes são alguns dos principais recursos que o PHP 7 trouxe. Porém vários outros novos recursos já foram adicionados ao PHP 7.1 e 7.2. Vale informar aqui alguns deles, que são:
- Sintaxe de escape de códigos Unicode
- Closure:call()
- unserialize() filtrado
- IntlChar
- Expectations
- Expressões de retorno nos geradores
- Delegações de geradores
- Nova função intdiv()
- Opções de sessões
- Nova função preg_replace_callback_array()
- Nova funções na lib CSPRNG
Referências:
http://php.net/releases/7_0_0.php
https://wiki.php.net/todo/php60
https://www.phproundtable.com/episode/what-happened-to-php-6
https://imasters.com.br/linguagens/php/o-debate-sem-fim-php-6-versus-php-7