PHP 8.6 introduit la Partial Function Application, ou PFA. La fonctionnalité est actuellement en bêta. La sortie est annoncée autour du 19 novembre 2026.

PHP 8.1 avait apporté la First-Class Callable Syntax. Une fonction existante peut ainsi devenir un callable avec une écriture comme `trim(...)`, notamment pour `array_map()`. Cette syntaxe ne fixe pas d’arguments à l’avance. La PFA permet cette configuration avec une expression telle que `str_replace(' ', '-', ?)`, qui produit un callable attendant la valeur restante.

Chaque `?` correspond à un seul argument fourni plus tard. Plusieurs marqueurs sont possibles, y compris entre des arguments positionnels ou nommés déjà fixés. L’ordre est imposé. Les valeurs positionnelles et les `?` viennent d’abord, puis les arguments nommés. Un seul `...` final peut être utilisé, toujours en dernière position. Il laisse ouverts tous les emplacements d’arguments qui suivent.

La PFA cible notamment les fonctions qui prennent un callable. `array_map()` peut recevoir directement `str_replace('hello', 'hi', ?)` comme callback. Dans l’exemple avec `array_filter()`, `mode: ?` reste ouvert, `is_numeric(...)` fixe le callback et `...` reporte l’argument du tableau. Le callable obtenu accepte alors `0` et `[1, 'a', 2, 'b', 3]` en positionnel, ou `mode: 0` et `array: [1, 'a', 2, 'b', 3]` avec des noms.

Le marqueur `...` sert aussi à différer l’exécution. Un callable créé depuis `printf('Hello, %s!' . PHP_EOL, ...)` peut être appelé au moment voulu. Avec l’opérateur pipe, `str_replace(' ', '-', ?)` reçoit la valeur transmise par l’étape précédente. La PFA fonctionne avec les méthodes statiques et d’instance. Les exemples utilisent `Book::create(category: Category::THRILLER, title: ?)` et `$book->publish(new DateTimeImmutable(), ...)`.

Les arguments fixes sont évalués lors de la création du callable partiel. Dans l’exemple utilisant `getPrefix()`, la fonction affiche `Called!`, renvoie `PHP` et s’exécute immédiatement. Cette valeur est conservée pour des appels ultérieurs comme `$partial('Alice')` et `$partial('Bob')`. Une closure classique évalue un appel tel que `getPrefix()` à chaque exécution.

La PFA crée une nouvelle closure. Elle ne conserve pas tous les attributs du callable original. Les attributs personnalisés tels que `#[MyAttribute]` disparaissent. `#[NoDiscard]` et `#[SensitiveParameter]` font exception, et `#[SensitiveParameter]` est conservé lorsque son paramètre reste ouvert. Le code utilisant Reflection doit tenir compte de cette différence. L’article signale aussi que certaines constructions spéciales ne sont pas prises en charge, sans les détailler.