Pressione enter para ver os resultados ou esc para cancelar.

PHP 7.4: novas funcionalidades – Parte 3

Chegamos ao terceiro e último post sobre as novidades da versão 7.4 do PHP, até aqui já falamos sobre arrow functions, spread operator, typed properties, operador de atribuição null coalesce e weak references mas se você ainda não conferiu os últimos dois posts sobre as novas funcionalidades, deixarei os links abaixo, não quero que você perca nada sobre essas novidades!

 

1ª Parte – PHP 7.4: novas funcionalidades

2ª Parte – PHP 7.4: novas funcionalidades

 

Bom, bora começar e descobrir mais funcionalidade no 3º post dessa sequência!


Foreign Function Interface (FFI)

Agora vamos falar de outro recurso super interessante, conhecido como Foreign Function Interface ou simplesmente, FFI. Esse recurso permite que um programa escrito em uma determinada linguagem possa fazer a chamada de métodos e utilizar serviços definidos em outra linguagem. E daí você deve estar perguntando como isso funciona, acertei? Uma linguagem consegue utilizar recursos de outras através de uma ABI (Application Binary Interface).

Como o próprio nome sugere, ela define uma interface para utilização de tais recursos. Uma das ABIs mais comuns para utilização com FFI é a C-ABI, que define convenções de chamada e estruturas de dados para programas compilados em linguagem C. A convenção estabelecida por essa ABI também é suportada por diversas linguagens diferentes de C, tais como Rust. Em suma, a partir da versão 7.4 você estará apto a utilizar recursos da linguagem C (ou de qualquer linguagem que suporte FFI usando C-ABI) dentro de seus scripts PHP. Mas vamos a um exemplo para tornar as coisas mais divertidas.

Crie o arquivo ffi.php no diretório app com o seguinte conteúdo:

ffi.php
<?php

// Cria uma estrutura de dados da linguagem C
$a = FFI::new("long[1024]");

// Trabalhamos com ela como um array PHP comum
for ($i = 0; $i < count($a); $i++) {
 $a[$i] = $i;
}
var_dump($a[25]);
$sum = 0;
foreach ($a as $n) {
 $sum += $n;
}
var_dump($sum);
var_dump(count($a));
var_dump(FFI::sizeof($a));

 

Ao executar a página http://localhost/ffi.php você obterá o seguinte resultado:

int(25)
int(523776)
int(1024)
int(8192)

 

Perceberam o que fizemos? Criamos uma estrutura de dados da linguagem C e usamos como se fosse um array comum do PHP. Claro que este é um simples exemplo apenas para demonstrar a funcionalidade mas não se engane, é um funcionalidade poderosíssima. Esse recurso que fez o python, dentre outras linguagens, ser extremamente útil para rápida prototipação.

 

Numeric Literal Separator

Você já precisou lidar com números gigantes em seus scripts? Já se perdeu e não sabia se estava tratando de milhares, milhões ou bilhões? Se sim, acredito que talvez você gostará dessa funcionalidade. Estou falando do Numeric Literal Separador que permite a inserção de underscore entre os numerais para melhorar a legibilidade. Vamos ver na prática seu funcionamento. Crie o arquivo numeric.php no diretório app com o seguinte conteúdo:

numeric.php
<?php

$numeroConfuso = 1000000000; // Seriam 100 bilhões? 100 milhões? 10 bilhões?
var_dump($numeroConfuso / 50);

$numeroClaro = 1_000_000_000; // certamente se trata de 1 bilhão
var_dump($numeroClaro / 50);

 

Perceberam o que fizemos? A variável $numeroClaro utiliza underscore (“_”) para separar as unidades do numeral e então melhorar sua legibilidade. Ambas expressões retornarão o mesmo valor, conforme pode ser visto abaixo:

int(20000000) 
int(20000000

 

Provavelmente essa funcionalidade irá gerar algumas discussões se ela é realmente útil ou não. De qualquer maneira, você já sabe como ela funciona e não ficará sem entender caso a veja por aí! 🙂

 

Preloading

Para fechar com chave de ouro, falaremos agora sobre uma funcionalidade que pode aumentar significativamente a performance de suas aplicações: o preloading. Entretanto, por se tratar de um assunto mais extenso (e pra não alongar ainda mais o artigo), vamos deixar a parte prática dessa funcionalidade para um post futuro, onde abordaremos cada aspecto dessa funcionalidade. Nesse post entenderemos sobre o que se trata o preloading e os ganhos que temos com sua utilização.

Se você já trabalha com a linguagem PHP há algum tempo já deve conhecer o Opcache. Basicamente, o que ele faz é manter scripts pré-compilados na memória compartilhada, evitando assim, a necessidade de carregar e parsear esses scripts a cada requisição, esses arquivos pré-compilados são conhecidos como “opcodes”. Entretanto, esses opcodes não sabem sobre outros arquivos, ou seja, se uma classe A extende uma classe B elas serão linkadas em tempo de execução.

Além disso, o Opcache realiza checagens para verificar se esses arquivos foram modificados e, nesse caso, invalidando os arquivos cacheados. Provavelmente você percebeu que as 2 operações citadas (link e checagem de mudanças) exigem algum trabalho extra, assim como o carregamento dos scripts da memória compartilhada para a memória principal. Essas tarefas impactam a performance e é exatamente esses itens que o preloading visa aprimorar.

 

Algumas Características do Preloading

  • Arquivos carregados no preloading são, além de compilados, linkados a classes, interfaces e traits relacionados. Assim, esse conjunto de códigos será mantido na memória principal, disponível para ser utilizado assim que uma requisição for feita.
  • Os arquivos serão carregados na inicialização do servidor e mudanças nesses arquivos não terão nenhum efeito, a menos que o servidor seja reiniciado.

Aposto que você deve estar se perguntando como utilizar o preloading, acertei? É bem simples! Vamos ao passos:

  • Você precisa criar um arquivo de preload e defini-lo no seu php.ini através da diretiva opcache.preload.
  • Os arquivos que necessitam se “pré-carregados” precisam passar pela função opcache_compile_file (ou require_once) no arquivo de preload.

 

Dessa forma, seu arquivo php.ini teria a seguinte diretiva:

opcache.preload=/caminho/para/o/arquivo/de/preload.php

 

e esse poderíamos implementar esse arquivo de preload de uma forma bem simples:

$arquivos = /* Array de arquivos que você deseja carregar */;

foreach ($arquivos as $arquivo) {
    opcache_compile_file($arquivo);
}

 

Bem legal, não é mesmo? Com essa funcionalidade podemos carregar frameworks inteiros ou apenas as hot classes (mais usadas), cabe a você definir qual será a melhor estratégia para sua aplicação e aproveitar todas as vantagens dessa funcionalidade.

 

Conclusão

Ufa, chegamos ao final do nosso artigo número 3. Tivemos a oportunidade de conhecer muitas novas funcionalidades: arrow functions, preloading, spread operator, FFI, weak references e tantas outras. Entretanto, não paramos por aqui, não! Algumas das funcionalidades ainda podem nos proporcionar muito assunto e, portanto, muito em breve abordaremos algumas dessas funcionalidades em artigos específicos, fique ligado! Um abraço e até a próxima!