PHP 8 - Nuevas características, mejoras y problemas probables con WordPress

Marten Gülink Última actualización 11.01.2021
10 min.
Actualización importante de php 8
Última actualización 11.01.2021


¡PHP 8 ya está aquí! La gran actualización fue lanzada el 26 de noviembre de 2020 y nos trae algunos cambios fundamentales, así como muchas características nuevas. Nuestro desarrollador Marten explica en qué caso PHP 8 realmente conduce a un mejor rendimiento y si deberías actualizar ya a la nueva versión como usuario WordPress.

Introducción en PHP 8 

PHP 8 fue presentado por primera vez a sus probadores alfa el 18 de junio de 2020 y se ha encontrado desde julio en una fase de "congelación" de características. Por ello, no se permitieron nuevas incorporaciones hasta el lanzamiento del 26 de noviembre. Una característica única de esta versión es que saltamos PHP 7.5 y pasamos directamente a PHP 8. Y este salto viene con un montón de características. 

Una de las preguntas más comunes sobre PHP 8 que probablemente se hacen los usuarios WordPress es: ¿Mejorará PHP 8 el rendimiento de mi sitio web?

La respuesta a esta pregunta es (como tantas veces): "Depende...".

Cuando se actualizó PHP de la versión 5 a la 7, se produjo un enorme aumento del rendimiento. Con PHP 8, sin embargo, no notarás ninguna mejora en el rendimiento general a menos que tu aplicación calcule muchas funciones matemáticas (consulta nuestra sección sobre JIT-Compiler). Esto se debe principalmente a que la optimización del código de PHP ya está muy bien establecida.

¿Pero quién dice que el rendimiento se limita al tiempo de compilación? Por mi parte, como desarrollador, mediría el rendimiento de varias maneras, incluyendo las características de las que dispongo para escribir un código bien estructurado. Y PHP 8 está lleno de novedades. Así que, ¡comencemos!

Las novedades más importantes de PHP 8 

PHP 8 tiene ocho nuevas características importantes que me gustaría presentarte brevemente: 

  1. JIT Compiler 
  2. Atributos
  3. Argumentos con nombre (Named Arguments)
  4. Términos que coinciden (Match Expressions) 
  5. Expresiones "throw"
  6. Static Return Type 
  7. Union Type 
  8. Mixed Types 

El compilador JIT (just-in-time)(rfc)

Cuando se ejecuta el código PHP, normalmente se hace compilando a instrucciones virtuales que se ejecutan en una máquina virtual. JIT cambiará esto compilando el código en código máquina x86 y ejecutando ese código directamente en la CPU. Para las aplicaciones que dependen en gran medida de funciones matemáticas, esto debería suponer un aumento del rendimiento. Sin embargo, esto no es lo que se espera de las aplicaciones web medias (v. el gráfico). 

PHP 8 - Nuevas características, mejoras y problemas probables con WordPress
Fuente

Para ver un ejemplo de las ganancias de rendimiento que se pueden conseguir con el JIT, lo mejor es ver el siguiente vídeo.

YouTube

Al cargar el vídeo, acepta la política de privacidad de YouTube.
Más información

Cargar vídeo

PGlmcmFtZSBsb2FkaW5nPSJsYXp5IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUtbm9jb29raWUuY29tL2VtYmVkL2RXSDY1cG1uc3JJIiBhbGxvdz0iYWNjZWxlcm9tZXRlcjsgYXV0b3BsYXk7IGNsaXBib2FyZC13cml0ZTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuPSIiIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBmcmFtZWJvcmRlcj0iMCI+PC9pZnJhbWU+

Básicamente, se reduce al hecho de que tu aplicación funciona con mayor fluidez con la nueva versión si se utiliza PHP para una tarea matemática intensiva. Pero si usas PHP como la mayoría de usuarios WordPress, no notarás mucho el cambio. A continuación, explico más sobre lo que significa PHP 8 para propietarios/as de sitios web WordPress. 

Pasemos a las nuevas características:

Attributes v2(rfc, rfc)

Una de las nuevas características de PHP 8 (que ha dado lugar a un gran debate en la comunidad PHP) son los atributos, conocidos también como "annotations" en muchos otros idiomas. Los atributos reemplazan la necesidad de almacenar metadatos con docblocks en PHP 8. Antes había que recurrir a esto para declarar los metadatos de las clases, métodos, funciones y argumentos de forma estructurada. 

Como puedes imaginar, utilizar los comentarios del código para aplicar los metadatos no era lo ideal, pero funcionaba. Afortunadamente, ahora no tendremos ese problema. 

Los atributos pueden anuaciarse introduciendo Syntax #[...] .

A continuación se presentan algunos ejemplos de la RFC sobre cómo se pueden aplicar los atributos a diferentes tipos de datos.

#[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;

Llegados a este punto, cabe destacar que la RFC para los atributos ha sufrido una serie de cambios desde su concepción original, lo que demuestra el esfuerzo y la reflexión que se han llevado a cabo en esta actualización. 

Named Arguments (rfc)

Losargumentos con nombre te dan más flexibilidad a la hora de solicitar funciones. Hasta ahora, había que invocar una función y pasar cada argumento en el orden especificado por la función. 

// Using positional arguments:
array_fill(0, 100, 50);

Los argumentos con nombre (named arguments) permiten definir un nombre para cada parámetro. Y ahora pueden ser llamados fuera de orden, como se describe a continuación: 

// Using named arguments:
array_fill(start_index: 0, num: 100, value: 50);

También pueden solicitarse de la siguiente manera:

array_fill(value: 50, num: 100, start_index: 0);

También es posible un híbrido de los dos, que permite combinar parámetros con nombre y argumentos posicionales, mejorando la legibilidad del código: 

htmlspecialchars($string, double_encode: false);

Match Expressions (rfc)

Con las expresiones o términos coincidentes, match expressions, se pretende resolver algunos problemas existentes relativo a la funcionalidad de su predecesor, Switch. 

Comparison Operator

Switch utiliza un operador relacional de conversión de tipo (==) que puede causar problemas. En cambio, Match utiliza un operador de comparación estricto (===), independiente de strict_types.

Return Value

Las órdenes de Switch a menudo crean un valor que se necesita más adelante en el flujo del programa. Puede ocurrir que este valor no se establezca en la orden switch, lo que posteriormente puede dar lugar a problemas en el script PHP. Además, la sintaxis de la orden switch dificulta la lectura de las órdenes switch entrelazadas.

switch (1) {
    case 0:
        $y = 'Foo';
        break;
    case 1:
        $y = 'Bar';
        break;
    case 2:
        $y = 'Baz';
        break;
}
 
echo $y;
//> Bar

La nueva expresión de coincidencia elimina este problema asignando el valor de retorno directamente para cada rama de coincidencia(=>), lo que es más intuitivo. 

echo match (1) {
    0 => 'Foo',
    1 => 'Bar',
    2 => 'Baz',
};
//> Bar

Fallthrough

Si una orden switch no tiene un break después de cada caso, continuará con el siguiente caso aunque el código se rompa. Esto fue diseñado así para permitir que las funciones de conmutación ejecuten múltiples bloques de código en secuencia. Sin embargo, esta ha sido una fuente común de errores. 

Match ha implementado una ruptura implícita después de cada rama (=>). Ahora se pueden ejecutar múltiples condiciones colocando comas entre cada una de ellas: 

match ($x) {
    1, 2 => {
        // Same for 1 and 2
    },
    3, 4 => {
        if ($x === 3) {
            // Only 3
        }
        // Same for 3 and 4
    },
}

Throw expressions (rfc)

En PHP 8, la orden throw se ha convertido en una expresión. Esto significa que, técnicamente, el lanzamiento puede devolver un valor. Esto es útil en el sentido de que ahora se puede utilizar el lanzamiento en muchos más lugares, como las funciones de flecha o los operadores de coalescencia. 

Arrow Functions: 

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

Coalesce Operators: 

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

Ternary Operators:

// $value is only set if the array is not empty.
$value = !empty($array)
    ? reset($array)
    : throw new InvalidArgumentException();

Static Return Type (rfc)

Tal y como indica esta RFC, el static return type permite la devolución del nombre de clase especial "static" desde un método: “The static special class name in PHP refers to the class a method was actually called on, even if the method is inherited. This is known as “late static binding” (LSB). This RFC proposes to make static also usable as a return type (next to the already usable self and parent types).”

Static en cambio no puede utilizarse como parte de un parámetro en este caso. El retorno estático se referirá a la clase que fue invocada. 

Union Types (rfc)

Tipos de sindicatos te permiten declarar el tipo de valor que esperas de una entrada. En algunos idiomas, esto se conoce como "schema" o esquema. Esto se hace sintácticamente utilizando  | (por ejemplo string|array|int) definida. Pero la magia no se acaba ahí, porque también puedes utilizar clases definidas como:

class MyClass {

}
function myFunction(string|array|int|MyClass){

}

Los tipos de unión (union types) ya se utilizan en PHP. Sin embargo, se implementan utilizando el método de anotaciones phpdoc, como se muestra a continuación. 

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;
    }
}

Para obtener un poco más de contexto sobre el uso, consulta este ejemplo de la RFC:

class Number {
    private int|float $number;
 
    public function setNumber(int|float $number): void {
        $this->number = $number;
    }
 
    public function getNumber(): int|float {
        return $this->number;
    }
}

Todo esto se reduce al hecho de que se pueden utilizar varios tipos de entrada para la misma función en lugar de uno solo, lo que permite un mayor grado de reutilización del código.

Mixed Types (rfc)

En versiones recientes de PHP era posible declarar el tipo esperado de datos de entrada y de retorno. Sin embargo, PHP no siempre soportaba los tipos, y esto es un problema. En algunos casos, se ha omitido un tipo o simplemente se ha olvidado.Mix Typesintenta ahora resolver este problema.

Un mixed sería el equivalente a array|bool|callable|int|float|null|object|resource|string

He aquí un ejemplo de documentación del RFC de cómo se utiliza:

// Valid example
 
class A
{
    public function foo(int $value) {}
}
 
class B extends A
{
    // Parameter type was widened from int to mixed, this is allowed
    public function foo(mixed $value) {}
}

Funciones adicionales de PHP 8

Make Sorting Stable (rfc)

La estabilidad se añade a todas las funciones que entran en el ámbito de Sort (por ejemplo.

sort, rsort, usort, asort, arsort, uasort, ksort, krsort, uksort, array_multisort).

Recomiendo que leas esto en la documentación de RFC y lo compares con tu aplicación, ya que la modificación de esta funcionalidad de sorting inestable a estable podría afectar negativamente a tu código.

Constructor Property Promotion (rfc)

Esta función debería ayudar a acelerar el flujo de trabajo de desarrolladores/as y a reducir los errores. En la actualidad, la definición de un objeto de valores requiere un conjunto de plantillas, como se muestra a continuación en la documentación de la RFC:

class Point {
    public float $x;
    public float $y;
    public float $z;
 
    public function __construct(
        float $x = 0.0,
        float $y = 0.0,
        float $z = 0.0,
    ) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;
    }
}

En este método, las propiedades deben repetirse tres veces. La mejora a esto es la fórmula corta que se muestra a continuación: 

class Point {
    public function __construct(
        public float $x = 0.0,
        public float $y = 0.0,
        public float $z = 0.0,
    ) {}
}

Nullsafe Operator (rfc)

Hay un nuevo operador en este bloque. 

Anstelle des klassischen <code>!== null</code> haben wir nun das bekommen: <code>?-></code>. Es scheint zunächst merkwürdig, aber wenn man es unter dem Gesichtspunkt der Verkettung von “if-Statements” betrachtet, dann wird die Anwendung ziemlich deutlich: 

$country =  null;
 
if ($session !== null) {
    $user = $session->user;
 
    if ($user !== null) {
        $address = $user->getAddress();
 
        if ($address !== null) {
            $country = $address->country;
        }
    }
}
 
// do something with $country
$country = $session?->user?->getAddress()?->country;
 
// do something with $country

str_contains (rfc)

Esta nueva función, bastante agradable, devuelve un valor booleano (verdadero/falso) si una cadena se encuentra en otra cadena. Toma dos argumentos, la cadena que va a buscarse y la que debe buscarse.

str_contains('php8', '8'); // true
str_contains('php8', 'wordpress'); // false

Para obtener filtros de cadena aún más útiles, consulta estas nuevas funciones:

str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true

Ambas devolverán un resultado booleano y funcionan de la misma manera que str_contains().

Weak Maps (rfc)

En PHP, cuando se establece una variable con el valor de un objeto, normalmente se crea una referencia a ese objeto, pero no un nuevo objeto. 

Así que en este caso, puedes acabar teniendo muchas referencias a un objeto, pero solo un objeto. El problema con esto es el siguiente: cuando llegue el momento de borrar tal objeto, PHP contará el número de referencias que tiene el mismo. Y si es más de uno, PHP se negará a borrar ese objeto. 

Weak Maps resuelve este problema creando una referencia "débil" al objeto correspondiente. Una vez eliminado el objeto, todas las variables con la referencia Weak Maps a ese objeto se ponen a cero. 

Non-capturing Catches (rfc)

Un bloque try-catch ya es bastante impresionante cuando se trata de informar de errores y ahora hay una forma aún más rápida de implementarlo. Y no, esto no afectará realmente a la legibilidad. 

En la "vieja escuela" esto significaba que tenías tú mismo/a que pasar tu catch exception a una variable como esta:

function catchMeWhenIFall(){
	try {
        throw new Exception('NOPE - GRAVITY');
    } catch (Exception $e) {
        return $e->getMessage();
    }

}

Pero ahora no necesitas definir la variable para pasarla a tu bloque de captura.

try {
	throw new Exception('FOO!');
 catch  (){
	//Do some code here
 }

}

Más material de lectura sobre PHP 8

Si quieres saber más sobre el lanzamiento de PHP 8 o ver los ejemplos de código RFC por ti mismo/a, solo tienes que echarle un vistazo al anuncio oficial del lanzamiento

¿Estás preparado/a para PHP 8? 

Ningún/a desarrollador/a es partidario/a de las actualizaciones con grandes cambios (recordemos WordPress 5.0 y Gutenberg), donde se corre el riesgo de que se rompa tu código y tengas que esperar horas de trabajo a una reconstrucción completa. Sin embargo, si tu código ya funcionaba limpiamente con PHP 7.4, no deberías tener ningún problema con PHP 8 (más sobre PHP y WordPress en el próximo capítulo). 

Sin embargo, si estás ejecutando una versión anterior de PHP, debes comprobar la lista de características obsoletas antes de actualizar. Consulta la documentación de los "Apéndices" de PHP para obtener una lista completa de las características anteriores, los cambios y los problemas al actualizar de una versión de PHP a la siguiente. 

¿Deberías actualizar tu WordPress a PHP 8? 

Para las bases de código bien tipificadas o que se han mantenido al día con las últimas versiones de PHP, no hay un gran problema [para migrar a PHP 8]. La realidad, sin embargo, es que WordPress no es una base de código de este tipo.

Omar Reiss, yoast

Esta cita del informe de compatibilidad de Yoast "“WordPress and PHP 8 Compatibility Report” ya sugiere que tú, como usuario WordPress, no deberías tratar la actualización a PHP 8 a la ligera. La conclusión del informe refuerza esta suposición, como escribe Omar Reiss: "con solo investigar un subconjunto de cambios de ruptura en PHP 8 ya pudimos confirmar que es probable que esto cause una ruptura importante en los sitios con un origen poco claro de esa ruptura. A menudo el error se produce en un lugar, pero es causado por un plugin o theme en un lugar diferente, lo que hace que estos problemas sean difíciles de depurar".

Estos problemas de compatibilidad son también una razón por la que PHP 8 no está disponible inmediatamente para nuestros clientes en el panel de control de RAIDBOXES. Especialmente después de las grandes actualizaciones, siempre tiene sentido darle a los desarrolladores/as de plugin el tiempo suficiente para posibles ajustes y esperar por el momento. Tan pronto como podamos estar seguros de que no hay problemas con una instalación estándar WordPress y que PHP 8 se ejecuta de forma estable y con un buen rendimiento en nuestro sistema, por supuesto que haremos que PHP 8 esté disponible.

Si ya tienes acceso a PHP 8 y quieres probar la nueva versión con tu sitio web WordPress, deberías, como antes de cada actualización, crear primero una copia de seguridad. Cómo probar correctamente una nueva versión de PHP en RAIDBOXES lo descubrirás en este artículo del centro de ayuda (aquí usando PHP 7.2 como ejemplo).

Nuestra conclusión

PHP 8 es un gran paso adelante respecto a sus predecesores. Si bien es posible que no veas una mejora dramática en el rendimiento de inmediato (dependiendo de cómo utilices PHP 8), deberías considerar la actualización, al menos después de que la hayas probado, sea estable y esté disponible en su hoster WordPress. La nueva versión es una progresión natural, y al implementarla estarás sentando una base sólida para futuras mejoras, crecimiento y rendimiento.

¿Más preguntas sobre PHP 8?

Espero haber podido presentarte las nuevas y emocionantes características de PHP 8 con este artículo. ¿Tienes más preguntas sobre el tema? No dudes en utilizar la función de comentarios. ¿Quieres más consejos sobre WordPress, diseño web y demás? Entonces síguenos en Twitter, Facebook o a través de nuestra newsletter.

Como desarrollador web en RAIDBOXES, Marten siempre está trabajando en nuevas características para nuestros clientes. En "wp unboxed" destaca por sus conocimientos sobre desarrollo web, WordPress y nuestro panel de control. En su tiempo libre le gusta ocuparse de autogestiones relacionadas con el hosting y de las últimas tendencias en internet.

Artículos relacionados

Comentarios sobre este artículo

Escribe un comentario

Tu dirección de correo electrónico no se publicará. Los campos obligatorios están marcados con *.