O PHP 8 deverá ser lançado em Dezembro de 2020 e nos trará um monte de recursos poderosos e grandes melhorias na linguagem.

Muitos RFCs já foram aprovados e implementados, então é hora de mergulharmos em algumas das mais emocionantes adições que devem tornar o PHP mais rápido e mais confiável.

Como o PHP 8 ainda está em desenvolvimento, pudemos ver várias mudanças antes do lançamento final. Nós vamos acompanhar essas mudanças e atualizar esse post regularmente, então certifique-se de não perder nada sobre o PHP 8 e verifique esse post de tempos em tempos.

Então, quais características e melhorias devemos esperar com o PHP 8? Qual a maior coisa que vem com o PHP 8, o próximo grande lançamento da linguagem?

Vamos mergulhar!

PHP JIT (Compilador Just in Time)

O recurso mais aclamado que vem com o PHP 8 é o compilador Just-in-time (JIT). Do que se trata o JIT?

A proposta da RFC descreve o JIT da seguinte forma:

“O PHP JIT é implementado como uma parte quase independente do OPcache. Ele pode ser habilitado/desabilitado em tempo de compilação e em tempo de execução do PHP. Quando habilitado, o código nativo dos arquivos PHP é armazenado em uma região adicional da memória compartilhada do OPcache e op_array→opcodes[]. manipulador(es) mantém apontadores para os pontos de entrada do código JIT-ed.”

Então, como chegamos ao JIT e qual é a diferença entre JIT vs OPcache?

Para entender melhor o que é o JIT para PHP, vamos dar uma rápida olhada em como o PHP executa desde o código fonte até o resultado final.

A execução do PHP é um processo em 4 etapas:

A imagem a seguir mostra uma representação visual do processo básico de execução do PHP.

Processo básico de execução do PHP

Processo básico de execução do PHP

Então, como o OPcache torna o PHP mais rápido? E que mudanças no processo de execução com o JIT?

A Extensão OPcache

PHP é uma linguagem interpretada. Isto significa que, quando um script PHP é executado, o intérprete analisa, compila e executa o código uma e outra vez a cada solicitação. Isto pode resultar em desperdício de recursos da CPU e tempo adicional.

É aqui que entra a extensão da OPcache para jogar:

“OPcache melhora a performance do PHP ao armazenar bytecode de script pré-compilado em memória compartilhada, removendo assim a necessidade do PHP carregar e analisar scripts em cada requisição”.

Com o OPcache habilitado, o intérprete PHP passa pelo processo de 4 etapas mencionado acima apenas na primeira vez que o script é executado. Como os bytecodes PHP são armazenados em memória compartilhada, eles estão imediatamente disponíveis como representação intermediária de baixo nível e podem ser executados na VM da Zend imediatamente.

Processo de execução do PHP com OPcache habilitado

Processo de execução do PHP com OPcache habilitado

A partir do PHP 5.5, a extensão Zend OPcache está disponível por padrão e você pode verificar se está configurado corretamente, simplesmente chamando phpinfo() de um script em seu servidor ou verificando seu arquivo php.ini (veja as configurações do OPcache).

Seção Zend OPcache em uma página phpinfo

Seção Zend OPcache em uma página phpinfo

Pré-carga

OPcache foi recentemente melhorado com a implementação do pré-carregamento, um novo recurso OPcache adicionado com o PHP 7.4. O pré-carregamento fornece uma forma de armazenar um conjunto específico de scripts na memória OPcache “antes que qualquer código de aplicação seja executado“, mas não traz melhorias tangíveis de performance para aplicações típicas baseadas na web.

Você pode ler mais sobre pré-carga em nossa introdução ao PHP 7.4.

Com o JIT, o PHP dá um passo à frente.

JIT – O Compilador Just in Time

Mesmo que os opcodes estejam na forma de representação intermediária de baixo nível, eles ainda têm que ser compilados em código de máquina. JIT “não introduz nenhuma forma adicional de IR (Representação Intermediária)”, mas utiliza DynASM (Dynamic Assembler for code generation engines) para gerar código nativo diretamente do byte-código PHP.

Em resumo, o JIT traduz as partes quentes do código intermediário em código de máquina. Ao contornar a compilação, ele seria capaz de trazer melhorias consideráveis na performance e uso de memória.

Zeev Surasky, co-autor da proposta PHP JIT, mostra o quanto os cálculos seriam mais rápidos com o JIT:

Mas, o JIT efetivamente melhoraria o desempenho do WordPress?

JIT para aplicações web ao vivo

De acordo com a RFC do JIT, a implementação do compilador just in time deve melhorar a performance do PHP. Mas será que nós realmente experimentaríamos tais melhorias em aplicações da vida real como WordPress?

Os primeiros testes mostram que o JIT faria com que as cargas de trabalho intensivas em CPU funcionassem significativamente mais rápido, no entanto, o RFC adverte:

“… como as tentativas anteriores – atualmente não parece melhorar significativamente aplicações da vida real como WordPress (com opcache.jit=1235 326 req/sec vs 315 req/sec).

Está previsto um esforço adicional, melhorando o JIT para aplicações da vida real, utilizando otimizações de perfil e especulativas.”

Com o JIT habilitado, o código não seria executado pela VM da Zend, mas pela própria CPU, e isto melhoraria a velocidade nos cálculos. Aplicações Web como WordPress também dependem de outros fatores como TTFB, otimização de banco de dados, solicitações HTTP, etc.

Então, quando se trata de WordPress e aplicativos similares, não devemos esperar um grande impulso na velocidade de execução do PHP. No entanto, o JIT pode trazer vários benefícios para os desenvolvedores.

De acordo com Nikita Popov:

“Os benefícios do compilador JIT são mais ou menos (e como já foi delineado no RFC):

  • Desempenho significativamente melhor para códigos numéricos.
  • Um pouco melhor desempenho para código “típico” de aplicações web PHP.
  • O potencial para mover mais código de C para PHP, porque o PHP agora será suficientemente rápido.”

Então, enquanto o JIT dificilmente trará grandes melhorias na performance do WordPress, ele estará atualizando o PHP para o próximo nível, fazendo dele uma linguagem na qual muitas funções poderiam agora ser escritas diretamente.

O lado negativo, porém, seria a maior complexidade que pode levar ao aumento dos custos de manutenção, estabilidade e depuração. De acordo com Dmitry Stogov:

“JIT é extremamente simples, mas de qualquer forma aumenta o nível de toda a complexidade do PHP, risco de novos tipos de bugs e custo de desenvolvimento e manutenção.”

A proposta de incluir o JIT no PHP 8 foi aprovada com 50 a 2 votos.

PHP 8 está chegando no final deste ano. 🚀 Confira nosso mergulho profundo nas novas funcionalidades!Click to Tweet

Melhorias e novas funcionalidades do PHP 8

Além do JIT, nós podemos esperar muitas funcionalidades e melhorias com o PHP 8. A lista a seguir é nossa seleção das próximas adições e mudanças que devem tornar o PHP mais confiável e eficiente.

Validação para Métodos de Traços Abstratos

Os traços são definidos como “um mecanismo para reutilização de código em linguagens de herança única, como PHP”. Tipicamente, eles são usados para declarar métodos que podem ser usados em múltiplas classes.

Uma característica também pode conter métodos abstratos. Estes métodos simplesmente declaram a assinatura do método, mas a implementação do método deve ser feita dentro da classe usando o traço.

De acordo com o manual PHP,

“Traços apoiam o uso de métodos abstratos para impor requisitos à classe expositora.”

Isto também significa que as assinaturas dos métodos devem coincidir. Em outras palavras, o tipo e o número de argumentos necessários precisam ser os mesmos.

De qualquer forma, de acordo com Nikita Popov, autora do RFC, a validação da assinatura atualmente só é aplicada de forma pontual:

O seguinte exemplo de Nikita se refere ao primeiro caso (assinatura não forçada):

trait T {
	abstract public function test(int $x);
}
 
class C {
	use T;

	// Allowed, but shouldn't be due to invalid type.
	public function test(string $x) {}
}

Dito isto, esta RFC se propõe a lançar sempre um erro fatal se o método de implementação não for compatível com o método do traço abstrato, independentemente de sua origem:

Fatal error: Declaration of C::test(string $x) must be compatible with T::test(int $x) in /path/to/your/test.php on line 10

Esta RFC foi aprovada por unanimidade.

Assinaturas Incompatíveis do Método

No PHP, erros de herança devido a assinaturas de métodos incompatíveis lançam um erro fatal ou um aviso, dependendo do que está causando o erro.

Se uma classe está implementando uma interface, assinaturas de métodos incompatíveis lançam um erro fatal. De acordo com a documentação das Interfaces de Objetos:

“A classe implementando a interface deve utilizar uma assinatura de método compatível com LSP (Liskov Substitution Principle)”. Não fazer isso resultará em um erro fatal.”

Aqui está um exemplo de um erro de herança com uma interface:

interface I {
	public function method(array $a);
}
class C implements I {
	public function method(int $a) {}
}

No PHP 7.4, o código acima lançaria o seguinte erro:

Fatal error: Declaration of C::method(int $a) must be compatible with I::method(array $a) in /path/to/your/test.php on line 7

Uma função em uma classe infantil com uma assinatura incompatível lançaria um aviso. Veja o seguinte código da RFC:

class C1 {
	public function method(array $a) {}
}
class C2 extends C1 {
	public function method(int $a) {}
}

No PHP 7.4, o código acima simplesmente lançaria um aviso:

Warning: Declaration of C2::method(int $a) should be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

Agora, esta RFC se propõe a sempre lançar um erro fatal para assinaturas de métodos incompatíveis. Com o PHP 8, o código que vimos acima iria provocar o seguinte:

Fatal error: Declaration of C2::method(int $a) must be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

Matrizes ”Arrays” começando com um índice negativo

No PHP, se uma matriz começa com um índice negativo (start_index < 0), os seguintes índices começarão a partir de 0 (mais sobre isso na documentação do array_fill). Veja o exemplo a seguir:

$a = array_fill(-5, 4, true);
var_dump($a);

No PHP 7.4 o resultado seria o seguinte:

array(4) {
	[-5]=>
	bool(true)
	[0]=>
	bool(true)
	[1]=>
	bool(true)
	[2]=>
	bool(true)
}

Agora, esta RFC propõe mudar as coisas para que o segundo índice seja start_index + 1, qualquer que seja o valor do start_index.

No PHP 8, o código acima resultaria no seguinte array:

array(4) {
	[-5]=>
	bool(true)
	[-4]=>
	bool(true)
	[-3]=>
	bool(true)
	[-2]=>
	bool(true)
}

Com o PHP 8, matrizes começando com um índice negativo mudam seu comportamento. Leia mais sobre as incompatibilidades para trás na RFC.

Tipos de União 2.0

Tipos de União aceitam valores que podem ser de diferentes tipos. Atualmente, o PHP não oferece suporte a tipos de união, com exceção da sintaxe ?Type e do tipo especial iterable.

Antes do PHP 8, os tipos de união só podiam ser especificados em anotações phpdoc, como mostrado no exemplo a seguir da RFC:

class Number {
	/**
	 * @var int|float $number
	 */
	private $number;

	/**
	 * @param int|float $number
	 */
	public function setNumber($number) {
		$this->number = $number;
	}

	/**
	 * @return int|float
	 */
	public function getNumber() {
		return $this->number;
	}
}

Agora, o RFC tipos de Sindicato 2.0 propõe adicionar suporte a tipos de sindicatos em assinaturas de funções, para que não confiemos mais na documentação inline, mas definamos tipos de sindicatos com uma sintaxe T1|T2|... em vez disso:

class Number {
	private int|float $number;

	public function setNumber(int|float $number): void {
		$this->number = $number;
	}

	public function getNumber(): int|float {
		return $this->number;
	}
}

Como explicado por Nikita Popov no RFC,

“Apoiar tipos de união no idioma nos permite mover mais informações do tipo phpdoc para assinaturas de função, com as vantagens habituais que isso traz:

  • Os tipos são realmente aplicados, assim os erros podem ser pegos cedo.
  • Por serem aplicadas, é menos provável que as informações digitadas fiquem desatualizadas ou percam os casos de bordas.
  • Os tipos são verificados durante a herança, aplicando o Princípio de Substituição Liskov.
  • Os tipos estão disponíveis através do Reflection.
  • A sintaxe é muito menos “boilerplate-y” do que “phpdoc”.

Os tipos de União suportam todos os tipos disponíveis, com algumas limitações:

Você pode ler mais sobre os tipos de União V2 na RFC.

Você pode ler mais sobre os tipos de União V2 na RFC.

Ao passar um parâmetro de tipo ilegal, funções internas e funções definidas pelo usuário se comportam de forma diferente.

Funções definidas pelo usuário lançam um TypeError, mas funções internas se comportam de diversas formas, dependendo de várias condições. De qualquer forma, o comportamento típico é lançar um aviso e retornar null. Veja o seguinte exemplo no PHP 7.4:

var_dump(strlen(new stdClass));

Isto resultaria no seguinte aviso:

Warning: strlen() expects parameter 1 to be string, object given in /path/to/your/test.php on line 4
NULL

Se o strict_types estiver habilitado, ou se a informação do argumento especificar tipos, o comportamento seria diferente. Nesses cenários, o erro de tipo é detectado e resulta em um TypeError.

Esta situação levaria a uma série de problemas bem explicados na seção de questões do RFC.

Para remover estas inconsistências, esta RFC propõe fazer a análise interna dos parâmetros APIs para sempre gerar um ThrowError no caso de um parâmetro do tipo mismatch.

No PHP 8, o código acima apresenta o seguinte erro:

Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in /path/to/your/test.php:4
Stack trace:
#0 {main}
  thrown in /path/to/your/test.php on line 4

throw Expressão

Em PHP, throw é uma afirmação, portanto não é possível usá-lo em lugares onde apenas uma expressão é permitida.

Esta RFC propõe converter a declaração de throw em uma expressão para que ela possa ser usada em qualquer contexto onde as expressões são permitidas. Por exemplo, funções de seta, operador null coalesce, operadores ternários e elvis, etc.

Veja os seguintes exemplos da RFC:

$callable = fn() => throw new Exception();

// $value is non-nullable.
$value = $nullableValue ?? throw new InvalidArgumentException();
 
// $value is truthy.
$value = $falsableValue ?: throw new InvalidArgumentException();

Weak Maps

Um mapa fraco é uma coleção de dados (objetos) em que as chaves são fracamente referenciadas, o que significa que elas não são impedidas de serem coletadas.

O PHP 7.4 adicionou suporte a referências fracas como forma de reter uma referência a um objeto que não impede que o objeto em si seja destruído. Como apontado por Nikita Popov,

“As referências em bruto fracas são apenas de utilidade limitada por si mesmas e os mapas fracos são muito mais usados na prática. Não é possível implementar um mapa fraco eficiente em cima de referências fracas em PHP porque a capacidade de registrar uma callback de destruição não é fornecida.”

É por isso que este RFC introduz uma classe WeakMap para criar objetos a serem usados como chaves fracas de mapa que podem ser destruídas e removidas do mapa fraco se não houver mais referências ao objeto chave.

Em processos de longa duração, isso evitaria vazamentos de memória e melhoraria o desempenho. Veja o seguinte exemplo da RFC:

$map = new WeakMap;
$obj = new stdClass;
$map[$obj] = 42;
var_dump($map);

Com o PHP 8, o código acima produziria o seguinte resultado (veja o código em ação aqui):

object(WeakMap)#1 (1) {
	[0]=>
	array(2) {
		["key"]=>
		object(stdClass)#2 (0) {
		}
		["value"]=>
		int(42)
	}
}

Se você desajustar o objeto, a chave é automaticamente removida do mapa fraco:

unset($obj);
var_dump($map);

Agora o resultado seria o seguinte:

object(WeakMap)#1 (0) {
}

Para uma visão mais detalhada dos mapas Fracos, veja o RFC. A proposta foi aprovada por unanimidade.

Precisa de uma hospedagem rápida, segura e amigável ao desenvolvedor para seus sites? Kinsta é construído com desenvolvedores WordPress em mente e fornece muitas ferramentas e um poderoso painel de controle.
Confira os nossos planos

Vírgula de Rastreamento na Lista de Parâmetros

As vírgulas de rastreamento são vírgulas anexadas a listas de itens em diferentes contextos. O PHP 7.2 introduziu vírgulas de rastreamento em sintaxe de lista, o PHP 7.3 introduziu vírgulas de rastreamento em chamadas de função.

O PHP 8 agora introduz vírgulas de rastreamento em listas de parâmetros com funções, métodos e fechamentos, como mostrado no exemplo a seguir:

class Foo {
	public function __construct(
		string $x,
		int $y,
		float $z, // trailing comma
	) {
		// do something
	}
}

Esta proposta foi aprovada com 58 votos a 1 voto.

Allow ::class syntax nos objetos

Para buscar o nome de uma classe, podemos usar a sintaxe Foo\Bar::class syntax. Esta RFC propõe estender a mesma sintaxe aos objetos para que agora seja possível ir buscar o nome da classe de um determinado objeto, como mostrado no exemplo abaixo:

$object = new stdClass;
var_dump($object::class); // "stdClass"
 
$object = null;
var_dump($object::class); // TypeError

Com PHP 8, $object::class fornece o mesmo resultado que get_class($object). Se $object não é um objeto, ele lança uma exceção TypeError.

Esta proposta foi aprovada por unanimidade.

Atributos v2

Atributos, também conhecidos como anotações, são uma forma de metadados estruturados que podem ser usados para especificar propriedades de objetos, elementos ou arquivos.

Até o PHP 7.4, os doc-comments eram a única forma de adicionar metadados às declarações de classes, funções, etc. Agora, o Attributes v2 RFC introduz atributos para o PHP definindo-os como uma forma de metadados estruturados e sintáticos que podem ser adicionados a declarações de classes, propriedades, funções, métodos, parâmetros e constantes.

Os atributos são adicionados antes das declarações a que se referem. Veja os seguintes exemplos da RFC:

<<ExampleAttribute>>
class Foo
{
	<<ExampleAttribute>>
	public const FOO = 'foo';

	<<ExampleAttribute>>
	public $x;

	<<ExampleAttribute>>
	public function foo(<<ExampleAttribute>> $bar) { }
}

$object = new <<ExampleAttribute>> class () { };

<<ExampleAttribute>>
function f1() { }

$f2 = <<ExampleAttribute>> function () { };

$f3 = <<ExampleAttribute>> fn () => 1;

Atributos podem ser adicionados antes ou depois de um comentário em bloco de documentos:

<<ExampleAttribute>>
/** docblock */
<<AnotherExampleAttribute>>
function foo() {}

Cada declaração pode ter um ou mais atributos e cada atributo pode ter um ou mais valores associados:

<<WithoutArgument>>
<<SingleArgument(0)>>
<<FewArguments('Hello', 'World')>>
function foo() {}

Veja a RFC para uma visão mais profunda dos atributos PHP, casos de uso, e sintaxe alternativa. Note que Attributes v2 está atualmente pendente de implementação.

Novas Funções do PHP

O PHP 8 traz várias novas funções para a linguagem:

str_contains

Antes do PHP 8, strstr e strpos eram as opções típicas para desenvolvedores procurarem por uma agulha dentro de uma determinada string. O problema é que ambas as funções não são consideradas muito intuitivas e sua utilização pode ser confusa para novos desenvolvedores de PHP. Veja o exemplo a seguir:

$mystring = 'Managed WordPress Hosting';
$findme = 'WordPress';
$pos = strpos($mystring, $findme);

if ($pos !== false) {
	echo "The string has been found";
} else {
	echo "String not found";
}

No exemplo acima usamos o operador de comparação !==, que também verifica se dois valores são do mesmo tipo. Isto nos impede de obter um erro se a posição da agulha for 0:

“Esta função pode retornar FALSE Booleano, mas também pode retornar um valor não-Booleano que avalia para FALSE. […] Utilize o operador === para testar o valor de retorno desta função”.

Além disso, vários frameworks fornecem funções de ajuda para buscar um valor dentro de uma determinada string (veja a documentação do Laravel Helpers como exemplo).

Agora, esta RFC propõe a introdução de uma nova função que permite a busca dentro de uma string: str_contains.

str_contains ( string $haystack , string $needle ) : bool

Seu uso é bastante simples. str_contains cheques se $needle é encontrado em $haystack e retorna true ou false de acordo.

Então, graças ao str_contains, podemos escrever o seguinte código:

$mystring = 'Managed WordPress Hosting';
$findme   = 'WordPress';

if (str_contains($mystring, $findme)) {
	echo "The string has been found";
} else {
	echo "String not found";
}

O que é mais legível e menos propenso a erros (veja este código em ação aqui).
No momento desta escrita, str_contains é sensível a maiúsculas e minúsculas, mas isto pode mudar no futuro.

A proposta str_contains aprovada com 43 a 9 votos.

str_starts_with() e str_ends_with()

Além da função str_contains, duas novas funções permitem procurar por uma agulha dentro de uma determinada string: str_starts_with e str_ends_with.

Estas novas funções verificam se uma determinada string começa ou termina com outra string:

str_starts_with (string $haystack , string $needle) : bool
str_ends_with (string $haystack , string $needle) : bool

Ambas as funções retornam false se a $needle for maior que o $haystack.

De acordo com Will Hudgins, o autor deste RFC,

“O str_starts_with e str_ends_with funcionalidade é tão comumente necessário que muitos dos principais frameworks PHP o suportam, incluindo Symfony, Laravel, Yii, FuelPHP, e Phalcon“.

Graças a eles, agora poderíamos evitar o uso de funções sub-ótimas e menos intuitivas como substr, strpos. Ambas as funções são sensíveis a maiúsculas e minúsculas:

$str = "WordPress";
if (str_starts_with($str, "Word")) echo "Found!";

if (str_starts_with($str, "word")) echo "Not found!";

Você pode ver este código em ação aqui.

Este RFC foi aprovado com 51 a 4 votos.

get_debug_type

get_debug_type é uma nova função PHP que retorna o tipo de uma variável. A nova função funciona de forma bastante similar à função get_debug_type, mas get_debug_type retorna nomes de tipos nativos e resolve nomes de classes.

Isso é uma boa melhoria para o idioma, pois gettype() não é útil para a verificação de tipo.

A RFC fornece dois exemplos úteis para entender melhor a diferença entre a nova função get_debug_type() e gettype(). O primeiro exemplo mostra gettype at work:

$bar = [1,2,3];

if (!($bar instanceof Foo)) { 
	throw new TypeError('Expected ' . Foo::class . ', got ' . (is_object($bar) ? get_class($bar) : gettype($bar)));
}

Com o PHP 8, nós poderíamos usar o get_debug_type, ao invés disso:

if (!($bar instanceof Foo)) { 
	throw new TypeError('Expected ' . Foo::class . ' got ' . get_debug_type($bar));
}

A tabela a seguir mostra os valores de retorno do get_debug_type e gettype:

Valor gettype() get_debug_type()
1 integer int
0.1 double float
true boolean bool
false boolean bool
null NULL null
“WordPress” string string
[1,2,3] array array
Uma aula com o nome “Foo\Bar” object Foo\Bar
Uma aula anônima object [email protected]

RFCs adicionais

No momento da redação deste texto, vários RFCs direcionados para o PHP 8 ainda estão em rascunho e/ou pendentes de implementação. Nós os adicionaremos assim que seu status mudar para “Implementado”.

Aqui está uma lista rápida de melhorias adicionais aprovadas que farão parte do PHP 8:

  1. Interface Stringable: esta RFC introduz uma interface Stringable que é automaticamente adicionada às classes que implementam o método __to String(). O objetivo principal aqui é usar o tipo string|Stringable union.
  2. Novas APIs DOM Living Standard em ext/dom: este RFC propõe implementar o DOM Living Standard atual para a extensão DOM PHP, introduzindo novas interfaces e propriedades públicas.
  3. Tipo de retorno estático: O PHP 8 introduz o uso de static como tipo de retorno ao lado dos tipos self e parent.
  4. Tweaks de sintaxe variável: esta RFC resolve algumas inconsistências residuais na sintaxe variável do PHP.
O PHP 8 está chegando no final deste ano e vai trazer muitas mudanças e melhorias. 🚀 Confira nosso mergulho profundo nas novas funcionalidades!Click to Tweet

Resumo

Que passeio! Neste post, nós cobrimos todas as principais mudanças e melhorias esperadas com o lançamento do PHP 8. O mais esperado certamente é o compilador Just in Time, mas há muito mais vindo com o PHP 8.

Certifique-se de marcar este post no blog, pois adicionaremos nossos favoritos à lista assim que eles forem aprovados. 🤓

Agora é a sua vez: você está pronto para testar as próximas funcionalidades do PHP? Qual delas é a sua favorita? Deixe uma linha na seção de comentários abaixo.


Economize tempo, custos e otimize o desempenho do seu site com:

  • Ajuda instantânea de especialistas em hospedagem do WordPress, 24/7.
  • Integração do Cloudflare Enterprise.
  • Alcance global com 28 centros de dados em todo o mundo.
  • Otimização com nosso monitoramento integrado de desempenho de aplicativos.

Tudo isso e muito mais em um plano sem contratos de longo prazo, migrações assistidas e uma garantia de 30 dias de devolução do dinheiro. Confira nossos planos ou entre em contato com as vendas com as vendas para encontrar o plano certo para você.