---
title: 'PHP 8.3: Typed Constants, #[Override], json_validate & Upgrade Notes | DevSense'
description: 'Guía de PHP 8.3 desde 8.2: #[Override], constantes de clase tipadas, clonación de propiedades readonly, json_validate, str_increment/str_decrement, validación de range().'
faq:
    - { question: '¿Qué hace el atributo #[Override] en PHP 8.3?', answer: 'El atributo #[Override] marca un método que debe sobrescribir un método padre o una declaración de interfaz. Si el método padre se renombra o elimina, PHP genera un Fatal Error en tiempo de compilación.' }
    - { question: '¿Cómo funcionan las Constantes de Clase Tipadas en PHP 8.3?', answer: 'Las constantes de clase, interfaz, trait y enum ahora pueden declarar tipos específicos (como string, int, bool, float o array). Los valores asignados deben coincidir estrictamente con este tipo en tiempo de compilación.' }
    - { question: '¿Cuál es el beneficio de json_validate() en PHP 8.3?', answer: 'json_validate() comprueba si una cadena es un JSON válido sin decodificarla, ahorrando una sobrecarga significativa de CPU y memoria en comparación con json_decode() para comprobaciones de validación.' }
    - { question: '¿Cómo cambia la clonación de propiedades readonly en PHP 8.3?', answer: 'Las propiedades readonly ahora se pueden reinicializar dentro del método `__clone()`, lo que facilita la clonación profunda y la modificación de estructuras inmutables.' }
published: '2026-05-31'
---
# PHP 8.3: Características Principales

Una versión de refinamiento para equipos en PHP 8.2.x: invariantes más fuertes (`#[Override]`, constantes tipadas), mejor ergonomía de JSON y cadenas (`json_validate`, `str_increment`/`str_decrement`), y una larga cola de pequeños cambios en tiempo de ejecución que se muestran bajo carga o en rutas de código de casos extremos.

## Índice
* [`#[\Override]` — detectar sobrescrituras faltantes en tiempo de compilación](#override-attribute)
* [Constantes de clase tipadas](#typed-constants)
* [Readonly: clases anónimas y clonación](#readonly-tweaks)
* [Calidad de vida del lenguaje](#language-qol)
* [Nuevas funciones que vale la pena adoptar (`json_validate`, `str_*`, DOM, Random)](#new-functions)
* [Cambios incompatibles con versiones anteriores (notas de migración)](#backward-incompatible)
* [Depreciaciones (incrementar/decrementar cadenas, `get_class()`, configuración INI de assert)](#deprecations)
* [Otros cambios y operaciones (gc_status, streams, aspectos destacados)](#other-changes)
* [Errores Comunes](#common-mistakes)
* [Quiz de Autoevaluación](#self-test-quiz)

---

PHP 8.3 se centra en reforzar la seguridad de los contratos y optimizar el consumo de recursos. Al introducir constantes de clase tipadas y el atributo `#[\Override]`, PHP hace que la refactorización sea más segura y evita desviaciones silenciosas de la API. Para los desarrolladores que manejan APIs de alto tráfico, la nueva función `json_validate()` introduce una forma ligera de comprobar payloads sin desperdiciar memoria en el análisis. Sin embargo, estas mejoras se unen a reglas de validación más estrictas en toda la biblioteca estándar (especialmente en `range()` y funciones de socket), y la depreciación de los comportamientos heredados de incremento de cadenas. Aquí tiene cómo actualizar sus aplicaciones sin problemas.

<a id="override-attribute"></a>
## `#[\Override]` — detectar sobrescrituras faltantes en tiempo de compilación

Marque los métodos que están destinados a sobrescribir un padre o interfaz. Si el nombre es incorrecto o el padre elimina el método, **PHP falla temprano** en lugar de introducir silenciosamente un nuevo método.

> [!NOTE]
> **¿Sabía que?**
> ¡El atributo `#[Override]` es completamente ignorado por el motor de tiempo de ejecución en el momento de la ejecución! Es puramente una comprobación en tiempo de compilación diseñada para detectar errores de refactorización e implementaciones de interfaz que no coinciden antes de que su código se ejecute.

```php
// app/Services/Loggers/FileLogger.php
interface Logger
{
    public function log(string $message): void;
}

final class FileLogger implements Logger
{
    #[\Override]
    public function log(string $message): void
    {
        // ...
    }
}
```

Use esto especialmente en bases de código grandes donde las refactorizaciones renombran métodos de interfaz.

---

<a id="typed-constants"></a>
## Constantes de clase tipadas

Las constantes en **clases, interfaces, traits y enums** pueden declarar tipos, alineando las constantes con el resto del sistema de tipos.

```php
// app/Config/AppConfig.php
interface Config
{
    public const string APP_NAME = 'MyApp';
}
```

Esto reduce los errores de \"tipo de constante incorrecto\" que anteriormente solo surgían en los sitios de uso.

---

<a id="readonly-tweaks"></a>
## Readonly: clases anónimas y clonación

* **Las clases anónimas** pueden declararse `readonly`.
* **Las propiedades readonly** se pueden **reiniciar durante el `clone`** (dentro del método `__clone()`), lo que hace que los clones inmutables sean menos dolorosos que en los patrones exclusivos de PHP 8.2.

---

<a id="language-qol"></a>
## Calidad de vida del lenguaje

* **Acceso dinámico a constantes de clase**: `SomeClass::{$name}` para nombres de constantes en tiempo de ejecución.
* **Los inicializadores de variables estáticas** pueden usar expresiones arbitrarias (no solo constantes).
* **`final` en métodos de trait** al importar un método de trait.
* **Las clausuras a partir de métodos mágicos** pueden recibir **argumentos nombrados** cuando se invocan.
* **`php.ini`**: sintaxis de valor por defecto/de respaldo para una configuración más limpia.

---

<a id="new-functions"></a>
## Nuevas funciones que vale la pena adoptar

### `json_validate()`

Valide JSON **sin decodificarlo** en valores de PHP—ideal para APIs, colas y guardias rápidos antes de un costoso `json_decode()`.

> [!NOTE]
> **¿Sabía que?**
> ¡El uso de `json_validate()` consume significativamente menos memoria que `json_decode()` porque no construye ningún array u objeto PHP en memoria! Simplemente escanea la sintaxis de la cadena, lo que lo hace perfecto para validar payloads grandes antes de procesarlos.

```php
// app/Http/Middleware/JsonValidateMiddleware.php
if (!json_validate($payload)) {
    throw new InvalidArgumentException('JSON inválido');
}
$data = json_decode($payload, true, flags: JSON_THROW_ON_ERROR);
```

### `str_increment()` / `str_decrement()`

Reemplazos preferidos para los operadores heredados `++`/`--` en cadenas (ver depreciaciones). Úselo para contadores alfanuméricos donde anteriormente dependía de los operadores de incremento.

```php
// app/Services/CounterService.php
$next = str_increment('a9'); // paso predecible sin string ++
$prev = str_decrement($next);
```

### DOM, Intl, Random, POSIX, etc.

PHP 8.3 agrega muchos métodos **DOM** (por ejemplo, `insertAdjacentElement`, `getRootNode`, `replaceChildren`), asistentes de calendario **Intl**, asistentes de **Random** en `Randomizer` (`getFloat`, `nextFloat`, ...), y **POSIX** `sysconf`/`pathconf`/`eaccess`—útil para scripts y herramientas a nivel de sistema.

---

<a id="backward-incompatible"></a>
## Cambios incompatibles con versiones anteriores (notas de migración)

### Pila / temporizadores / fibers

* **La recursión profunda** cerca de los límites de la pila ahora puede lanzar `Error` cuando se excede `zend.max_allowed_stack_size` (menos el reservado); las fibers usan `fiber.stack_size` de manera similar.
* **Zend Max Execution Timers** tienen el valor predeterminado **activado** para compilaciones ZTS en Linux—vigile los trabajadores de CLI de larga ejecución.

### Procesos

* **`proc_get_status()`** en POSIX devuelve valores correctos en llamadas **repetidas**; los resultados pueden estar **almacenados en caché** (compruebe la clave `"cached"`). **`proc_close()`** después de `proc_get_status()` ahora produce códigos de salida correctos (no `-1`).

### Arrays y traits

* **Visibilidad de constantes de clase**: ahora se impone la varianza cuando las constantes se heredan de **interfaces**—el código que dependía de una visibilidad más flexible puede necesitar correcciones.
* **Array vacío + primer índice negativo**: la siguiente clave implícita sigue a `n+1` (no a `0`).
* **Traits con propiedades estáticas**: las estáticas heredadas del padre se **redestinan** por usuario del trait (almacenamiento separado)—puede afectar al estado estático sutil.

### Biblioteca estándar (alto impacto)

* **`range()`**: validación más estricta (`TypeError`/`ValueError` para entradas incorrectas), más advertencias para límites extraños, comportamiento diferente para rangos de caracteres cuando los límites parecen numéricos—**vuelva a probar** cualquier código que genere rangos a partir de la entrada del usuario.
* **`number_format()`**: los decimales negativos `$decimals` ahora redondean **antes** del punto decimal (anteriormente se ignoraban).
* **`file()`**: se rechazan las combinaciones de banderas no válidas (por ejemplo, `FILE_APPEND` se aceptaba silenciosamente antes).

### Date / DOM / FFI / Opcache

* **Date**: jerarquías de **`DateError`/`DateException`** más ricas en lugar de advertencias/excepciones genéricas—actualice los bloques `catch`.
* **DOM**: comportamiento alineado con las especificaciones para nodos sin padres; correcciones de `createAttributeNS()`; los nuevos miembros pueden tener **conflictos** con subclases de espacio de usuario—asegure firmas compatibles.
* **FFI**: las funciones C de tipo `void` devuelven **`null`**, no un objeto ficticio `FFI\CData:void`.
* **Opcache**: se **eliminó** `opcache.consistency_checks` (estaba roto con JIT de rastreo / caché de herencia).

### WeakMap

* **Las claves autorreferenciales** en `WeakMap` pueden recolectarse en ciclos donde la alcanzabilidad es solo a través de la iteración—audite patrones de almacenamiento en caché exóticos.

---

<a id="deprecations"></a>
## Depreciaciones (incrementar/decrementar cadenas, `get_class()`, assert INI)

### String `++` / `--`

El incremento/decremento en cadenas **vacías o no numéricas** está depreciado; el **incremento no numérico** está \"suavemente depreciado\". Prefiera **`str_increment()`** / **`str_decrement()`** para el código nuevo.

### `get_class()` / `get_parent_class()` sin argumentos

Llamarlos **sin argumentos** está depreciado—pase un objeto o nombre de clase explícitamente.

### Assert

* **`assert_options()`** y **constantes** relacionadas están depreciadas.
* Las configuraciones de **`assert.*` INI** están depreciadas—migre a las configuraciones de ini documentadas en las notas de migración de PHP 8.3 \"Manejo de INI\".

---

<a id="other-changes"></a>
## Otros cambios y operaciones

* **`gc_status()`** informa campos de tiempo más ricos (tiempo de recolector/destructor/liberación)—útil al ajustar cargas de trabajo con uso intensivo de memoria.
* **Streams**: `fread()` en sockets puede retornar antes cuando existen datos almacenados en búfer.
* **`open_basedir`**: en tiempo de ejecución `ini_set` rechaza rutas con `..` incluso cuando están prefijadas con `./`.

---

<a id="common-mistakes"></a>
## ⚠️ Errores Comunes

Aquí tiene algunos problemas comunes al usar las características de PHP 8.3:

### 1. Usar el Operador de Incremento (++) en Cadenas
In PHP 8.3, usar los operadores `++` o `--` en cadenas no numéricas desencadena una advertencia de depreciación.

```php
// app/Services/Counter.php
// MALO: Desencadena una advertencia de depreciación en PHP 8.3
$code = 'a9';
$code++; 

// BUENO: Use la nueva función auxiliar str_increment
$code = str_increment('a9'); // 'b0'
```

### 2. Falta de compatibilidad de constante tipada en subclases
Si una clase padre define una constante tipada, las clases hijas que sobrescriban esa constante deben coincidir exactamente con el tipo.

```php
// app/Config/DatabaseConfig.php
class ParentConfig {
    public const string DRIVER = 'mysql';
}

// MALO: Fatal Error: ChildConfig::DRIVER type (int) is not compatible with ParentConfig::DRIVER type (string)
class ChildConfig extends ParentConfig {
    public const int DRIVER = 123; 
}
```

### 3. Llamar a `get_class()` sin argumentos
Llamar a `get_class()` sin argumentos para obtener el nombre de la clase actual está depreciado en PHP 8.3.

```php
// app/Services/LogService.php
// MALO: Desencadena una advertencia de depreciación en PHP 8.3
class LogService {
    public function log(): void {
        echo "Logging from " . get_class(); 
    }
}

// BUENO: Use self::class o pase $this explícitamente
class LogService {
    public function log(): void {
        echo "Logging from " . self::class; 
        // O: echo "Logging from " . get_class($this);
    }
}
```

---

<a id="self-test-quiz"></a>
## Quiz de Autoevaluación

Pruebe su comprensión de las características de PHP 8.3.

### Pregunta 1: ¿Qué sucede si define una constante de clase con un tipo y asigna un valor de un tipo diferente (por ejemplo, `public const int NAME = 'MyApp';`) en PHP 8.3?
* A) Desencadena una advertencia de depreciación, pero se ejecuta con éxito.
* B) PHP convierte automáticamente la cadena al entero `0`.
* C) Lanza un `Fatal Error` en tiempo de compilación.

<details>
<summary>Mostrar respuestas</summary>

**Respuesta: C**  
En PHP 8.3, las constantes de clase tipadas se comprueban estrictamente en tiempo de compilación. Asignar un valor incompatible a una constante tipada resulta en un Fatal Error.
</details>

### Pregunta 2: ¿Por qué debería usar `json_validate()` en lugar de `json_decode()` si solo necesita comprobar si una cadena es un JSON válido?
* A) `json_validate()` es más rápido y consume mucha menos memoria porque no construye estructuras de objetos/arrays de PHP.
* B) `json_validate()` admite formatos JSON que `json_decode()` no puede analizar.
* C) `json_decode()` se depreciará en futuras versiones de PHP.

<details>
<summary>Mostrar respuestas</summary>

**Respuesta: A**  
`json_validate()` solo escanea la sintaxis de la cadena JSON sin asignar memoria para las estructuras decodificadas, lo que la hace mucho más eficiente para los pasos que son exclusivamente de validación.
</details>

---

## Resumen

PHP 8.3 se trata de reforzar la seguridad del contrato y optimizar el consumo de recursos. Al introducir constantes de clase tipadas y el atributo `#[Override]`, PHP hace que la refactorización sea más segura y evita desviaciones silenciosas de la API.