FrankenPHP 1.13.0 est sorti le 4 octobre à 14:01. Après v1.12.7, cette version intègre Caddy 2.11.7 et Mercure 1.0. Elle ajoute la compatibilité avec PHP 8.6 et passe à Go 1.27.

Cinq problèmes de sécurité sont corrigés. Sous Windows, la résolution de `SCRIPT_FILENAME` ne peut plus sortir de la racine documentaire. Le correctif est référencé GHSA-868c-7h7m-mmj9. Caddy 2.11.7 rejette par défaut les noms d’en-tête contenant un point. Cela ferme un vecteur d’usurpation où PHP transforme `Foo.Bar` en `HTTP_FOO_BAR` comme `Foo-Bar`. Le correctif porte la référence GHSA-qcrp-8483-f2f2. La séparation du chemin CGI exige maintenant une limite de segment. `/uploads/a.php.txt/b.php` ne peut donc plus exécuter `uploads/a.php`, selon GHSA-xxjp-cjxr-2x6m. `putenv()` ne modifie plus l’environnement OS global du processus, ce qui empêche la fuite de valeurs entre requêtes et threads. Ce changement correspond à GHSA-996f-w38m-f574. Un tableau préparé transmis à `frankenphp_log()` ne peut plus faire tomber tout le processus serveur. La correction est suivie par GHSA-4prg-hv4r-g6mv.

Caddy 2.11.7 reprend les changements de Caddy 2.11.6 et 2.11.7. La protection contre Slowloris réinitialise les délais de lecture et d’écriture dès qu’une opération réussit. La directive `timeouts` permet de les régler par route. Le matcher `url_pattern` suit le standard web URLPattern. Il accepte les groupes nommés, les jokers et les expressions régulières, puis expose les groupes capturés comme placeholders.

L’en-tête `Incremental: ?1` de la RFC 10036 demande à `reverse_proxy` et `encode` de transmettre immédiatement les réponses. Les Server-Sent Events derrière `encode` ne sont plus mis en tampon, ce qui profite à Mercure. L’arrêt gracieux attend les serveurs issus d’anciennes configurations. Les réponses longues ne sont donc pas interrompues par un rechargement.

L’option globale `tls_automate_names` peut gérer les certificats de noms qui ne disposent pas de bloc de site. La recherche de certificat pendant le handshake TLS est environ deux fois plus rapide et passe de 15 à 10 allocations. Le reverse proxy vide correctement les réponses partielles et transmet le half-close TCP sur les flux mis à niveau. Les contrôles de santé actifs sont isolés pour chaque configuration de contrôle. `expected_underscore_headers` et `expected_dot_headers` permettent de conserver certains en-têtes que Caddy supprimerait normalement.

Mercure 1.0 modifie `mercure_publish()`. La fonction lève une `ValueError` si la mise à jour utilise un topic du namespace réservé `/.well-known/mercure`, un identifiant commençant par `#`, des caractères de contrôle, un UTF-8 invalide, une valeur de retry négative ou aucun topic. Un échec de diffusion produit une `RuntimeException` contenant le message du hub. Le nouveau bloc `issuer` associe les clés des éditeurs et des abonnés à un émetteur de confiance. Le Caddyfile d’exemple et `php-server --mercure` utilisent cette configuration.

La mise à niveau change plusieurs paramètres. `num_threads` compte maintenant les threads disponibles pour les requêtes qu’aucun worker ne sert. Les threads des workers s’y ajoutent. Une configuration avec des workers peut donc démarrer davantage de threads qu’auparavant. Le démarrage échoue si `max_threads` est inférieur à `num_threads` plus les threads des workers, et le message indique les trois valeurs. Les valeurs par défaut ne changent pas.

Définir `publisher_jwt` ou `subscriber_jwt` sans `protocol_version_compatibility` est désormais invalide. Les configurations Mercure doivent utiliser le bloc `issuer`. Lors d’un hot reload, `$_SERVER['FRANKENPHP_HOT_RELOAD']` annonce maintenant `/.well-known/mercure?match=<topic>`. Les URL codées en dur avec `?topic=` doivent être modifiées.

Caddy limite par défaut les en-têtes de requête à 16 KiB. L’option `max_header_size` permet d’augmenter cette limite. Les lectures et écritures bloquées sont interrompues après une minute. Les en-têtes contenant un point sont supprimés comme ceux contenant un underscore. Le `client_auth` d’un site générique ne s’applique plus aux sites plus spécifiques. Certaines configurations invalides supplémentaires sont rejetées. Un build PHP sans `--disable-zend-signals` (ZTS) fait maintenant arrêter FrankenPHP avec une erreur explicite. Le processus pouvait auparavant rester bloqué pendant que sa consommation mémoire augmentait.

La version expose une API de threads pour les extensions PHP écrites en Go. Elle comprend `Thread(index)`, `PHPThread.Pin()`, `PHPThread.IsRequestDone()` et la fonction C `frankenphp_thread_index()`. Une configuration est validée avant de remplacer celle qui sert les requêtes. Un fichier de worker absent, un nom de worker dupliqué ou un budget de threads incohérent sont rejetés, tandis que la configuration active continue de répondre. Les utilisateurs de la bibliothèque disposent de `frankenphp.Validate()`.

Les journaux de démarrage indiquent désormais `total_threads` et `worker_threads`. Les redémarrages de la mémoire partagée d’Opcache sont journalisés et comptés par la métrique expérimentale `frankenphp_opcache_restarts{reason}` avec PHP 8.4 et les versions suivantes. Ces redémarrages sont dangereux sous ZTS, le compteur doit donc rester à zéro. Les blocs `php_server` sont répliqués côté FrankenPHP. `phpinfo()` reçoit une section FrankenPHP avec la version de Caddy. Le code Go peut ajouter des lignes avec `frankenphp.AddPHPInfoEntry()`.

À partir de PHP 8.5, `php-cli` utilise la SAPI CLI intégrée à PHP. La compatibilité avec PHP 8.6 fait également partie de cette version.

Les requêtes arrivant avant la préparation des threads classiques ne restent plus bloquées. Cela évite les réponses 499 et 504 aléatoires après le démarrage d’un conteneur. Les crashs de workers sont journalisés au niveau warning avec leur statut de sortie. Les redémarrages normaux restent au niveau debug. `Shutdown()` n’attend plus indéfiniment un worker qui a abandonné son démarrage après `max_consecutive_failures`.

Les builds statiques ne transforment plus les erreurs Go récupérables de l’extension parallel intégrée en crashs de processus. Un possible use-after-free du tableau d’extensions conservé par `register_extensions` est corrigé. `extgen` gère maintenant les paramètres groupés et nullable, les callables, les valeurs de retour mixed, les wrappers de méthodes, les constantes et les littéraux entiers dans les extensions générées.

La documentation recense désormais les paramètres du moteur qui persistent entre les requêtes en mode worker, notamment `ini_set()`, `stream_context_set_default()`, `date_default_timezone_set()` et `chdir()`. Elle décrit les différences de filtrage des requêtes HTTP, enrichit la documentation des métriques, ajoute une page Yii 3, corrige l’URL CDN d’Idiomorph dans l’exemple de hot reload et complète les traductions turques. johanjanssens, luminalpark, KalimeroMK et quyt0 ont contribué pour la première fois à cette version.