---
title: 'PHP 8.5: Pipe Operator, NoDiscard, URI Extension & Migration | DevSense'
description: 'Guía de PHP 8.5 desde 8.4: operador pipe |>, #[NoDiscard] y (void), clausuras en expresiones constantes, ext/uri, FILTER_THROW_ON_FAILURE y cambios en Opcache y PDO.'
faq:
    - { question: '¿Qué es el Operador Pipe en PHP 8.5?', answer: 'El operador pipe (|>) permite encadenar operaciones pasando el valor del lado izquierdo como primer argumento al callable del lado derecho, mejorando la legibilidad del código.' }
    - { question: '¿Qué es el atributo #[NoDiscard] en PHP 8.5?', answer: 'Marca funciones o métodos cuyo valor de retorno no debe ignorarse. Si un llamador descarta el valor de retorno, las herramientas de análisis estático (y PHP en algunas configuraciones) emitirán una advertencia.' }
    - { question: '¿Qué cambios ocurrieron en Opcache en PHP 8.5?', answer: 'Opcache ahora está compilado estáticamente en el binario de PHP. Ya no necesita (y no debe) cargarlo a través de zend_extension=opcache en sus archivos INI.' }
    - { question: '¿Cómo funciona FILTER_THROW_ON_FAILURE?', answer: 'Es una nueva bandera para las funciones de filtrado que activa una excepción ValueError si la validación falla, en lugar de devolver false.' }
published: '2026-05-31'
---
# PHP 8.5: Características Principales y Guía Interactiva

PHP 8.5 es un lanzamiento importante centrado en la expresividad sintáctica y la consolidación de la plataforma central. Trae el muy solicitado **Operador Pipe (`|>`)**, el atributo **`#[\NoDiscard]`** para obligar al manejo del valor de retorno de las funciones, y un análisis de URL/URI nativo alineado con WHATWG.

¡Exploremos estas actualizaciones con ejemplos interactivos, errores comunes y una sección de autoevaluación!

---

## Índice
* [El Operador Pipe (`|>`)](#pipe-operator)
* [Clausuras en expresiones constantes](#closures-in-constants)
* [`#[\NoDiscard]` y la conversión `(void)`](#nodiscard)
* [La extensión URI nativa](#uri-extension)
* [Asistentes de utilidad (`array_first()`, `array_last()`)](#new-functions)
* [Cambios incompatibles con versiones anteriores (PDO, Opcache)](#backward-incompatible)
* [🧠 Preguntas de autoevaluación](#self-check)

---

<a id="pipe-operator"></a>
## El Operador Pipe (`|>`)

¿Cansado de anidar funciones como `strtolower(trim($input))` o de poblar su alcance con variables temporales? PHP 8.5 introduce el **Operador Pipe (`|>`)** que le permite escribir transformaciones secuenciales de izquierda a derecha.

```php
// app/Services/Slugger.php
$slug = $title
    |> trim(...)
    |> strtolower(...)
    |> fn($s) => preg_replace('/\s+/', '-', $s);

echo $slug; // Salida: hello-world
```

> [!NOTE]
> **¿Sabía que?**
> El operador pipe pasa el valor de la izquierda como el **primer parámetro** al callable de la derecha. Si necesita pasarlo como un segundo o tercer parámetro, envuelva la llamada en una clausura personalizada o función de flecha.

### ⚠️ Errores Comunes

**1. Olvidar poner entre paréntesis las funciones de flecha**
Si encadena funciones de flecha personalizadas directamente en un pipe, debe envolverlas entre paréntesis para evitar la ambigüedad de análisis:

```php
// app/Services/Formatter.php
// ❌ ¡Error de sintaxis!
$result = $value |> fn($x) => $x * 2 |> fn($y) => $y + 10;

// ✅ Enfoque correcto
$result = ($value |> fn($x) => $x * 2) |> fn($y) => $y + 10;
```

---

<a id="closures-in-constants"></a>
## Clausuras y Callables de primera clase en expresiones constantes

PHP 8.5 le permite definir **clausuras** y **callables de primera clase** en lugares que antes solo aceptaban valores estáticos, como constantes de clase, valores predeterminados de propiedades y parámetros de atributos.

```php
// app/Attributes/Route.php
class Route
{
    public function __construct(
        public string $path,
        public Closure $callback = (fn() => 'Default Route')
    ) {}
}
```

Esta es una gran victoria para los motores de enrutamiento y las bibliotecas de validación que necesitan empaquetar una lógica ligera en los metadatos.

---

<a id="nodiscard"></a>
## `#[\NoDiscard]` y la conversión `(void)`

Cuando las operaciones de escritura o las llamadas de validación devuelven resultados de estado, los desarrolladores a menudo olvidan verificarlos. PHP 8.5 agrega el atributo `#[\NoDiscard]` para advertir cuando se ignora un valor de retorno.

```php
// app/Services/Transaction.php
class Transaction
{
    #[\NoDiscard]
    public function commit(): bool
    {
        // ...
        return true;
    }
}

$tx = new Transaction();
$tx->commit(); // ❌ Advertencia: Return value of Transaction::commit() must not be discarded!
```

Si *sabe* lo que está haciendo y desea descartar el valor, use la nueva conversión `(void)` para suprimir la advertencia:

```php
// app/Services/Handler.php
(void) $tx->commit(); // ✅ Descartado explícitamente, ¡sin advertencia!
```

---

<a id="uri-extension"></a>
## La extensión URI nativa (RFC 3986)

Las URLs y URIs son notoriamente difíciles de analizar correctamente debido a fallos de seguridad como el recorrido de directorios. PHP 8.5 incluye una extensión `uri` siempre habilitada que implementa un análisis compatible con las especificaciones de la RFC 3986 y el estándar de URL de WHATWG.

```php
// app/Services/UrlParser.php
$uri = Uri\parse('https://user:pass@example.com:8080/path?query=1#hash');

echo $uri->host;     // example.com
echo $uri->port;     // 8080
echo $uri->userInfo; // user:pass
```

---

<a id="new-functions"></a>
## Nuevos asistentes de utilidad: `array_first()` y `array_last()`

En lugar de restablecer los punteros del array o escribir funciones personalizadas, PHP 8.5 introduce asistentes nativos y eficientes:

```php
// app/Services/Collection.php
$list = ['apple', 'banana', 'cherry'];

$first = array_first($list); // 'apple'
$last  = array_last($list);  // 'cherry'
```

Además, ahora se puede pasar `FILTER_THROW_ON_FAILURE` a los filtros de validación para que lancen excepciones en lugar de devolver `false` en caso de fallo:

```php
// app/Http/Request.php
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, FILTER_THROW_ON_FAILURE);
```

---

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

Antes de actualizar a PHP 8.5, verifique estos cambios críticos:

1. **Opcache está compilado estáticamente**
   Opcache ahora es una parte central del binario PHP y no se puede compilar como una extensión compartida. Agregar `zend_extension=opcache.so` en sus archivos INI emitirá una advertencia.
2. **Cambios numéricos en las constantes de PDO Fetch**
   Si almacena enteros del modo de obtención de PDO (por ejemplo, `PDO::FETCH_GROUP`) en tablas de bases de datos o configuraciones dinámicas, tenga cuidado: sus valores enteros de respaldo han cambiado en la versión 8.5.
3. **Restricción de `class_alias()`**
   Ya no puede usar `"array"` o `"callable"` como nombres de alias.

---

<a id="self-check"></a>
## 🧠 Preguntas de autoevaluación

Probemos su comprensión de PHP 8.5:
1. **¿Verdadero o falso?** El lado derecho del operador pipe (`|>`) puede aceptar múltiples argumentos de forma predeterminada.
2. ¿Cuál es la sintaxis para suprimir explícitamente una advertencia para un método marcado con `#[\NoDiscard]`?
3. ¿Cómo debe cargar Opcache en su archivo `php.ini` bajo PHP 8.5?
4. **¿Verdadero o falso?** `array_first()` y `array_last()` funcionan en arrays asociativos.

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

1. **Falso.** El lado derecho debe aceptar exactamente un argumento. Si la función de destino acepta más parámetros, debe envolverla en una clausura o función de flecha.
2. Anteponga la llamada con una conversión `(void)` (por ejemplo, `(void) $obj->method();`).
3. ¡No necesita cargarlo en absoluto! Está compilado estáticamente en el binario. Solo necesita habilitarlo a través de `opcache.enable=1`.
4. **Verdadero.** Devuelven el primer y último elemento de cualquier array, independientemente de si las claves son numéricas o asociativas.
</details>