PHP 8.3: Las Novedades que Cambian Cómo Escribes PHP

PHP 8.3 ya está aquí y trae unas cuantas mejoras que merecen la pena. Estas son las novedades que más me han llamado la atención.

Novedades destacadas de PHP 8.3

Tipado en constantes

A partir de ahora puedes definir constantes de clase con su tipo de dato. Por ejemplo:

Antes:

class Foo
{
    public const FOO = 1;
}

class Bar extends Foo
{
    public const FOO = 'foo';
}

Ahora:

class Foo
{
    public const int FOO = 1;
}

class Bar extends Foo
{
    public const int FOO = 'foo'; // Esto daría un fatal error por el tipo de dato
}

Recuperación de constantes de forma dinámica

Ahora puedes recuperar el valor de una constante de forma dinámica muy fácilmente:

Antes:

class Foo {
    const TEST = 'test';
}

$constant = 'TEST';

$value = constant(Foo::class . "::{$constant}");

Ahora:

class Foo {
    const TEST = 'test';

}

$constant = 'TEST';

$value = Foo::{$constant};

Nuevo atributo #[Override]

Uno de esos detalles que parecen menores y te ahorran horas de depuración. Marcas un método con #[Override] y PHP te avisa con un error si en la clase base no existe el método que crees que estás sobreescribiendo. Se acabó descubrir a las dos semanas que escribiste taerDown en vez de tearDown.

Antes:

use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase {
    protected $logFile;

    protected function setUp(): void {
        $this->logFile = fopen('/tmp/logfile', 'w');
    }

    protected function taerDown(): void {
        fclose($this->logFile);
        unlink('/tmp/logfile');
    }
}

// The log file will never be removed, because the
// method name was mistyped (taerDown vs tearDown).

Ahora:

use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase {
    protected $logFile;

    protected function setUp(): void {
        $this->logFile = fopen('/tmp/logfile', 'w');
    }

    #[\Override]
    protected function taerDown(): void {
        fclose($this->logFile);
        unlink('/tmp/logfile');
    }
}

// Fatal error: MyTest::taerDown() has #[\Override] attribute,
// but no matching parent method exists

Modificar propiedades readonly únicamente en el clonado

Ahora puedes modificar propiedades readonly únicamente en el clonado de un objeto. Esto es útil para objetos inmutables.

Ejemplo:

readonly class Quote {
    public function __construct(
        ...
        public DateTime $createdAt,
        ...
    ) {}

    public function __clone() {
        $this->createdAt = new DateTime();
        // Esto ahora se puede hacer.
    }
}

Nuevo método json_validate()

Por fin tenemos un método para validar si un json es correcto o no.

Ejemplo:

$isValid = json_validate('{"test":{"test":"test"}}');

Continuación de los índices negativos

Antes, cuando creabas un array con un índice negativo, el siguiente índice era 0. Ahora continúa la secuencia de índices negativos.

Antes:

$array = [];
$array[-3] = 'test';
$array[] = 'test2';

//Generaba:
//[
//    -3 => 'test',
//    0 => 'test2',
//]

Ahora:

$array = [];
$array[-3] = 'test';
$array[] = 'test2';

//Genera:
//[
//    -3 => 'test',
//    -2 => 'test2',
//]

Clases anónimas readonly

Antes no se podían crear clases anónimas readonly, pero ahora sí.

Ejemplo:

$object = new readonly class() {
    ....
};

Conclusión

Estas son las novedades que más me han llamado la atención de la nueva versión de PHP. ¿Y a ti? ¿Qué te parecen? ¿Vas a actualizar a la nueva versión?

Puedes consultar más información en la web oficial y en stitcher.io.

PD: Si tenéis cualquier duda podéis poneros en contacto conmigo enviando un DM por twitter.

Luis Miguel Martín
Luis Miguel Martín

CTO en LCApps. Escribo sobre Claude Code, MCP, agentes IA y arquitectura de software real.

💡

¿Te ha gustado este artículo?

Explora más artículos sobre desarrollo, buenas prácticas y herramientas.