# WeakMap PHP 8.0 pour mémoriser un résultat sans empêcher sa libération mémoire

> WeakMap permet d'associer une valeur calculée à un objet PHP sans empêcher le ramasse-miettes de le libérer. Un mécanisme discret mais précieux pour un cache en mémoire.

- Auteur : Clément Hadrot
- Publié le : 2021-02-27
- Mis à jour le : 2021-02-27
- Catégorie : Performance
- URL : https://wpmoderne.dev.wordpress-developpement.fr/performance/weakmap-php-8-0-cache-memoire-objets/

## L’essentiel

- Une clé de tableau classique retient l'objet indéfiniment
- WeakMap laisse le ramasse-miettes faire son travail
- Utile pour des calculs coûteux liés à un objet temporaire

`$cache = new WeakMap();` — cette seule ligne change la façon dont on peut mémoriser un résultat lié à un objet, sans risquer de créer une fuite mémoire silencieuse. WeakMap fait partie des ajouts discrets de PHP 8.0, moins commentés que les types d'union ou les arguments nommés, mais tout aussi utiles dans certains cas précis de développement WordPress.

Le problème qu'elle résout est simple à décrire une fois qu'on l'a rencontré : un tableau PHP classique utilisé comme cache, indexé par un objet (via `spl_object_id()` par exemple), garde une référence forte vers cet objet. Tant que le tableau existe, l'objet ne peut jamais être libéré par le ramasse-miettes, même si plus rien d'autre dans le code n'y fait référence. Sur un traitement qui instancie des milliers d'objets temporaires, cela peut faire grimper la consommation mémoire d'un script PHP bien au-delà de ce qui serait nécessaire.

## Ce que change une référence faible

Une `WeakMap` associe une clé (qui doit être un objet) à une valeur, mais sans empêcher cet objet d'être détruit par le ramasse-miettes s'il n'est plus référencé ailleurs. Dès que l'objet clé disparaît, l'entrée correspondante disparaît automatiquement de la `WeakMap`, sans qu'il soit nécessaire d'appeler quoi que ce soit pour nettoyer. C'est exactement le comportement qu'on attend d'un cache éphémère : mémoriser un résultat tant que l'objet source existe, et l'oublier proprement dès qu'il n'existe plus.

Dans un contexte WordPress, ce mécanisme trouve sa place quand un même objet métier (un objet `WP_Post` enrichi, une instance de classe personnalisée représentant une fiche produit) sert de point d'ancrage à un calcul coûteux qu'on ne veut pas refaire deux fois pendant la même requête, sans pour autant vouloir gérer manuellement l'invalidation.

## Un exemple concret de mise en œuvre

```
final class CalculPrixAffiche {
    private WeakMap $cache;

    public function __construct() {
        $this->cache = new WeakMap();
    }

    public function pour(WP_Post $produit): float {
        if (isset($this->cache[$produit])) {
            return $this->cache[$produit];
        }

        $prix = $this->calculerPrixComplexe($produit);
        $this->cache[$produit] = $prix;

        return $prix;
    }

    private function calculerPrixComplexe(WP_Post $produit): float {
        // agrégation de plusieurs meta et d'une remise conditionnelle
        return 0.0;
    }
}
```

> L'essentiel à retenir : Une clé de tableau classique retient l'objet indéfiniment ; WeakMap laisse le ramasse-miettes faire son travail ; Utile pour des calculs coûteux liés à un objet temporaire

## Pourquoi ce n'est pas un remplacement du cache d'objet persistant

Il faut garder une distinction claire entre les deux outils. Le cache d'objet persistant (Redis ou Memcached derrière `wp_cache_get()`) survit d'une requête HTTP à l'autre et sert à éviter des lectures en base de données répétées entre visiteurs. La `WeakMap` ne survit jamais au-delà de la requête PHP courante : elle vit et meurt avec le processus, et son seul rôle est d'éviter des recalculs redondants pendant l'exécution d'un même script.

## Quand l'utiliser, et quand s'abstenir

- Utile quand une même instance d'objet transite plusieurs fois dans le même appel (boucles imbriquées, hooks déclenchés à plusieurs reprises pour le même contenu).
- Inutile si le calcul dépend uniquement d'un identifiant scalaire : un tableau associatif classique indexé par cet identifiant suffit largement, sans le coût conceptuel supplémentaire.
- À éviter si l'on a besoin d'itérer sur toutes les entrées du cache dans un ordre prévisible : `WeakMap` est conçue pour l'association clé-objet, pas pour le parcours ordonné.

### Un piège de compatibilité à vérifier

Comme WeakMap n'existe qu'à partir de PHP 8.0, tout code destiné à tourner sur un parc d'hébergement hétérogène doit vérifier la version PHP disponible avant de l'utiliser, ou prévoir un repli vers un tableau associatif classique pour les environnements encore en PHP 7.4.

## En résumé

WeakMap répond à un besoin précis et rare mais réel : mémoriser un résultat lié à un objet sans figer cet objet en mémoire pour toute la durée du script. Ce n'est pas un outil à sortir systématiquement, mais quand le besoin se présente, il évite un genre de fuite mémoire particulièrement difficile à diagnostiquer, puisqu'elle ne se manifeste que sur des volumes de données suffisamment grands pour la rendre visible dans les journaux.
