Dans les normes ISO-8859-1 et ISO-8859-15, le caractère numéro 146 est un caractère de contrôle. MW
(Message en attente) à partir du Gamme C1 .
SGML fait référence à ISO 8859-1 (attention à l'espace entre ISO et 8859-1, qui n'est pas un trait d'union comme dans les jeux de caractères que vous utilisez). Il n'autorise pas les caractères de contrôle, mais trois (ici : SGML en HTML ):
Dans le jeu de caractères du document HTML, seuls trois caractères de contrôle sont autorisés : Horizontal tabulation horizontale, le retour chariot et le saut de ligne (positions de code 9, 13 et 10).
Vous avez donc transmis un caractère illégal. Il n'existe pas d'entité SGML/HTML pour le remplacer.
Je vous suggère de valider les données qui entrent dans votre application afin de vous assurer qu'elles n'autorisent pas les caractères de contrôle. Si vous pensez que ces caractères représentaient à l'origine quelque chose d'utile, comme une lettre qui peut être lue (c'est-à-dire pas un caractère de contrôle), il est probable que lorsque vous traitez les données, l'encodage est cassé à un moment donné.
D'après les informations fournies dans votre question, il est difficile de dire où, car vous ne spécifiez que l'encodage d'entrée et l'encodage de la base de données déposée - mais ces deux-là ne correspondent déjà pas (ce qui ne devrait pas produire le problème que vous demandez, mais qui peut en produire d'autres). En plus de ces deux endroits, il y a aussi le charset de connexion du client à la base de données (non spécifié dans votre question), l'encodage de sortie (non spécifié dans votre question) et l'encodage du contenu de la réponse (non spécifié dans votre question).
Il pourrait être logique de modifier votre encodage global en UTF-8 pour prendre en charge un plus grand nombre de caractères, mais il s'agit en réalité d'une pourrait .
Edita: La partie ci-dessus est en quelque sorte un point de vue strict. Il m'est venu à l'esprit que l'entrée que vous recevez n'est pas ISO-8859-1(5) mais quelque chose d'autre, comme une page de code Windows. Je dirais probablement que c'est Windows-1252 (cp1252) Wkipedia . Par rapport à la gamme C1 de l'ISO-8859-1 (128-159), il comporte plusieurs caractères de non-contrôle.
La page Wikipedia indique également que la plupart des navigateurs traitent ISO-8859-1 comme Windows-1252/CP1252/CP-1252. La page PHP htmlentities()
fonction n'est pas en mesure de traiter ces caractères, le table de traduction pour les entités HTML ne couvre pas les points de code (PHP 5.3, non testé avec 5.4). Vous devez créer votre propre table de traduction et l'utiliser avec strtr
pour remplacer les caractères non disponibles dans la norme ISO 8859-15 pour Windows-1252 :
/*
* mappings of Windows-1252 (cp1252) 128 (0x80) - 159 (0x9F) characters:
* @link http://en.wikipedia.org/wiki/Windows-1252
* @link http://www.w3.org/TR/html4/sgml/entities.html
*/
$cp1252HTML401Entities = array(
"\x80" => '€', # 128 -> euro sign, U+20AC NEW
"\x82" => '‚', # 130 -> single low-9 quotation mark, U+201A NEW
"\x83" => 'ƒ', # 131 -> latin small f with hook = function = florin, U+0192 ISOtech
"\x84" => '„', # 132 -> double low-9 quotation mark, U+201E NEW
"\x85" => '…', # 133 -> horizontal ellipsis = three dot leader, U+2026 ISOpub
"\x86" => '†', # 134 -> dagger, U+2020 ISOpub
"\x87" => '‡', # 135 -> double dagger, U+2021 ISOpub
"\x88" => 'ˆ', # 136 -> modifier letter circumflex accent, U+02C6 ISOpub
"\x89" => '‰', # 137 -> per mille sign, U+2030 ISOtech
"\x8A" => 'Š', # 138 -> latin capital letter S with caron, U+0160 ISOlat2
"\x8B" => '‹', # 139 -> single left-pointing angle quotation mark, U+2039 ISO proposed
"\x8C" => 'Œ', # 140 -> latin capital ligature OE, U+0152 ISOlat2
"\x8E" => 'Ž', # 142 -> U+017D
"\x91" => '‘', # 145 -> left single quotation mark, U+2018 ISOnum
"\x92" => '’', # 146 -> right single quotation mark, U+2019 ISOnum
"\x93" => '“', # 147 -> left double quotation mark, U+201C ISOnum
"\x94" => '”', # 148 -> right double quotation mark, U+201D ISOnum
"\x95" => '•', # 149 -> bullet = black small circle, U+2022 ISOpub
"\x96" => '–', # 150 -> en dash, U+2013 ISOpub
"\x97" => '—', # 151 -> em dash, U+2014 ISOpub
"\x98" => '˜', # 152 -> small tilde, U+02DC ISOdia
"\x99" => '™', # 153 -> trade mark sign, U+2122 ISOnum
"\x9A" => 'š', # 154 -> latin small letter s with caron, U+0161 ISOlat2
"\x9B" => '›', # 155 -> single right-pointing angle quotation mark, U+203A ISO proposed
"\x9C" => 'œ', # 156 -> latin small ligature oe, U+0153 ISOlat2
"\x9E" => 'ž', # 158 -> U+017E
"\x9F" => 'Ÿ', # 159 -> latin capital letter Y with diaeresis, U+0178 ISOlat2
);
$outputWithEntities = strtr($output, $cp1252HTML401Entities);
Si vous voulez être encore plus sûr, vous pouvez éviter les entités nommées et ne prendre que les entités numériques, ce qui devrait également fonctionner dans les très vieux navigateurs :
$cp1252HTMLNumericEntities = array(
"\x80" => '€', # 128 -> euro sign, U+20AC NEW
"\x82" => '‚', # 130 -> single low-9 quotation mark, U+201A NEW
"\x83" => 'ƒ', # 131 -> latin small f with hook = function = florin, U+0192 ISOtech
"\x84" => '„', # 132 -> double low-9 quotation mark, U+201E NEW
"\x85" => '…', # 133 -> horizontal ellipsis = three dot leader, U+2026 ISOpub
"\x86" => '†', # 134 -> dagger, U+2020 ISOpub
"\x87" => '‡', # 135 -> double dagger, U+2021 ISOpub
"\x88" => 'ˆ', # 136 -> modifier letter circumflex accent, U+02C6 ISOpub
"\x89" => '‰', # 137 -> per mille sign, U+2030 ISOtech
"\x8A" => 'Š', # 138 -> latin capital letter S with caron, U+0160 ISOlat2
"\x8B" => '‹', # 139 -> single left-pointing angle quotation mark, U+2039 ISO proposed
"\x8C" => 'Œ', # 140 -> latin capital ligature OE, U+0152 ISOlat2
"\x8E" => 'Ž', # 142 -> U+017D
"\x91" => '‘', # 145 -> left single quotation mark, U+2018 ISOnum
"\x92" => '’', # 146 -> right single quotation mark, U+2019 ISOnum
"\x93" => '“', # 147 -> left double quotation mark, U+201C ISOnum
"\x94" => '”', # 148 -> right double quotation mark, U+201D ISOnum
"\x95" => '•', # 149 -> bullet = black small circle, U+2022 ISOpub
"\x96" => '–', # 150 -> en dash, U+2013 ISOpub
"\x97" => '—', # 151 -> em dash, U+2014 ISOpub
"\x98" => '˜', # 152 -> small tilde, U+02DC ISOdia
"\x99" => '™', # 153 -> trade mark sign, U+2122 ISOnum
"\x9A" => 'š', # 154 -> latin small letter s with caron, U+0161 ISOlat2
"\x9B" => '›', # 155 -> single right-pointing angle quotation mark, U+203A ISO proposed
"\x9C" => 'œ', # 156 -> latin small ligature oe, U+0153 ISOlat2
"\x9E" => 'ž', # 158 -> U+017E
"\x9F" => 'Ÿ', # 159 -> latin capital letter Y with diaeresis, U+0178 ISOlat2
);
J'espère que cela vous sera plus utile. Voir aussi la page Wikipedia liée ci-dessus pour quelques caractères qui sont dans Windows-1242 et ISO 8859-15 mais à différents endroits. Vous devriez probablement envisager d'utiliser UTF-8 sur votre site web.