O que há de novo no PHP 8: Tudo que você precisa saber!

Publicados: 2021-01-06

Entraremos em contato com o PHP8 em 26 de novembro de 2020 e, certamente, há muito a ser escrito sobre os próximos recursos desta versão apreciada.

PHP8

Como é uma versão principal, haverá mudanças de última hora e novos recursos, além de tornar importante estar ciente de tudo o que está mudando. Será conveniente pensar em como o PHP8 afetará seus aplicativos e quais ações serão necessárias para garantir que você possa atualizar convenientemente sem incidentes.

Passamos por algumas das mudanças mais consideráveis ​​para descobrir o que vamos obter na próxima versão do PHP e o que vale a pena criticar.

vamos começar com a visão geral!

Visão geral do PHP 8

Como mencionado acima, o PHP 8 apresenta um pacote de novos recursos, melhorias, funções e depreciações para a linguagem. Entre todos eles, o recurso mais discutido é o compilador JIT. No entanto, recursos de melhoria de desempenho, como JIT, merecem destaque, mas espera-se que as melhorias sintáticas tenham mais um verdadeiro sucesso para os praticantes de PHP, diríamos, “pelo menos no curto prazo”.

Uma história de mudança

Algumas mudanças no PHP são propostas, debatidas, implementadas e aprovadas em pouco tempo. Eles são populares, incontroversos e têm um método natural para implementá-los.

E depois disso vêm os que são tentados, falham e retornam várias vezes antes de aceitá-los finalmente. Algumas vezes, a implementação consome muito tempo para ser resolvida, e às vezes a ideia em si está apenas incompleta, e às vezes a própria comunidade ainda não se aqueceu para a ideia – “ainda não é hora”.

Os créditos se enquadram diretamente na categoria de tipo. Eles foram propostos pela primeira vez no ano de 2016 para PHP 7.1. No entanto, eles encontraram resistência obstinada e perderam o voto de aceitação por uma margem pesada. Agora, avançando quatro anos, e uma proposta bastante semelhante, embora de escopo ligeiramente reduzido, surgiu com apenas um dissidente. É evidentemente uma ideia cuja hora certamente chegou!

Quais são os problemas com o código antigo?

Como o PHP 8 é uma grande nova versão, devemos esperar que o código antigo não seja mais compatível. No entanto, a maioria das mudanças que poderiam propor complicações já estavam veiculadas nas versões 7.2 , 7.3 e 7.4 . Vamos falar sobre as últimas mudanças agora. Eles estão:

Legado de citações mágicas

  • O verdadeiro tipo
  • Filtro FILTER_SANITIZE_MAGIC_QUOTES
  • Desvinculando $this de fechamentos não estáticos
  • array_key_exists() com objetos
  • mb_strrpos() com codificação como terceiro argumento
  • Métodos de exportação () de reflexão
  • função convert_cyr_string()
  • mix de ordem do parâmetro implode()
  • função restore_include_path()
  • função hebrevc()
  • função money_format()
  • diretiva allow_url_include ini
  • função ezmlm_hash()

Novas funções no PHP 8

str_contains

Se uma string contém outra, existem várias maneiras de descobrir.

Geralmente, você usará strpos(). Como você sabe, strpos() pega um palheiro ao lado da agulha que você deseja procurar. Ele retorna um inteiro mostrando a primeira posição na qual você vê a agulha.

Agora, como está retornando a posição de uma string em outra, você simplesmente não pode verificar se strpos() a descobriu ou não; se retornar “0” (as posições são indexadas a zero e começam com 0 em vez de 1), então a condicional irá tratá-lo como um valor falso, indicando que não foi encontrado.

O que isso significa?

Você terá que escrever condicional –“strpos($haystack, $needle) !== false.” False indica que não foi possível encontrar a posição da string. Este é um método não transparente e esotérico para pesquisar uma string em uma string! Bem, não tão confuso.

Para evitar isso, o PHP 8 traz str_contains(). O trabalho de str_contains() é retornar um booleano simples mostrando se a agulha está ou não presente no palheiro. Isso é muito mais fácil de escrever, além disso, entender como alguém que mantém o código, não é?

 if (str_contains( 'Foo Bar Baz' , 'Foo' )) { // FOUND }

PHP 8: Recursos e alterações do mecanismo

Existem alguns novos recursos de mecanismo e mudanças observadas no PHP 8. O recurso principal, sem dúvida, é o novo compilador JIT.

Compilador JIT

  • Aplicação de LSP
  • Erros fatais em assinaturas de métodos incompatíveis
  • Recurso "Aulas"
  • XML-RPC está agora em PECL
  • Comportamento de afirmação
  • Alterações de reflexão

Para o propósito central deste blog, vamos nos concentrar no compilador JIT, nas “classes” de recursos e, finalmente, nas alterações da API de reflexão.

Compilador Just-In-Time ( RFC )

Devido às melhorias de velocidade feitas antes do lançamento do PHP7, ocorreu o nascimento do compilador Just-In-Time (ou JIT). Está sendo introduzido no PHP8 porque quase não há mais melhorias na velocidade que podem ser trazidas sem usar um JIT. A ideia é que isso melhore o desempenho do PHP.

O código PHP é traduzido em bytecodes quando executado, e esses bytecodes são posteriormente utilizados para executar as etapas do programa.

O PHP analisará o código que você executou, é isso que um JIT significa. Além disso, ele pode tomar decisões em tempo real além de melhorias de desempenho no código à medida que você o executa. Será altamente utilizável em aplicativos com uso intensivo de CPU e não apenas em cenários baseados na web.

Isso reflete que os aplicativos PHP do lado do servidor certamente podem ser mais predominantes com o sistema JIT embutido em PHP.

Você primeiro precisa ativar o JIT se quiser usá-lo. Em nosso sistema de teste (Ubuntu 20.04), já instalamos o módulo PHP opcache, que instalamos com o pacote principal do PHP8. Configuramos no arquivo colocado em /etc/php/8.0/cli/conf.d/10-opcache.ini.

Agora, você está pronto para ativar o JIT, certo?  

  • Habilite o opcache

Você pode atribuir armazenamento de memória à configuração opcache.jit_buffer_size . Seu arquivo aparecerá assim no meu sistema.

  1. zend_extension=opcache.so
  2. opcache.enable_cli=1
  3. ; configuração para o módulo php opcache
  4. opcache.jit_buffer_size=256M

Além disso, use a função opcache_get_status() para garantir se está ativo. Role seu olhar sobre a parte 'jit' desta matriz e obtenha informações sobre o status atual do JIT.


var_dump(opcache_get_status()['jit']);

Se o JIT foi ativado perfeitamente, isso deve ser impresso conforme mostrado abaixo.

  1. array(7) {
  2. [“habilitado”]=>
  3. bool(true)
  4. [“ligado”]=>
  5. bool(true)
  6. [“gentil”]=>
  7. int(5)
  8. [“opt_level”]=>
  9. int(4)
  10. [“opt_flags”]=>
  11. int(6)
  12. [“buffer_size”]=>
  13. int(268435440)
  14. [“buffer_free”]=>
  15. int(268432880)
  16. }

Então foi mais rápido? Em uma palavra, exclamávamos um caloroso “sim”.

Percebemos algumas pessoas fazendo benchmarks com a ajuda de um conjunto mandelbrot, então decidimos usar uma biblioteca que criamos há algum tempo que desenha alguns tipos diferentes de fractais em PHP. Tudo o que fizemos foi gerar três fractais e rastrear quanto tempo levou utilizando a função microtome(). Exibimos os resultados do PHP 7.4.8 abaixo.

  • Queimada – 84.20269203186
  • Mandlebrot – 21.552599906921
  • Tricórnio – 32.685042858124

Quando rodamos o mesmo código no PHP8, foi bem mais rápido. Os números falarão por si. .

  • Queimada – 15.272277116776
  • Mandlebrot -3.7528541088104
  • Tricórnio -4.4957919120789

Este enorme aumento de velocidade é bastante interessante. O código que usamos aqui cria fractais de tamanho enorme, mas lembramos ao criar o código que a maior parte do nosso tempo foi gasto esperando a geração de fractais.

Essa adição é interessante para nós, pois levamos o PHP aos seus limites em algumas ocasiões (fora da geração de fractais). Podemos notar que isso será um grande benefício para o futuro do PHP e permitirá que a linguagem seja escolhida para situações fora da linguagem normal do site.

Não analisamos o incremento de velocidade para aplicativos como WordPress ou Drupal, mas pelo que lemos, certamente há pouca diferença nesses tipos de aplicativos. No futuro, executaremos benchmarks nessas plataformas para descobrir que tipo de diferença o JIT marca lá.

Tipos de União ( RFC )

Desde o PHP7, estipulando que tipo de valores de retorno e tipos de argumentos e tem sido possível. Isso permitirá que o PHP lance um erro caso o tipo de argumento que você está passando seja uma classificação não idêntica ao tipo esperado. É crucial garantir que as funções recebam e produzam os tipos perfeitos de valor em uma linguagem de tipagem flexível, como PHP.

No PHP8, agora é possível estipular vários tipos de argumentos e valores de retorno, divididos por um caractere de barra vertical.

Mostramos abaixo uma função capaz de aceitar um valor float ou um valor inteiro.

 function addNumbers(int|float $number1, int|float $number2) : int|float { return $number1 + $number2; }

Anteriormente, uma função idêntica a essa precisaria ser gerada sem nenhuma dica de tipo porque o PHP poderia mostrar silenciosamente o tipo caso o argumento passado não estivesse correto. Isso significava que, caso definissemos o tipo de argumento como um inteiro, o PHP mostraria qualquer valor float em um inteiro. Certamente pode levar a alguns bugs complicados de serem detectados caso você não esteja testando a unidade.

Nós apenas chamamos como qualquer outro para usar a função acima

 echo addNumbers(1, 1); // prints 2 echo addNumbers(1.1, 1.1); // prints 2.2

Caso tentemos passar uma string para a função idêntica:

 echo addNumbers('one', 'two');

Receberemos um erro PHP Fatal exclamando que precisamos passar um float ou um “int” para a função.

Você não pode usar o tipo void como um tipo de união porque estipula que a função não retornará nada. Em palavras simples, você não pode dizer que uma função vai retornar um void ou um inteiro; você receberá um erro fatal do PHP.

Embora uma mudança normal que podemos ver foi esse recurso sendo usado um pouco, pois anteriormente só era possível estipular vários tipos de valor nos comentários, o que resultou em comentários do bloco de documentos se tornando mais detalhados do que o código.

O operador Nullsafe (RFC)

Além do operador de coalescência nulo, a capacidade de detectar valores de retorno nulo é possível diretamente dos métodos. Se você não estava ciente, o operador de coalescência nulo permite obter um valor, e você não precisa testar caso o valor esteja presente além de retornar um valor diferente caso o primeiro valor seja nulo.

Então, podemos fazer isso para obter um valor de – “$_GET superglobal”. e caso esse valor não esteja presente, então “0”.


1. $page = $_GET['page'] ?? 0;

2. echo $página;

O funcionamento do operador null safe é o mesmo, mas permite que você crie um atalho útil e teste um retorno nulo de um caminho antes de tentar usar esse valor.

Percebemos que isso será útil no Drupal, onde tendemos a escrever muito código de verificação para garantir que “retornos de métodos” ou “propriedades de objetos” tenham coisas neles antes de utilizá-los. Isso é obrigatório devido ao estado contextual dos objetos no Drupal devido ao conteúdo que eles contêm. Essa mudança certamente simplificará algumas das verificações.

Argumentos nomeados ( RFC )

Os argumentos nomeados permitem estipular uma ordem diferente de argumentos e chamar funções. Pegue a seguinte função normal que tem dois parâmetros. Ele preenche uma matriz com o comprimento fornecido.

 function fillArray(array $arrayToFill, int $number) : array { for ($i = 0 $i < $number; ++$i) { $arrayToFill[$i] =1; } return $arrayToFill; }

Podemos passar os argumentos no arranjo em que são definidos, podemos chamar essa técnica da maneira normal.

 $newArray = fillArray([], 2);

A partir do PHP8, agora você pode nomear os parâmetros à medida que os passa para a função. Também permite enviar os parâmetros na ordem que quisermos.

 $newArray = fillArray(number: 2, arrayToFill: []);

Um exemplo normal, mas também pode tornar o código mais legível.

Esta técnica funciona com todas as funções em PHP, não apenas as definidas pelo usuário. Na linguagem PHP, as funções array e string têm ordens de parâmetros não idênticas. Então, é uma adição verdadeiramente bem-vinda.

Atributos V2 ( RFC1 RFC2 RFC3 )

Os atributos fornecem um mecanismo para juntar metadados a classes PHP, funções, propriedades de classe, parâmetros de função e constantes. Eles não podem ser acessados ​​diretamente por meio de código, e você precisa retirá-los com a ajuda do PHP construído em classes de reflexão.

A classe ReflectionClass está em PHP desde PHP5; entretanto, o método getAttribute() é novo para PHP8. Esse método retorna um intervalo de objetos ReflectionAttribute que vão incluir informações sobre atributos.

Essa adição enfrentou algumas mudanças (como podemos notar nas várias RFCs acima). No caso de você instanciar a classe, você pode usar o ReflectionClass e imprimir as informações do atributo contidas em um nível de classe. Há muitos atributos no PHP8, então recomendamos ler as RFCs e se familiarizar com o que elas realmente são e como você pode integrá-las ao seu código.

Expressão de correspondência ( RFC )

No PHP 8, podemos comparar a nova expressão de correspondência com uma instrução switch abreviada.

Parece um pouco como uma declaração de função que retornará um valor com base no valor passado.

A instrução switch no PHP é incrível quando você deseja verificar a condição na expressão idêntica sem incluir várias instruções if .

Aqui trazemos uma comparação básica if-else em uma expressão idêntica.

 <?php if ($i == 'apple') { echo 'i is apple'; } elseif ($i == 'cake') { echo 'i is cake'; } else { echo 'i is pizza'; }

E é assim que a instrução switch equivalente do nosso exemplo anterior apareceria como

 <?php switch ($i) { case 'apple': echo 'i is apple'; break; case 'cake': echo 'i is cake'; break; default: echo 'i is pizza'; }

Recurso “Aulas”

As “classes” de recursos vêm na lista das principais mudanças no PHP 8 e servem como substitutos não instanciados para determinados tipos de recursos. Veja abaixo para saber as substituições disponíveis incluem:

  • CurlHandle — curl_init() agora retorna CurlHandle, relacionando um recurso curl.
  • Socket / AddressInfo — Dado pela extensão sockets; a quantidade de funções socket_*() retorna um Socket, enquanto a função socket_address_info_lookup() retorna uma instância AddressInfo.
  • GdImage — Representa um recurso GD, conforme restaurado pelas inúmeras funções imagecreatefrom*().

Além disso, é crucial observar que os recursos não são destruídos por funções como curl_close(). Em vez disso, você precisa unset() a instância para desreferenciá-la, pois agora é uma instância de classe.
Você ganha a capacidade de especificar as classes como dicas de tipo em suas funções e métodos.
Anteriormente, tínhamos que retornar valores sem tipo ou deixar argumentos de recursos e documentá-los por meio de anotações, mas agora você pode ter tipos explícitos, e isso não apenas torna seu código mais legível, mas também mais seguro.
Qual é a troca aqui?
Agora você precisará atualizar seu código se quiser destruir recursos com a ajuda de unset() no lugar das funções anteriores usadas para demolir recursos. Isso normalmente pode ser feito por meio de pesquisa e substituição.

Alterações da API de reflexão

Outra pequena, mas uma mudança vital no PHP 8 está relacionada à API de reflexão. Ao usar o sistema de atributos, você pode recuperar convenientemente esses atributos por meio da API de reflexão em qualquer classe de reflexão.
Com a adição de tipos mistos e de união, as técnicas de ReflectionParameter getClass(), isCallable() e isArray() agora estão obsoletas.
O cenário é assim porque usar getType() é muito melhor e você obtém a lista completa de tipos que um parâmetro específico satisfaz.

Melhorias na sintaxe do PHP 8

Como estamos percebendo, o JIT está roubando as manchetes; as melhorias sintáticas do PHP 8 oferecem enormes vantagens de qualidade de vida para desenvolvedores PHP.
Não importa a eliminação do clichê comum entre os argumentos do construtor promovidos ou o tratamento aprimorado de exceções e erros, há muito para os desenvolvedores se sentirem animados.

  • pseudotipo “misto”
  • Tipos de União
  • Promoção de propriedade de construtor de classe
  • Lançando exceções de expressões
  • Atributos
  • :: onipresença de classe
  • Capturar apenas por tipo
  • Expressões de correspondência

Para fins de manutenção deste blog, estamos nos concentrando em tipos de união, atributos e expressões de correspondência.

Tipos de União

Os tipos de união mostram que um valor é um entre duas ou mais classificações especificadas. É feito com uma barra vertical colocada entre cada tipo permitido. Para vários desenvolvedores que são profundos em anotações PHP para retornar valores ou especificar seus parâmetros, você já está fazendo isso, provavelmente.
Os tipos de união podem trazer muita complexidade e dificuldade de compreensão para aqueles que aceitam muitos tipos diferentes ou retornam muitos tipos diferentes.
Ainda assim, isso será muito útil em várias ocasiões. Por exemplo, caso você possa aceitar ou um objeto implementando a nova interface Stringable (“string|Stringable”), ou uma string, ou se você puder aceitar um objeto implementando a interface Traversable (“array|Traversable”) ou um array .

Expressões de correspondência

As expressões de correspondência eliminam as suposições relacionadas a descobrir se a falha na quebra de um determinado caso de comutação é intencional ou não. Também simplifica o padrão normal de atribuição de um valor com base em uma correspondência.
Quando usado, o valor que passamos para match() será comparado diretamente com qualquer expressão que esteja no lado esquerdo. Não importa se é uma expressão ou um valor, o valor que você passa para match() deve corresponder a ele para que seja escolhido.
Quando correspondida, a expressão presente à direita é estimada e seu valor de retorno retornado, enquanto as expressões só podem ser funções Lambda ou callables, e nenhum fechamento de várias linhas é permitido.

Atributos

O PHP 8 também integra atributos no nível da linguagem. Embora os atributos estejam presentes por mais de 15 anos por meio de anotações do docblock, integrá-los à linguagem oferece melhor desempenho e, certamente, mais poder e consistência. Provavelmente veremos atributos sendo muito usados ​​no desenvolvimento de ferramentas e aplicativos rápidos.

Conclusão

Certamente, existem algumas mudanças no PHP8. Ainda assim, parece que a maioria do código obsoleto que está sendo eliminado é para recursos mais antigos que não vimos sendo usados ​​nos últimos tempos.
Estamos bastante interessados ​​em observar o impacto que o mecanismo JIT terá nas bases de código que usamos e também na comunidade PHP mais ampla - dizendo que recomendamos verificar sua base de código quanto a incompatibilidades com PHP8 e executar testes de unidade para garantir que seu PHP os aplicativos funcionam perfeitamente antes de dizer “sim” à atualização.