La octava versión de PHP no se espera hasta finales de noviembre de 2020, pero ya podemos ir echándole un ojo y ponernos los dientes largos con algunas de las novedades.

PHP 8 será una major release y por tanto traerá muchos cambios que no serán retrocompatibles y que nos obligarán a actualizar nuestro código. Aun así, con todo y con eso, todo apunta a que merecerá la pena.

Algunos de los cambios como un nuevo compilador JIT, mejoras de rendimiento y nuevas características para hacer nuestro código más legible y cómodo hacen que muchos (entre los que me incluyo) estemos deseando que llegue ya el momento de dar el salto.

Antes de empezar, he decidido dejar de traducir algunos términos del inglés al español ya que, o la traducción es más dificil de entender que el própio término anglosajón o directamente no hay una forma de traducirlo sin describirlo. Todos somos programadores y estamos acostumbrados a este tipo de términos, espero.

Nuevas características de PHP 8

JIT

JIT, del inglés just in time, promete grandes mejores en rendimiento aunque no esté pensado para trabajar siempre con una petición web. No hay aún pruebas de rendimientos oficiales que avalen esta gran mejora, pero eso es todo lo que nos han dicho hasta ahora.

La diferencia con este compilador es que es capaz de compilar partes del código, durante la ejecución de este, para usar luego este código compilado ahorrando así tiempo y memoria. Sería algo así como una versión compilada y cacheada del código.

Aquí hay una pequeña prueba de las diferencias de rendimiento que, a simple vista, son evidentes.

Union types

En PHP 7 se introdujo el tipado en los parámetros de entrada y salida de las funciones pero, dado que PHP es un lenguaje dinámico muchas veces nos veíamos obligados a no ponerlo por que las funciones podían devolver varios tipos.

Ahora en PHP 8 puedes especificar directamente que tipo de respuestas o parámetros son aceptables y cuales no.

public function foo(Foo|Bar $input): int|float;

Hay que tener en cuenta que el void nunca podrá estar concatenado con otro tipado, ya que indica que no hay ninguna salida y en caso de ser una respuesta o parámetro opcional podremos seguir usando el interrogante o añadir implícitamente el tipo null.

public function foo(?Foo $input): int|null;

Named argumentos

Desde esta versión en adelante podremos nombrar los parámetros cuando llamemos a una función cómo pasa en otros lenguajes de programación.

function greet(string $name, string $surname)
{
	echo "$name $surname";
}

greet(name: "Víctor", surname: "Falcón"); // Víctor Falcón

greet(surname: "Falcón", name: "Víctor"); // Víctor Falcón

Attributes

Estos nuevos attributes o annotations nos dan una forma de añadir metadatos a nuestras clases sin tener que parsear un PHPDoc completo.

use App\Attributes\ExampleAttribute;

@@ExampleAttribute
class Foo
{
    @@ExampleAttribute
    public const FOO = 'foo';
 
    @@ExampleAttribute
    public $x;
 
    @@ExampleAttribute
    public function foo(@@ExampleAttribute $bar) { }
}
@@Attribute
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}

Expresión Match

Es una alternativa al conocido switch con muchas ventajas y mejoras.

$person = 1;

$name = match($person) {
	1 => "Víctor",
	2 => "Antonio",
	default => "Unnamed"
}

// name = "Víctor"

Esta expresión es más legible, nos ahorra el break y además nos permite devolver un valor. Sinceramente, la voy a usar muchísimo.

Cómo curiosidad, el match funciona con tipos estrictos por tanto, si no coincide, siempre acabará en el default, en caso de que haya.

$person = "1";

$name = match($person) {
	1 => "Víctor",
	2 => "Antonio",
	default => "Unnamed"
}

// name = "Unnamed" 

Promoción de propiedades del constructor

De este cambio en concreto hablé en más profundidad en este artículo. A partir de ahora nuestros constructores pasarán de:

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

A esto otro:

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

Nuevo tipo static

Ya teníamos disponible el tipo self y ahora se añade, además, el static.

class Foo
{
    public function test(): static
    {
        return new static();
    }
}

Nuevo tipo mixed

En ocasiones este tipo de inclusiones son algo así como un comodín que acaba volviéndose en nuestra contra molestando más de lo que nos ayuda, personalmente evitaría usarlo, pero ahora podremos definir entradas y salidas de funciones como mixed.

Al final, con el cambio anterior de poder definir varios tipos, en ocasiones usar este mixed nos ahorrará concatenar muchos tipos.

Este tipo incluye los siguientes parámetros:

  • array
  • bool
  • callable
  • int
  • float
  • null
  • object
  • resource
  • string

Coma final en los parámetros de las funciones

Ahora es posible añadir una coma al final de la última propiedad de nuestros métodos. Igual que hacíamos en los arrays.

public function(
    string $parameterA,
    int $parameterB,
    Foo $objectfoo,
) {
    // …
}

Cambios en la expresión throw

Ahora pasa de ser una declaración a una expresión por lo que podremos hacer cosas como esta:

$triggerError = fn () => throw new MyError();

$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');

Y estos no son los únicos cambios que traerá esta versión de PHP, pero si son los que me han parecido más interesantes. ¡Algunos de ellos los espero con mucha ansia 😍!