PHP 7.4, a próxima versão menor do PHP 7, foi lançada em 28 de novembro de 2019. Então é hora de mergulharmos em algumas das mais emocionantes adições e novas funcionalidades que terão tornado o PHP mais rápido e confiável.

O PHP 7.4. (lançamento oficial) está disponível para todos os clientes Kinsta para testes no painel MyKinsta. 🤘

Mesmo que o PHP 7.4 aumente significativamente a performance e melhore a legibilidade do código, o PHP 8 será o verdadeiro marco para a performance do PHP, já que a proposta de inclusão do JIT já foi aprovada.

De qualquer forma, hoje estamos passando por algumas das funcionalidades e mudanças mais interessantes que estamos esperando com o PHP 7.4. Só para que conste, estas foram as datas importantes para a versão 7.4:

  • 6 de Junho de 2019: PHP 7.4 Alpha 1
  • 18 de Julho de 2019: PHP 7.4 Beta 1 – Congelamento de recursos
  • 28 de Novembro de 2019: Lançamento do PHP 7.4 GA

Você pode conferir a lista completa de recursos e adições na página oficial da RFC.

O que há de novo em PHP com PHP 7.4?

Neste post estamos cobrindo várias mudanças e funcionalidades que devem ser adicionadas à linguagem com o lançamento final do PHP 7.4:

Esqueça o array_merge: PHP 7.4 Traz Operador de Espalhamento na Expressão de Array

Disponível desde o PHP 5.6, a descompactação de argumentos é uma sintaxe para descompactar arrays e Traversables em listas de argumentos. Para desempacotar um array ou um Traversable, tem de ser preparado por … (3 pontos), como mostrado no exemplo seguinte:

function test(...$args) { var_dump($args); }
test(1, 2, 3);

Agora esta RFC do PHP 7.4 propõe estender este recurso para definições de array:

$arr = [...$args];

O primeiro benefício declarado do Spread Operator na expressão de array é tudo sobre desempenho. Na verdade, o médico da RFC afirma:

O operador Spread deve ter melhor desempenho do que o array_merge. Isso não é só porque o operador spread é uma estrutura de linguagem enquanto array_merge é uma função, mas também porque a otimização de tempo de compilação pode ser performante para arrays constantes.

Uma vantagem significativa do operador Spread é que ele suporta qualquer objeto passível de ser atravessado, enquanto a função array_merge apenas suporta arrays.

Aqui está um exemplo de descompactação de argumentos na expressão array:

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

Se você executar este código com o PHP 7.3 ou anterior, o PHP emite um erro de Parse:

Parse error: syntax error, unexpected '...' (T_ELLIPSIS), expecting ']' in /app/spread-operator.php on line 3

Em vez disso, o PHP 7.4 retornaria um array:

array(5) {
	[0]=>
	string(6) "banana"
	[1]=>
	string(6) "orange"
	[2]=>
	string(5) "apple"
	[3]=>
	string(4) "pear"
	[4]=>
	string(10) "watermelon"
}

A RFC afirma que podemos expandir o mesmo array várias vezes. Além disso, podemos usar a sintaxe Spread Operator em qualquer lugar do array, já que elementos normais podem ser adicionados antes ou depois do operador spread. Assim, o seguinte código funcionará como seria de esperar:

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];

Também é possível descompactar arrays retornados por uma função diretamente em um novo array:

function buildArray(){
	return ['red', 'green', 'blue'];
}
$arr1 = [...buildArray(), 'pink', 'violet', 'yellow'];

O PHP 7.4 produz o seguinte array:

array(6) {
	[0]=>
	string(3) "red"
	[1]=>
	string(5) "green"
	[2]=>
	string(4) "blue"
	[3]=>
	string(4) "pink"
	[4]=>
	string(6) "violet"
	[5]=>
	string(6) "yellow"
}

Também podemos usar a sintaxe do gerador:

function generator() {
	for ($i = 3; $i <= 5; $i++) {
		yield $i;
	}
}
$arr1 = [0, 1, 2, ...generator()];

Mas não nos é permitido desempacotar arrays passados por referência. Considere o seguinte exemplo:

$arr1 = ['red', 'green', 'blue'];
$arr2 = [...&$arr1];

Se tentarmos descompactar um array por referência, o PHP lança o seguinte erro de Parse:

Parse error: syntax error, unexpected '&' in /app/spread-operator.php on line 3

De qualquer forma, se os elementos do primeiro array são armazenados por referência, eles são armazenados por referência no segundo array, também. Aqui está um exemplo:

$arr0 = 'red';
$arr1 = [&$arr0, 'green', 'blue'];
$arr2 = ['white', ...$arr1, 'black'];

E aqui está o que temos com o PHP 7.4:

array(5) {
	[0]=>
	string(5) "white"
	[1]=>
	&string(3) "red"
	[2]=>
	string(5) "green"
	[3]=>
	string(4) "blue"
	[4]=>
	string(5) "black"
}

A proposta do operador de Spread passou com 43 para 1 votos.

Funções de setas 2.0 (Fechamentos curtos)

Em PHP, funções anônimas são consideradas bastante verbosas e difíceis de implementar e manter Esta RFC propõe a introdução da sintaxe mais curta e clara das funções de seta (ou closures curtos), que deve nos permitir limpar significativamente nosso código PHP.

Considere o seguinte exemplo:

function cube($n){
	return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);

O PHP 7.4 permite usar uma sintaxe mais concisa, e a função acima pode ser reescrita da seguinte forma:

$a = [1, 2, 3, 4, 5];
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);

Atualmente, funções anônimas (closures) podem herdar variáveis definidas no escopo pai graças à construção da linguagem de use, como mostrado abaixo:

$factor = 10;
$calc = function($num) use($factor){
	return $num * $factor;
};

Mas com o PHP 7.4, variáveis definidas no escopo pai são implicitamente capturadas pelo valor (encadernação implícita pelo escopo do valor). Assim podemos escrever toda a função vista acima numa única linha:

$factor = 10;
$calc = fn($num) => $num * $factor;

A variável definida no escopo pai pode ser usada na função de seta exatamente como se estivéssemos usandouse($var), e não é possível modificar uma variável do escopo pai.

A nova sintaxe é uma grande melhoria para a linguagem, pois permite-nos construir código mais legível e de fácil manutenção. Também podemos usar tipos de parâmetros e retornos, valores padrão, listas de argumentos de comprimento variável (variadic functions), podemos passar e retornar por referência, etc. Finalmente, fechamentos curtos também podem ser usados em métodos de classe, e eles podem fazer uso da variável $esta como fechamentos regulares.

Esta RFC foi aprovada com 51 a 8 votos, então podemos esperar que ela faça parte das adições do PHP 7.4.

Operador de Atribuição de Coalescimento Nulo

Adicionado com PHP 7, o operador coalescente (??? ) é útil quando precisamos usar um operador ternário em conjunto com isset(). Retorna o primeiro operando se existe e não é NULL. Caso contrário, retorna o segundo operando. Aqui está um exemplo:

$username = $_GET['user'] ?? 'nobody';

O que esse código faz é bem simples: ele obtém o parâmetro request e define um valor padrão se ele não existir. O significado dessa linha é claro, mas e se tivéssemos nomes de variáveis muito mais longos como neste exemplo da RFC?

$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';

A longo prazo, este código pode ser um pouco difícil de manter. Assim, com o objetivo de ajudar os desenvolvedores a escrever código mais intuitivo, esta RFC propõe a introdução do null coalescing assignment operator (??=). Então, em vez de escrever o código anterior, poderíamos escrever o seguinte:

$this->request->data['comments']['user_id'] ??= 'value';

Se o valor do parâmetro esquerdo for null, então o valor do parâmetro direito é utilizado.
Note que, enquanto o operador coalescente é um operador de comparação, ??= é um operador de atribuição.

Esta proposta foi aprovada com 37 votos a favor e 4 contra.

Propriedades Digitadas 2.0

As declarações de tipo de argumento, ou dicas de tipo, permitem especificar o tipo de uma variável que se espera que seja passada para uma função ou um método de classe. Dicas de tipo são um recurso disponível desde o PHP 5, e desde o PHP 7.2 podemos usá-las com o tipo de dados do object. Agora o PHP 7.4 traz o type hinting um passo à frente adicionando suporte para declarações de tipo de propriedade de primeira classe. Aqui está um exemplo muito básico:

class User {
	public int $id;
	public string $name;
}

Todos os tipos são suportados, com exceção de void e callable:

public int $scalarType;
protected ClassName $classType;
private ?ClassName $nullableClassType;

A RFC explica o motivo pelo qual não há suporte para void e callable:

O tipo de vazio não é suportado, porque não é útil e tem semântica pouco clara.

O tipo de chamada não é suportado, porque seu comportamento é dependente do contexto.

Assim podemos usar com segurança bool, int, float, string, array, object, iterable, self, parent, qualquer classe ou nome de interface, e tipos anuláveis (? type).

Os tipos podem ser usados em propriedades estáticas:

public static iterable $staticProp;

Também são permitidos com a notação var:

var bool $flag;

É possível definir valores de propriedade padrão, que obviamente devem corresponder ao tipo de propriedade declarado, mas somente propriedades anuláveis podem ter um valor null padrão:

public string $str = "foo";
public ?string $nullableStr = null;

O mesmo tipo aplica-se a todas as propriedades numa única declaração:

public float $x, $y;

O que acontece se fizermos um erro no tipo de propriedade? Considere o seguinte código:

class User {
	public int $id;
	public string $name;
}

$user = new User;
$user->id = 10;
$user->name = [];

No código acima, declaramos um tipo de propriedade string, mas definimos um array como valor de propriedade. Neste cenário, obtemos o seguinte erro Fatal:

Fatal error: Uncaught TypeError: Typed property User::$name must be string, array used in /app/types.php:9

Esta RFC foi aprovada com 70 votos a 1 voto.

Referências Fracas

Com essa RFC, o PHP 7.4 introduz a classe WeakReference, que permite aos programadores manter uma referência a um objeto que não impede que o próprio objeto seja destruído.

Atualmente o PHP suporta referências fracas usando uma extensão como pecl-weakref. De qualquer forma, a nova API é diferente da classe WeakRef documentada.

Aqui está um exemplo do autor desta proposta, Nikita Popov:

$object = new stdClass;
$weakRef = WeakReference::create($object);

var_dump($weakRef->get());
unset($object);
var_dump($weakRef->get());

O primeiro var_dump imprime object(stdClass)#1 (0) {}, enquanto o segundo var_dump imprime NULL, pois o objeto referenciado foi destruído.

Esta RFC passou com 28 a 5 votos.

Devoluções covariantes e parâmetros contravariantes

A variância é uma propriedade das hierarquias de classes que descrevem como os tipos de um construtor de tipo afetam os subtipos. Em geral, um construtor de tipo pode ser:

  • Invariante: se o tipo da restrição de supertipo for o tipo do subtipo.
  • Covariante: se a ordenação dos tipos é preservada (os tipos são ordenados de mais específico para mais genérico).
  • Contravariante: se inverter a ordem (os tipos são ordenados de mais genéricos para mais específicos).

Atualmente, o PHP tem parâmetros e tipos de retorno invariantes, com poucas exceções. Esta RFC propõe permitir covariância e contravariância em tipos de parâmetros e tipos de retorno, fornecendo também vários exemplos de código.

Aqui está um exemplo de tipo de retorno covariante:

interface Factory {
	function make(): object;
}

class UserFactory implements Factory {
	function make(): User;
}

E aqui está um exemplo de tipo de parâmetro contravariante:

interface Concatable {
	function concat(Iterator $input); 
}
 
class Collection implements Concatable {
	// accepts all iterables, not just Iterator
	function concat(iterable $input) {/* . . . */}
}

Veja a RFC para um olhar mais atento sobre covariância e contravariação no PHP 7.4.

Esta RFC passou com 39 para 1 votos.

Pré-carregamento

Esta proposta de Dmitry Stogov é uma das nossas favoritas porque deve trazer um impulso significativo no desempenho. Pré-carregamento é o processo de carregar bibliotecas e frameworks para o OPCache na inicialização do módulo (leia mais sobre o ciclo de vida do PHP).

Ciclo de vida do PHP

Ciclo de vida do PHP (Fonte da imagem: PHP Internals)

Aqui está como a pré-carga funciona nas palavras de Dmitry:

Na inicialização do servidor – antes que qualquer código de aplicação seja executado – podemos carregar um certo conjunto de arquivos PHP na memória – e tornar seu conteúdo “permanentemente disponível” para todas as requisições subseqüentes que serão atendidas por esse servidor. Todas as funções e classes definidas nestes arquivos estarão disponíveis para solicitações fora da caixa, exatamente como entidades internas.

Esses arquivos são carregados na inicialização do servidor, são executados antes de qualquer aplicação e permanecem disponíveis para quaisquer solicitações futuras. Isso é óptimo em termos de desempenho.

A pré-carga é controlada por uma diretiva php.ini específica: opcache.preload. Esta diretiva especifica um script PHP para ser compilado e executado na inicialização do servidor. Este arquivo pode ser usado para pré-carregar arquivos adicionais, incluindo-os ou através da função opcache_compile_file() (leia mais na documentação do PHP).

Mas há uma desvantagem. Na verdade, a RFC afirma explicitamente:

arquivos pré-carregados permanecem em cache na memória opcache para sempre. A modificação de seus arquivos fonte correspondentes não terá nenhum efeito sem que outro servidor seja reiniciado.

No entanto, todas as funções definidas em arquivos pré-carregados serão permanentemente carregadas nas tabelas de funções e classes do PHP, e permanecerão disponíveis para cada solicitação futura. Isto conduzirá a melhorias de bom desempenho, ainda que essas melhorias possam ser consideravelmente variáveis.

Você pode ler mais sobre as limitações e exceções de pré-carregamento na página oficial Pré-carregamento RFC.

Novo mecanismo de serialização de objetos personalizados

Esta é outra proposta de Nikita Popov aprovada por uma grande maioria de votos.

Atualmente, temos dois mecanismos diferentes para serialização personalizada de objetos em PHP:

  • Os métodos __sleep() e __wakeup() mágicos
  • A interface serializável

De acordo com Nikita, ambas as opções têm problemas que levam a um código complexo e não confiável. Você pode mergulhar fundo neste tópico na RFC. Aqui eu apenas menciono que o novo mecanismo de serialização deve evitar esses problemas, fornecendo dois novos métodos mágicos, __serialize() e __unserialize(), que combinam os dois mecanismos existentes.

Esta proposta foi aprovada por 20 a 7 votos a favor.

Depreciações

As seguintes funções/funcionalidades serão obsoletas com o PHP 7.4. Para uma lista mais abrangente de depreciações, confira as Notas de Atualização do PHP 7.4.

Alterar a Precedência do Operador de Concatenação

Atualmente, em PHP os operadores aritméticos “+” e “-“, e o operador de string “.” são associativos à esquerda e têm a mesma precedência (leia mais sobre Precedência do Operador).

Como exemplo, considere a seguinte linha:

echo "sum: " . $a + $b;

No PHP 7.3 este código produz o seguinte aviso:

Warning: A non-numeric value encountered in /app/types.php on line 4

Isto porque a concatenação é avaliada da esquerda para a direita. É o mesmo que escrever o seguinte código:

echo ("sum: " . $a) + $b;

Esta RFC propõe alterar a precedência dos operadores, dando a “.” uma precedência inferior à dos operadores “+” e “-“, para que as adições e subtracções sejam sempre efectuadas antes da concatenação da string. Essa linha de código deve ser equivalente ao seguinte:

echo "sum: " . ($a + $b);

Esta é uma proposta em duas etapas:

  • A partir da versão 7.4, o PHP deve emitir um aviso de depreciação ao encontrar uma expressão não parentética com “+”, “-” e “.”.
  • A mudança real de precedência destes operadores deve ser adicionada com o PHP 8.

Ambas as propostas foram aprovadas por larga maioria de votos.

Depreciar operador ternário associativo-esquerdo

No PHP o operador ternário, ao contrário de muitas outras linguagens, é deixado-associativo. De acordo com Nikita Popof, isso pode ser confuso para programadores que alternam entre diferentes linguagens.

Atualmente, em PHP o seguinte código está correto:

$b = $a == 1 ? 'one' : $a == 2 ? 'two' : $a == 3 ? 'three' : 'other';

É interpretado como:

$b = (($a == 1 ? 'one' : $a == 2) ? 'two' : $a == 3) ? 'three' : 'other';

E isso pode levar a erros, porque pode não ser o que pretendemos fazer. Assim, esta RFC propõe depreciar e remover o uso da associatividade esquerda para operadores ternários e forçar os desenvolvedores a usar parênteses.

Esta é outra proposta de duas etapas:

  • A partir do PHP 7.4, ternários aninhados sem uso explícito de parênteses irão lançar um aviso de depreciação.
  • A partir do PHP 8.0, haverá um erro de execução de compilação.

Esta proposta foi aprovada com 35 a 10 votos a favor.

O que o PHP 7.4 significa para usuários do WordPress?

O PHP é a linguagem de programação do lado do servidor mais usada na web. De acordo com a W3Techs, em 2 de dezembro de 2019, o uso do PHP é usado por 78,9% de todos os sites cuja linguagem de programação do lado do servidor eles podem detectar.

Utilização do PHP (Dezembro 2019)

Utilização do PHP (Dezembro 2019)

Infelizmente, o PHP 5 ainda é usado por 44.0% de todos os sites com uma linguagem de programação conhecida do lado do servidor. Se você adicionar o número de usuários que ainda usam o PHP 7.0 e 7.1, acontece que a grande maioria dos sites estão rodando versões não suportadas do PHP.

Versões PHP suportadas

Versões PHP suportadas (Fonte da imagem: Supported Versions)

De acordo com a página oficial Estatísticas do WordPress, a partir de agora, 64% de todos os sites do WordPress estão rodando versões não suportadas do PHP. Apenas um pouco mais de 13% estão usando a versão mais recente: PHP 7.3. E a última versão, PHP 7.4, ainda não apareceu. Você pode ver que a grande maioria dos usuários, mais de 23%, ainda estão rodando no PHP 5.6.

WordPress PHP version Stats

WordPress PHP version Stats

Recomendamos vivamente que peça ao seu anfitrião uma versão suportada do PHP, de preferência de acordo com os requisitos oficiais do WordPress. A partir desta escrita, maio de 2019, WordPress requer:

  • PHP versão 7.3 ou superior.
  • MySQL versão 5.6 ou superior OU MariaDB versão 10.1 ou superior.
  • Suporte a HTTPS

Desempenho do PHP 7

Os números acima são especialmente desencorajadores vindo de um ponto de vista de desempenho, já que o PHP 7 mostrou ser significativamente mais rápido. Aqui estão algumas estatísticas:

Nós rodamos nossos próprios benchmarks de desempenho PHP com PHP 7.3. Vimos que o WordPress 5.0 no PHP 7.3 poderia executar quase três vezes mais transações (pedidos) por segundo em comparação com o PHP 5.6. Estaremos lançando benchmarks do PHP 7.4 em breve!

Referências do WordPress 5.0 PHP

Referências do WordPress 5.0 PHP

  • WordPress 5.0 PHP 5.6 benchmark: 91,64 req/sec
  • Resultados de benchmark do WordPress 5.0 PHP 7.0: 206.71 req/sec
  • Resultados de benchmark do WordPress 5.0 PHP 7.1: 210.98 req/sec
  • Resultados de benchmark do WordPress 5.0 PHP 7.2: 229.18 req/sec
  • WordPress 5.0 PHP 7.3 resultados de benchmark: 253.20 req/sec 🏆

Muitos são lentos para atualizar simplesmente por causa do tempo envolvido com o teste de novos todos os seus plugins de terceiros e temas para garantir que eles funcionam corretamente. Mas muitas vezes, resume-se ao facto de ainda não o terem feito.

Verificando sua versão PHP

Não tem certeza de qual versão do PHP você está executando? Uma das maneiras mais fáceis de verificar é usar uma ferramenta como o Pingdom ou o Google Chrome Devtools. O primeiro cabeçalho do pedido HTTP mostrará tipicamente a versão.

Verifique a versão PHP em Pingdom

Verifique a versão PHP em Pingdom

Isso depende da máquina não modificar o valor do cabeçalho X-Powered-By. No entanto, muitos o fazem por razões de segurança (incluindo Kinsta). Se sim, você pode não ver sua versão do PHP. Nesse caso, se você estiver executando o WordPress 5.2 ou superior, há uma nova ferramenta Site Health que você pode usar. Vá até “Tools” → “Site Health” → “Info” e na secção “Server” encontrará a versão PHP do seu servidor.

Verifique a versão PHP com a ferramenta WordPress Site Health

Verifique a versão PHP com a ferramenta WordPress Site Health

Alternativamente, você pode instalar um plugin gratuito como Version Info, que mostrará algumas informações básicas do servidor no rodapé do seu painel de administração do WordPress. Algumas outras maneiras de ver sua versão do PHP incluem fazer upload de um arquivo via FTP, ou simplesmente chegar ao seu host e perguntar.

Atualizando para PHP 7.4

A versão final do PHP 7.4 está disponível agora mesmo na Kinsta. Alternativamente, você pode testar seu site WordPress localmente ou verificar seus scripts em um ambiente como o Docker, que permite que você teste diferentes versões do PHP a partir da linha de comando.

A maneira mais fácil de começar a testar é criar um ambiente de testes, pois isso se assemelhará muito ao seu local de produção ao vivo. No painel do MyKinsta, clique no seu site e mude para Ambiente de teste.

Criar ambiente de desenvolvimento do WordPress

Criar ambiente de teste do WordPress

Então, no menu “Ferramentas” mude seu mecanismo PHP para PHP 7.4 (Beta). Você pode então começar a testar para garantir a compatibilidade do seu código, plugins de terceiros e temas.

Importante

Mesmo que esta seja uma versão estável, ainda encorajamos todos a testar o PHP 7.4 antes de usá-lo em seu site ao vivo.

Alterar para PHP 7.4

Alterar para PHP 7.4

Veja detalhes sobre o lançamento do PHP 7.4 na Kinsta.

Instalando e executando o PHP 7.4 no Docker

Queres testar no Docker? Felizmente, você não precisa compilar e configurar o PHP 7.4 manualmente. Se você já tem o Docker instalado em seu sistema, você só precisa instalar o Docker Image não oficial do PHP-FPM 7.4 e executar seus testes a partir da linha de comando em poucos segundos.

Instalando a imagem do Nginx Docker

Instalando a imagem do Nginx Docker

Se você preferir executar seu código PHP 7.4 em seu navegador, você também precisa instalar uma imagem Nginx ou Apache. Mas não te preocupes. Basta seguir as instruções do desenvolvedor. Copie e cole os comandos da página Imagem do Docker para a sua ferramenta de linha de comando, e você está pronto para começar.

PHP 7.4 é o última lançamento menor que tornará o PHP mais rápido e confiável. 🚀 Veja nosso mergulho profundo nas novas funcionalidades! Click to Tweet

Resumo

Neste post, cobrimos um bom número de mudanças e adições que podemos esperar com o lançamento do PHP 7.4. Se você está procurando a lista completa de recursos, junto com a documentação oficial da RFC, confira os seguintes recursos:

Vamos mantê-lo atualizado com todas as últimas informações sobre o PHP 7.4. Se você é um cliente Kinsta, você já pode começar a mover seus sites do WordPress para a versão mais recente.

Você está pronto para testar os próximos recursos do PHP? Qual deles é o teu favorito? Compartilhe suas idéias conosco nos comentários abaixo.


Se você gostou deste artigo, então você vai adorar a plataforma de hospedagem WordPress da Kinsta. Turbine seu site e obtenha suporte 24/7 de nossa experiente equipe de WordPress. Nossa infraestrutura baseada no Google Cloud se concentra em escalabilidade automática, desempenho e segurança. Deixe-nos mostrar-lhe a diferença Kinsta! Confira nossos planos