From d611ca7d13046489cb97c9a5a09dee0a363be0dc Mon Sep 17 00:00:00 2001 From: lacatoire Date: Thu, 10 Sep 2026 09:33:43 +0200 Subject: [PATCH] [Sync-En] Document window parameter role in zlib filters; update Serializable example --- appendices/filters.xml | 114 ++++++++++++++++++++++++++- language/predefined/serializable.xml | 94 ++++++++++++++++------ 2 files changed, 179 insertions(+), 29 deletions(-) diff --git a/appendices/filters.xml b/appendices/filters.xml index 2617fb0a26..19454b5a11 100644 --- a/appendices/filters.xml +++ b/appendices/filters.xml @@ -1,6 +1,5 @@ - - + Liste des filtres disponibles @@ -286,7 +285,7 @@ fclose($fp);
zlib.deflate et zlib.inflate - + zlib.deflate (compression) et zlib.inflate (décompression) sont les implémentations des méthodes de compression présentées dans la @@ -306,12 +305,119 @@ fclose($fp); occupent le moins d'espace en mémoire. Par défaut, window vaut actuellement 15. + Le filtre zlib.deflate implémente les méthodes de + compression DEFLATE, ZLIB et + GZIP selon la valeur du paramètre + window. + + Les 4 bits de poids faible du paramètre window définissent la taille du + tampon d'historique interne, exprimée comme le logarithme en base 2 de + cette taille, entre 8 et 15. La signification des autres bits est décrite + ci-dessous. + + + + + DEFLATE (RFC 1951) + est un algorithme de compression brut, sans en-tête ni somme de contrôle. + Il est utilisé lorsque le paramètre window est compris entre -9 et -15. + Cet algorithme est la base de tous les formats générés par le filtre + zlib.deflate. + Les fonctions qui opèrent directement sur des chaînes sont + gzdeflate et gzinflate. + + + + + + ZLIB (RFC 1950) + applique l'algorithme DEFLATE et ajoute un en-tête de + 2 octets et un trailer de 4 octets contenant la somme de contrôle Adler32 + des données non compressées en ordre big-endian : + + + L'en-tête de 2 octets, lu comme un entier non signé de 16 bits en + big-endian, doit être un multiple de 31. + Ce format est généré lorsque le paramètre window est compris entre 8 et 15. + Les fonctions qui opèrent directement sur des chaînes sont + gzcompress et gzuncompress. + + + + + + GZIP (RFC 1952) + applique l'algorithme DEFLATE en ajoutant un en-tête et + un trailer contenant la somme de contrôle CRC32 des + données non compressées et leur longueur, tous deux en ordre little-endian : + + + C'est le format des fichiers .gz. + Ce format est généré lorsque le paramètre window est compris entre + 9+16=25 et 15+16=31. La longueur des données non compressées est limitée + à 4 Go ; au-delà, seul le modulo 2^32 de la longueur réelle est stocké + dans la partie LONGUEUR. + Les fonctions qui opèrent directement sur des chaînes sont + gzencode et gzdecode ; + la fonction gzopen permet de lire et d'écrire des + fichiers .gz. + + + + + Avec le filtre zlib.inflate, seul le paramètre + window est pris en compte ; tout autre paramètre + (memory, level) est ignoré. + En notant $W le logarithme en base 2 de la taille du tampon d'historique, + de sorte que 2^$W octets sont alloués par le décompresseur. Pour le format + ZLIB, cette valeur doit être supérieure ou égale à celle enregistrée dans + l'en-tête, vérifiée à la décompression ; pour les autres formats, elle doit + simplement être suffisamment grande pour les distances de correspondance + présentes dans les données. + La plage est 9 ≤ $W ≤ 15. En cas de doute, $W=15 est le choix le plus sûr. + + + + + DEFLATE (RFC 1951) : + utiliser window=-$W, avec $W au moins égal à la valeur utilisée à la + compression. En cas de doute, utiliser window=-15. + + + + + + ZLIB (RFC 1950) : + utiliser window=$W. La valeur de $W est disponible dans l'en-tête ZLIB, + sinon utiliser window=15. + + + + + + GZIP (RFC 1952) : + utiliser window=$W+16. Un en-tête GZIP ne contient pas la taille de + fenêtre, donc utiliser window=31 sauf si la valeur utilisée à la + compression est connue. + + + + + + ZLIB ou GZIP : + utiliser window=$W+32 pour la détection automatique de l'en-tête, de + sorte que les deux formats puissent être reconnus et décompressés ; + window=15+32=47 est le choix le plus sûr. + + + + memory est une indication du niveau de mémoire nécessaire. Les valeurs valides vont de 1, pour l'allocation minimale, à 9, pour une allocation maximale. L'allocation de mémoire affecte la vitesse d'exécution, et n'a pas d'impact sur la taille de la charge utile générée. - + diff --git a/language/predefined/serializable.xml b/language/predefined/serializable.xml index a3e55b4710..f3b9e851dd 100644 --- a/language/predefined/serializable.xml +++ b/language/predefined/serializable.xml @@ -1,6 +1,5 @@ - - + L'interface Serializable @@ -38,6 +37,35 @@ une notice de dépréciation. + + + Le nouveau code devrait utiliser les méthodes magiques + __serialize() et + __unserialize(), + disponibles à partir de PHP 7.4.0. + Lorsqu'une classe les déclare en plus de cette interface, + serialize utilise toujours + __serialize() et n'atteint jamais + Serializable::serialize. + La désérialisation est déterminée par le format des données : un flux + écrit par PHP 7.4.0 ou ultérieur est lu par + __unserialize(), un flux écrit + avant l'est toujours par + Serializable::unserialize. + Implémenter Serializable reste donc utile + pour lire d'anciens flux, et pour satisfaire une déclaration de type + Serializable ; déclarer les quatre méthodes + couvre tous les cas et évite la notice de dépréciation. + + + + + Les méthodes magiques n'ont pas d'interface propre : une classe qui les + déclare sans implémenter Serializable + n'en est pas une instance. + method_exists est le moyen de les détecter. + +
@@ -57,45 +85,61 @@
&reftitle.examples; - Exemple simple + Prise en charge de PHP 7.1.0 à 7.3.0 + + Les méthodes magiques portent la forme sérialisée, et les méthodes de + l'interface leur délèguent, de sorte qu'une seule représentation convient + dans les deux cas. + data = "Mes données privées"; - } - public function serialize() { - return serialize($this->data); - } - public function unserialize($data) { - $this->data = unserialize($data); +class Task implements Serializable +{ + private $label; + + public function __construct($label) + { + $this->label = $label; } - public function getData() { - return $this->data; + + public function __serialize(): array + { + return ['label' => $this->label]; } -} -$obj = new obj; -$ser = serialize($obj); + public function __unserialize(array $data): void + { + $this->label = $data['label']; + } -var_dump($ser); + // Jamais appelé à partir de PHP 7.4.0 + public function serialize() + { + return serialize($this->__serialize()); + } -$newobj = unserialize($ser); + // Toujours appelé à partir de PHP 7.4.0, pour les données écrites avant + public function unserialize($data) + { + $this->__unserialize(unserialize($data)); + } +} -var_dump($newobj->getData()); +var_dump(serialize(new Task('deploy'))); ?> ]]> - &example.outputs.similar; + &example.outputs; + + Avant PHP 7.4.0, le même code sérialise via l'interface et affiche + string(47) "C:4:"Task":31:{a:1:{s:5:"label";s:6:"deploy";}}". +