---
title: 'PHP 8.5: Pipe Operator, NoDiscard, URI Extension & Migration | DevSense'
description: 'Guide PHP 8.5 depuis la version 8.4 : opérateur pipe |>, attribut #[NoDiscard] et cast (void), fermetures dans les expressions constantes, extension URI native.'
faq:
    - { question: "Qu'est-ce que l'opérateur Pipe dans PHP 8.5 ?", answer: "L'opérateur pipe (|>) permet de chaîner des opérations en transmettant la valeur de gauche comme premier argument à l'appelable (callable) de droite, améliorant ainsi la lisibilité du code." }
    - { question: "Qu'est-ce que l'attribut #[NoDiscard] dans PHP 8.5 ?", answer: "Il marque les fonctions ou méthodes dont la valeur de retour ne doit pas être ignorée. Si un appelant ignore cette valeur, les outils d'analyse statique (et PHP dans certaines configurations) émettront un avertissement." }
    - { question: 'Quels changements ont été apportés à Opcache dans PHP 8.5 ?', answer: "Opcache est désormais compilé statiquement dans le binaire PHP. Vous n'avez plus besoin de (et ne devriez plus) le charger via la directive zend_extension=opcache dans vos fichiers INI." }
    - { question: 'Comment fonctionne la constante FILTER_THROW_ON_FAILURE ?', answer: "Il s'agit d'une nouvelle option pour les fonctions de filtrage qui déclenche une exception ValueError si la validation échoue, au lieu de renvoyer false." }
published: '2026-05-31'
---
# PHP 8.5 : Fonctionnalités majeures & Guide interactif

PHP 8.5 est une version majeure axée sur l'expressivité de la syntaxe et la consolidation du noyau. Elle apporte l'**opérateur Pipe (`|>`)** très attendu, l'attribut **`#[\NoDiscard]`** pour imposer le traitement de la valeur de retour des fonctions, et une analyse des URL/URI native et conforme aux standards du WHATWG.

Découvrons ces nouveautés à l'aide d'exemples pratiques, analysons les pièges courants et testons vos connaissances dans la section d'auto-évaluation !

---

## Table des matières
* [L'opérateur Pipe (`|>`)](#pipe-operator)
* [Fermetures dans les expressions constantes](#closures-in-constants)
* [`#[\NoDiscard]` & le Cast `(void)`](#nodiscard)
* [L'extension URI native](#uri-extension)
* [Utilitaires pratiques (`array_first()`, `array_last()`)](#new-functions)
* [Changements non rétrocompatibles (PDO, Opcache)](#backward-incompatible)
* [🧠 Questions d'auto-évaluation](#self-check)

---

<a id="pipe-operator"></a>
## L'opérateur Pipe (`|>`)

Vous en avez assez de devoir imbriquer vos fonctions comme `strtolower(trim($input))` ou d'encombrer votre code avec des variables temporaires ? PHP 8.5 introduit l'**opérateur Pipe (`|>`)** qui vous permet d'écrire des transformations séquentielles de gauche à droite.

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

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

> [!NOTE]
> **Le saviez-vous ?**
> L'opérateur pipe transmet la valeur de gauche comme **premier paramètre** à l'appelable de droite. Si vous devez la transmettre comme deuxième ou troisième paramètre, enveloppez l'appel dans une fermeture ou une fonction fléchée personnalisée.

### ⚠️ Erreurs courantes

**1. Oublier de parenthéser les fonctions fléchées**
Si vous enchaînez des fonctions fléchées personnalisées directement dans un pipe, vous devez les envelopper entre parenthèses pour éviter toute ambiguïté syntaxique :

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

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

---

<a id="closures-in-constants"></a>
## Fermetures & Callables First-Class dans les expressions constantes

PHP 8.5 vous permet de définir des **fermetures** (closures) et des **callables de première classe** dans des emplacements qui n'acceptaient auparavant que des valeurs statiques, tels que les constantes de classe, les valeurs par défaut des propriétés et les paramètres d'attributs.

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

Il s'agit d'une avancée majeure pour les moteurs de routage et les bibliothèques de validation qui ont besoin d'embarquer une logique légère dans leurs métadaten.

---

<a id="nodiscard"></a>
## `#[\NoDiscard]` et le Cast `(void)`

Lorsque des opérations d'écriture ou des appels de validation retournent des résultats d'état, les développeurs oublient souvent de les vérifier. PHP 8.5 ajoute l'attribut `#[\NoDiscard]` pour alerter lorsqu'une valeur de retour est ignorée.

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

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

Si vous savez ce que vous faites et souhaitez ignorer délibérément la valeur, utilisez le nouveau cast `(void)` pour masquer l'avertissement :

```php
// app/Services/Handler.php
(void) $tx->commit(); // ✅ Ignoré explicitement, pas d'avertissement !
```

---

<a id="uri-extension"></a>
## L'extension URI native (RFC 3986)

Les URL et les URI sont notoirement difficiles à analyser correctement en raison de failles de sécurité telles que la traversée de répertoires (path traversal). PHP 8.5 intègre une extension `uri` activée en permanence qui implémente une analyse conforme aux spécifications de la RFC 3986 et au standard URL du 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>
## Nouveaux utilitaires : `array_first()` et `array_last()`

Plutôt que de réinitialiser les pointeurs de tableaux ou d'écrire des fonctions personnalisées, PHP 8.5 introduit des helpers natifs et performants :

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

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

De plus, l'option `FILTER_THROW_ON_FAILURE` peut désormais être passée aux filtres de validation afin qu'ils lèvent des exceptions au lieu de retourner `false` en cas d'échec :

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

---

<a id="backward-incompatible"></a>
## Changements non rétrocompatibles (liste de contrôle)

Avant de passer à PHP 8.5, vérifiez ces modifications critiques :

1. **Opcache est compilé statiquement**
   Opcache fait désormais partie intégrante du binaire PHP et ne peut plus être compilé en tant qu'extension partagée. L'ajout de `zend_extension=opcache.so` dans vos fichiers INI émettra un avertissement.
2. **Modifications numériques des constantes de PDO Fetch**
   Si vous stockez des valeurs entières de modes de récupération PDO (par exemple `PDO::FETCH_GROUP`) dans des tables de base de données ou des configurations dynamiques, soyez vigilant : leurs valeurs entières sous-jacentes ont changé dans la version 8.5.
3. **Restriction sur `class_alias()`**
   Vous ne pouvez plus utiliser `"array"` ou `"callable"` comme noms d'alias.

---

<a id="self-check"></a>
## 🧠 Questions d'auto-évaluation

Testons votre compréhension de PHP 8.5 :
1. **Vrai ou Faux ?** La partie droite de l'opérateur pipe (`|>`) peut accepter plusieurs arguments par défaut.
2. Quelle est la syntaxe pour masquer explicitement un avertissement pour une méthode marquée par `#[\NoDiscard]` ?
3. Comment devez-vous charger Opcache dans votre fichier `php.ini` sous PHP 8.5 ?
4. **Vrai ou Faux ?** `array_first()` et `array_last()` fonctionnent sur des tableaux associatifs.

<details>
<summary><b>Afficher les réponses</b></summary>

1. **Faux.** La partie droite doit accepter exactement un argument. Si la fonction cible requiert d'autres paramètres, vous devez l'envelopper dans une fermeture ou une fonction fléchée.
2. Préfixez l'appel avec un cast `(void)` (ex. `(void) $obj->method();`).
3. Vous n'avez pas besoin de le charger ! Il est compilé statiquement dans le binaire. Il vous suffit de l'activer via `opcache.enable=1`.
4. **Vrai.** Ils retournent le premier et le dernier élément de n'importe quel tableau, que les clés soient numériques ou associatives.
</details>