sábado, 11 de novembro de 2017

Introdução ao PHP 7 - O que há de novo e o que se foi

Um dos eventos mais emocionantes em 2015 no mundo do PHP foi o lançamento do PHP 7, 10 anos a partir do lançamento da última versão principal, o PHP 5. Com um grande passo em frente, o PHP 7 apresenta muitos novos recursos e atualizações de desempenho.

No entanto, ele também remove a funcionalidade antiga e obsoleta, que introduz algumas quebras de compatibilidade, dificultando a migração de aplicativos mais antigos para a nova versão. Este guia deve servir como um passeio rápido sobre o que esperar se você planeja mover suas aplicações existentes, ou criar novas, em cima do PHP 7.

Mas espere, para onde foi o PHP 6?

Se você não trabalhou com PHP ultimamente, você pode se perguntar o que aconteceu com o PHP 6, por que o salto do PHP 5 para o PHP 7? Bem, para ser breve, o PHP 6 foi uma falha. A principal característica da versão 6 foi o suporte nativo para caracteres Unicode, pois o PHP é usado principalmente no desenvolvimento web e a web precisa do Unicode, então o movimento para trazer Unicode para PHP fazia sentido.

A idéia era oferecer suporte completo para o Unicode ao próprio núcleo. Isso teria trazido capacidades extensas para o idioma, desde a capacidade de usar emojis tolos como nomes de funções e variáveis, até uma poderosa funcionalidade de string internacional. Por exemplo, quando outro idioma usa maiúsculas e minúsculas de forma diferente do inglês, ou quando um nome em caracteres chineses precisa ser convertido em inglês.


PHP 6 era ambicioso, porém sem valor. Desta forma surgiu o PHP 7, ignorando a versão 6 no processo.

Infelizmente esse plano ambicioso revelou-se um problema maior do que o esperado. Grande parte da base do código teve que ser alterada para suportar o Unicode para ambas as extensões principais e importantes, o que se mostrou tedioso e complicado. Isso desacelerou o desenvolvimento de outros recursos no idioma, frustrando muitos desenvolvedores do PHP no processo. Ocorreram obstáculos adicionais, o que resultou em menos interesse em desenvolver um suporte Unicode nativo, levando finalmente o projeto a ser abandonado.

Uma vez que os recursos, como livros e artigos, foram escritos para o PHP 6 e seu suporte Unicode, a nova versão seria renomeada PHP 7 para evitar confusão.

De qualquer forma, deixando o passado triste para trás, vamos ver o que o PHP 7 traz para a festa.

Batalha de Desempenho, PHP 7 vs. PHP 5

Como praticamente todas as atualizações, esperam-se pequenas atualizações de desempenho. No entanto, desta vez o PHP traz uma melhoria significativa em relação às versões anteriores, tornando o desempenho puro um dos recursos mais atraentes do PHP 7. Isso vem como parte do projeto "PHPNG", que aborda o core do próprio mecanismo Zend.

Ao refatorar estruturas internas de dados e adicionar uma etapa intermediária para compilação de código na forma de uma Árvore de sintaxe abstrata (AST), o resultado é um desempenho superior e uma alocação de memória mais eficiente. Os próprios números parecem muito promissores; os benchmarks feitos em aplicativos do mundo real mostram que o PHP 7 é duas vezes mais rápido do que o PHP 5.6 em média e resulta em 50 por cento menos consumo de memória durante os pedidos, tornando o PHP 7 um rival forte para o compilador JH HHVM do Facebook. Dê uma olhada nesta infografia do Zend que descreve o desempenho de alguns CMS e Frameworks comuns.


O PHP 7 parece familiar, mas está atento ao desempenho. O refinado Zend Engine e os ganhos de desempenho resultantes fazem uma enorme diferença.

A diminuição do consumo de memória também permite que as máquinas menores atendam melhor os pedidos, além da oportunidade de construir serviços micro em torno do PHP. As mudanças internas, em particular a implementação AST, também abre possibilidades para otimizações futuras que poderiam impulsionar o desempenho ainda mais. Uma nova implementação interna de um compilador JIT está sendo considerada para futuras versões.

PHP 7 Syntactic Sugar

O PHP 7 vem com novos recursos de sintaxe. Embora não estenda os recursos do próprio idioma, eles fornecem uma maneira melhor ou mais fácil de tornar seu código mais agradável para escrever e agradar aos olhos.

Declarações de importação de grupo

Agora podemos agrupar declarações de importação para classes provenientes do mesmo espaço de nomes em uma única linha [use]. Isso deve ajudar a alinhar declarações de forma significativa ou simplesmente salvar alguns bytes em seus arquivos.


use Framework\Module\Foo;
use Framework\Module\Bar;
use Framework\Module\Baz;


Com o PHP 7 podemos usar:


use Framework\Module\{Foo, Bar, Baz};


Ou, se você preferir um estilo multi-line:

use Framework\Module{
    Foo,
    Bar,
    Baz
};


Operador de Coalescente Nulo

Isso resolve um problema comum na programação do PHP, onde queremos atribuir um valor a uma variável de outra variável, se esta última estiver realmente configurada, ou de outra forma fornecer um valor diferente para ela. É comumente usado quando trabalhamos com a entrada fornecida pelo usuário.

Pre-PHP 7:

if (isset($foo)) {
    $bar = $foo;
} else {
    $bar = 'default'; // we would give $bar the value 'default' if $foo is NULL
}


Depois do PHP 7:

$bar = $foo ?? 'default';


Isso também pode ser alinhado com várias variáveis:

$bar = $foo ?? $baz ?? 'default';


Operador spaceship

O operador spaceship (<=>) permite uma comparação de três vias entre dois valores, não apenas indicando se eles são iguais, mas também qual é maior, na desigualdade retornando 1,0 ou -1.

Aqui podemos tomar diferentes ações, dependendo de como os valores diferem:

switch ($bar <=> $foo) {
    case 0:
        echo '$bar and $foo are equal';
    case -1:
        echo '$foo is bigger';
    case 1:
        echo '$bar is bigger';
}


Os valores comparados podem ser inteiros, flutuadores, strings ou mesmo arrays. Verifique a documentação para ter uma idéia de como diferentes valores são comparados entre si. [https://wiki.php.net/rfc/combined-comparison-operator]

Novos recursos no PHP 7

Mas, claro, o PHP 7 também traz funcionalidade nova e emocionante.

Tipos de Parâmetros Escalares e Dicas de Tipo de Retorno

O PHP 7 estende as declarações de parâmetros anteriores dos parâmetros em métodos (classes, interfaces e arrays), adicionando os quatro tipos escalares; Inteiros ( int), flutuadores ( float), booleanos ( bool) e strings como possíveis tipos de parâmetro.

Além disso, podemos opcionalmente especificar quais tipos de métodos e funções retornam. Os tipos suportados são bool, int, float, string, array, callable, nome da classe ou interface, auto e pai (para métodos de classe)

class Calculator
{
    // We declare that the parameters provided are of type integer
    public function addTwoInts(int $x, int $y): int {
        return $x + $y; // We also explicitly say that this method will return an integer
    }
}


As declarações de tipo permitem a construção de aplicativos mais robustos e evitam passar e retornar valores incorretos das funções. Outros benefícios incluem analisadores de código estático e IDEs, que fornecem uma melhor visão sobre a base de código se faltar DocBlocks.

Uma vez que o PHP é uma linguagem de tipagem fraca, certos valores para os tipos de parâmetros e de retorno serão lançados com base no contexto. Se nós passamos o valor "3" em uma função que tenha um parâmetro de tipo declarado int, o intérprete o aceitará como um número inteiro e não lançará nenhum erro. Se você não quiser isso, você pode ativar strict mode, adicionando uma diretiva [declare].

declare(strict_types=1);

Isso é definido em uma base por arquivo, como uma opção global seria dividir repositórios de código para aqueles que são construídos com rigor mundial em e aqueles que não são, resultando em um comportamento inesperado quando combinamos o código de ambos.

Exceções do motor

Com a adição de exceções do mecanismo, erros fatais que resultariam na rescisão do script podem ser capturados e tratados com facilidade.

Erros como chamar um método inexistente, não encerrará o script, em vez disso, eles lançam uma exceção que pode ser tratada por um bloco try catch, que melhora o tratamento de erros para seus aplicativos. Isso é importante para certos tipos de aplicativos, servidores e daemons porque erros fatais exigiriam que eles reiniciassem. Os testes em PHPUnit também devem se tornar mais utilizáveis ​​à medida que erros fatais deixam cair o conjunto completo de testes. As exceções, em vez de erros, seriam tratadas em cada caso de teste.


O PHP 7 parece familiar, mas está atento ao desempenho. O refinado Zend Engine e os ganhos de desempenho resultantes fazem uma enorme diferença.

O PHP 7 adiciona várias novas classes de exceções com base no tipo de erros que podem ser encontrados. Para manter a compatibilidade entre versões, Throwable foi adicionada uma nova interface que pode ser implementada a partir de exceções de motor e exceções de usuário. Isso foi necessário para evitar exceções do motor para estender a classe de exceção base, resultando em antigas exceções de captura de código que não existiam antes.

Antes do PHP 7 isso teria encerrado o script com um erro fatal:

try {
    thisFunctionDoesNotEvenExist();
} catch (\EngineException $e) {
    // Clean things up and log error
    echo $e->getMessage();
}


Classes Anônimas

As classes anônimas são primas de funções anônimas que você pode usar em uma simples instância de curto prazo. As classes anônimas são facilmente criadas e usadas como um objeto comum.

Pre-PHP 7

class MyLogger {
  public function log($msg) {
    print_r($msg . "\n");
  }
}

$pusher->setLogger( new MyLogger() );


Com a classe anônima:

$pusher->setLogger(new class {
  public function log($msg) {
    print_r($msg . "\n");
  }
});


As classes anônimas são úteis no teste de unidades, particularmente em objetos e serviços de mocking tests. Isso nos ajuda a evitar pesadas bibliotecas e estruturas de simulação criando um objeto simples que fornece a interface que queremos fingir.

Funções CSPRNG

Foram adicionadas duas novas funções para gerar strings e números inteiros criptograficamente seguros.

random_bytes(int $len);

Retorna uma string aleatória com comprimento $len.

random_int(int $min, int $max);

Retorna um número entre $min e $max.

Unicode Codepoint Escape Syntax

Ao contrário de muitos outros idiomas, antes do PHP 7, o PHP não tinha uma maneira de escape de um codigo Unicode em literais de strings. Essa funcionalidade adiciona a seqüência de escape "\u" para produzir esses caracteres usando seu código UTF-8. Isso é melhor do que inserir os caracteres diretamente, permitindo um melhor tratamento de caracteres invisíveis, bem como caracteres que possuem a mesma representação gráfica, mas diferem em significado.

echo "\u{1F602}"; // outputs 😂

Observe que isso interrompe o código existente com a seqüência \u porque altera o comportamento.

Geradores são atualizados

Os geradores em PHP também possuem alguns recursos adicionais agradáveis. Agora, os geradores têm uma declaração de retorno que pode ser usada para permitir a saída de um valor final após a iteração. Isso pode ser usado para verificar se o gerador foi executado sem erros e permite que o código que chamou o gerador para lidar com vários cenários adequadamente.

Além disso, os geradores podem retornar e produzir expressões de outros geradores. Isso permite que eles dividam operações complexas em unidades mais simples e modulares.

function genA() {
    yield 2;
    yield 3;
    yield 4;
}

function genB() {
    yield 1;
    yield from genA(); // 'genA' gets called here and iterated over
    yield 5;
    return 'success'; // This is a final result we can check later
}

foreach (genB() as $val) {
    echo "\n $val"; // This will output values 1 to 5 in order
}

$genB()->getReturn(); // This should return 'success' when there are no errors.


Expectativas

As expectativas são um aprimoramento da função assert(), mantendo a compatibilidade com versões anteriores. Eles permitem asserções de custo zero no código de produção e fornecem a capacidade de lançar exceções personalizadas quando a afirmação falhar, o que pode ser útil durante o desenvolvimento.

assert() torna-se uma construção de linguagem em PHP 7. As afirmações devem ser usadas apenas para fins de depuração no desenvolvimento e testes de ambientes. Para configurar o seu comportamento, recebemos duas novas diretivas.

zend.assertions
1: gerar e executar o código (modo de desenvolvimento) (valor padrão)
0: gera o código, mas salta em torno dele em tempo de execução
-1: não gera código tornando zero-custo (modo de produção)


assert.exception
1: lance quando a afirmação falhar, seja jogando o objeto fornecido como a exceção ou jogando um novo objeto AssertionError se a exceção não for fornecida
0: use ou gere um Throwable como descrito acima, mas apenas gere um aviso com base nesse objeto ao invés de jogá-lo (compatível com o comportamento do PHP 5)

Preparando para mover do PHP 5 para o PHP 7

A introdução de um lançamento importante traz a oportunidade de alterar/atualizar funcionalidades mais antigas ou até mesmo removê-las se elas forem consideradas antigas demais ou tenham sido obsoletas há algum tempo. Tais mudanças podem introduzir quebras na compatibilidade em aplicativos mais antigos.

Outra questão que surge de saltos dessa versão é que bibliotecas e frameworks importantes de que você depende podem ainda não terem sido atualizados para suportar a versão mais recente. A equipe do PHP tentou tornar as novas mudanças compatíveis com versões anteriores e permitir que a migração para a nova versão seja tão indolor quanto possível. Aplicativos mais recentes e atualizados devem achar mais fácil mudar para a nova versão, enquanto aplicativos mais antigos podem ter que decidir se os benefícios superam o custo, possivelmente escolhendo não atualizar.

A maioria das quebras são menores e podem ser mitigadas facilmente, enquanto outras podem exigir mais esforço e tempo. Basicamente, se você tivesse avisos de desaprovação em seu aplicativo antes de instalar o PHP 7, você provavelmente receberá erros que quebrarão o aplicativo até serem corrigidos. Você foi avisado, certo?

SAPIs e extensões antigas

Mais importante ainda, os SAPIs antigos e obsoletos foram removidos como a extensão mysql (mas você não deveria usar isso em primeiro lugar, certo?). Para obter uma lista completa de extensões, você pode verificar estas RFCs aqui e aqui.

Além disso, outros SAPIs estão sendo portados para o PHP 7.


Um monte de SAPIs e extensões antigas foram retirados do PHP 7. Estamos achando que não serão perdidas.

Sintaxe Variável Uniforme

Esta atualização fez algumas mudanças a favor da consistência para construções ​​variáveis. Isso permite expressões mais avançadas com variáveis, mas introduz mudanças no comportamento em alguns outros casos, como mostrado abaixo.

                        // old meaning            // new meaning
$$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']()


Isso quebraria o comportamento de aplicativos que acessassem valores como este. Por outro lado, você pode fazer algumas coisas como esta:

// Nested ()
foo()(); // Calls the return of foo()
$foo->bar()();

// IIFE syntax like JavaScript
(function() {
    // Function body
})();

// Nested ::
$foo::$bar::$baz


Etiquetas de estilo antigo removidas

A abertura/fechamento de tags <% ... %>, <%= ... %>, são removidos e não mais válidos.

Nomes inválidos para Classes, Interfaces e Traits

Como resultado de adições como classes de parâmetros e tipos de retorno, as interfaces e os traits não podem mais ter os seguintes nomes:

bool
int
float
string
null
true
false

Estes causam quebras em aplicativos e bibliotecas existentes que os usam, mas devem ser fáceis de corrigir. Além disso, embora não provoquem nenhum erro e sejam válidos, o seguinte não deve ser usado porque eles são reservados para uso futuro:

resource
object
mixed
numeric

Para obter uma lista completa de alterações que quebrariam a compatibilidade, verifique este documento.

Você também pode usar o php7cc, que verifica seu código e pode detectar possíveis problemas que podem surgir se você mudar para o PHP 7. Mas, claro, não há melhor maneira do que instalar o PHP 7 e ver por si mesmo.

Possíveis problemas de compatibilidade do PHP 7

Compatibilidade de infraestrutura do PHP 7

Muitos serviços de hospedagem começaram a adicionar suporte para o PHP 7. Esta é uma boa notícia para os provedores de hospedagem compartilhada, pois os ganhos de desempenho permitirão aumentar o número de sites de clientes em seu hardware, reduzindo suas despesas operacionais e aumentando suas margens. Quanto aos próprios clientes, eles não devem esperar muito de um impulso nestas condições, mas para ser justo, a hospedagem compartilhada não é uma escolha orientada para o desempenho de qualquer maneira.

Por outro lado, os serviços que oferecem servidores privados virtuais ou servidores dedicados obterão os benefícios completos dessa colisão de desempenho. Alguns serviços PaaS, como o Heroku, apoiaram o PHP 7 no início, mas outros serviços, como a AWS Beanstalk e o OpenShift da Oracle, estão atrasados. Verifique o site do seu fornecedor PaaS para ver se o PHP 7 já é suportado, ou se o suporte virá no futuro próximo.

Claro, os provedores de IaaS permitem que você controle o hardware e instale o PHP 7 (ou compile se isso é mais do seu agrado). Os pacotes PHP 7 já estão disponíveis para os principais ambientes IaaS.

Compatibilidade de software PHP 7

Além da compatibilidade de infra-estrutura, você também precisa estar atento aos possíveis problemas de compatibilidade de software. Sistemas de gerenciamento de conteúdo populares como o WordPress, o Joomla e o Drupal adicionaram suporte para o PHP 7 com seus últimos lançamentos. Marcos importantes como Symfony e Laravel também gozam de suporte total.

No entanto, é hora de uma palavra de cautela. Este suporte não se estende ao código de terceiros na forma de complementos, plugins, pacotes ou o que seu CMS ou framework os chama. Eles podem sofrer problemas de compatibilidade e é sua responsabilidade garantir que tudo esteja pronto para o PHP 7.

Para repositórios ativos e mantidos, isso não deve ser um problema. No entanto, os repositórios mais antigos e não mantidos que não possuem suporte ao PHP 7 podem tornar sua aplicação inteira inutilizável.

O futuro do PHP

O lançamento do PHP 7 removeu o código antigo e obsoleto e preparou o caminho para novos recursos e atualizações de desempenho no futuro. Além disso, o PHP deverá obter otimizações de desempenho adicionais em breve. Apesar de ter algumas quebras de compatibilidade com lançamentos anteriores, a maioria dos problemas é fácil de resolver.

Bibliotecas e frameworks agora estão migrando seu código para o PHP 7, disponibilizando as versões mais recentes. Eu encorajo você a experimentá-lo e ver os resultados para você. Talvez o seu aplicativo já seja compatível e esteja à espera de usar, e se beneficiar do PHP 7.

POR VILSON DUKA - FREELANCE SOFTWARE ENGINEER @TOPTAL

ARTIGO ORIGINAL: Introducción A PHP 7: Qué Hay De Nuevo Y Qué Se Ha Ido