web-dev-qa-db-fra.com

Que font les modificateurs ENT_HTML5, ENT_HTML401, ... sur html_entity_decode?

Depuis php 5.4 html_entity_decode introduit quatre nouveaux drapeaux, avec une explication minimale

ENT_HTML401 Handle code as HTML 4.01.
ENT_XML1    Handle code as XML 1.
ENT_XHTML   Handle code as XHTML.
ENT_HTML5   Handle code as HTML 5. 

Je veux comprendre à quoi servent-ils. Dans quels cas sont-ils significatifs?

Je suppose (mais je peux me tromper) que toute norme différente code certains caractères inhabituels, mais aucun autre ne le fait, donc afin de respecter cela, ils sont ici.

Ma recherche: htmlentities a la même explication minimale, sans aucun exemple aussi. J'ai googlé sans chance.

52
Luis Siquot

J'ai commencé à me demander quel comportement ces constantes ont lorsque j'ai vu ces constantes sur la page htmlspecialchars. La documentation était des ordures, alors j'ai commencé à creuser dans le code source de PHP.

Fondamentalement, ces constantes affectent si certaines entités sont codées ou non (ou décodées pour html_entity_decode). L'effet le plus évident est de savoir si l'apostrophe (') est codée en ' (pour ENT_HTML401) ou ' (pour les autres). De même, il détermine si ' est décodé ou non lors de l'utilisation de html_entity_decode. (' est toujours décodé).

Toutes les utilisations se trouvent dans ext/standard/html.c et son fichier d'en-tête. Depuis ext/standard/html.h:

#define ENT_HTML_DOC_HTML401            0
#define ENT_HTML_DOC_XML1                       16
#define ENT_HTML_DOC_XHTML                      32
#define ENT_HTML_DOC_HTML5                      (16|32)

(remplacez ENT_HTML_DOC_ par ENT_ pour obtenir leurs PHP noms constants)

J'ai commencé à rechercher toutes les occurrences de ces constantes et je peux partager ce qui suit sur le comportement des constantes ENT_*:

  • Il affecte quelles entités numériques seront décodées ou non. Par exemple,  est décodé en un caractère illisible/invalide pour ENT_HTML401, et ENT_XHTML et ENT_XML1. Pour ENT_HTML5 cependant, ceci est considéré comme un caractère invalide et donc il reste . ( fonction C unicode_cp_is_allowed )
  • Lorsque ENT_SUBSTITUTE est activé, les séquences d'unité de code non valides pour un jeu de caractères spécifié sont remplacées par . (ne dépend pas du type de document!)
  • Lorsque ENT_DISALLOWED est activé, les points de code qui sont interdits pour le type de document spécifié sont remplacés par . (ne dépend pas du jeu de caractères!)
  • Avec ENT_IGNORE, les mêmes séquences d'unité de code invalides de ENT_SUBSTITUTE sont supprimées et aucun remplacement n'est effectué (dépend du choix du "type de document", par exemple ENT_HTML5)
  • Interdire 
 pour ENT_HTML5 ( ligne 976 )
  • ENT_XHTML partage la mappe d'entité avec ENT_HTML401. La seule différence est que ' sera converti en apostrophe avec ENT_XHTML tandis que ENT_HTML401 ne le convertit pas (voir cette ligne )
  • ENT_HTML401 et ENT_XHTML utilisent exactement la même carte d'entité (moins la différence par rapport au point précédent). ENT_HTML5 utilise sa propre carte. D'autres (actuellement ENT_XML1) ont une carte de décodage très limitée (>, &, <, ', " et leurs équivalents numériques). (voir fonction C unescape_inverse_map )
  • Remarque pour le point précédent: lorsque seules quelques entités doivent être échappées (pensez à htmlspecialchars), toutes les mappes d'entités utiliseront la même que ENT_XML1, à l'exception de ENT_HTML401. Celui-ci n'utilisera pas ', mais '.

Cela couvre presque tout. Je ne vais pas lister toutes les différences d'entité, mais je voudrais pointer https://github.com/php/php-src/tree/php-5.4.11/ext/standard/html_tables = pour certains fichiers texte contenant les mappages de chaque type.

Quel ENT_ * dois-je utiliser pour htmlspecialchars?

Lorsque vous utilisez htmlspecialchars avec ENT_COMPAT (par défaut) ou ENT_NOQUOTES, peu importe celui que vous choisissez (voir ci-dessous). J'ai vu quelques réponses ici sur SO qui se résume à ceci:

<input value="<?php echo htmlspecialchars($str, ENT_HTML5);?>" >

C'est non sécurisé . Il remplacera la valeur par défaut ENT_HTML401 | ENT_COMPAT qui a pour différence que les entités HTML5 sont utilisées, mais aussi que les guillemets ne sont plus échappés! De plus, il s'agit d'un code redondant. Les entités qui doivent être encodées par htmlspecialchars sont les mêmes pour tous ENT_HTML401, ENT_HTML5, etc.

Utilisez simplement ENT_COMPAT ou ENT_QUOTES à la place. Ce dernier fonctionne également lorsque vous utilisez des apostrophes pour les attributs (value='foo'). Si vous n'avez que deux arguments pour htmlspecialchars, n'incluez pas du tout l'argument car c'est la valeur par défaut (ENT_HTML401 est 0, vous vous souvenez?).

Lorsque vous souhaitez imprimer quelque chose sur la page (entre les balises, pas les attributs), peu importe celui que vous choisissez car cela aura un effet égal. Il suffit même d'utiliser ENT_NOQUOTES | ENT_HTML401 qui est égal à la valeur numérique 0.

Voir également ci-dessous, sur ENT_SUBTITUTE et ENT_DISALLOWED.

Quel ENT_ * dois-je utiliser pour les htmlentities?

Si votre éditeur de texte ou votre base de données est tellement nul que vous ne pouvez pas inclure de caractères non US-ASCII (par exemple UTF-8), vous pouvez utiliser htmlentities. Sinon, enregistrez quelques octets et utilisez plutôt htmlspecialchars (voir ci-dessus).

Que vous ayez besoin d'utiliser ENT_HTML401, ENT_HTML5 ou autre chose dépend de la façon dont votre page est diffusée. Lorsque vous avez une page HTML5 (<!doctype html>), utilisez ENT_HTML5. XHTML ou XML? Utilisez le ENT_XHTML ou ENT_XML1 correspondant. En l'absence de doctype ou de HTML4 simple, utilisez ENT_HTML401 (qui est la valeur par défaut lorsqu'il est omis).

Dois-je utiliser ENT_DISALLOWED, ENT_IGNORE ou ENT_SUBSTITUTE?

Par défaut, les séquences d'octets invalides pour le jeu de caractères donné sont supprimées. Pour avoir un à la place d'une séquence d'octets invalide, spécifiez ENT_SUBSTITUTE. (notez que &#FFFD; est affiché pour les jeux de caractères non UTF-8). Cependant, lorsque vous spécifiez ENT_IGNORE, ces caractères ne sont pas affichés même si vous avez spécifié ENT_SUBSTITUTE.

Les caractères non valides pour un type de document sont remplacés par le même caractère de remplacement (ou son entité) ci-dessus lorsque ENT_DISALLOWED est spécifié. Cela se produit indépendamment du fait que ENT_IGNORE soit défini (ce qui n'a rien à voir avec les caractères invalides pour les doctypes).

86
Lekensteyn