Suppression incorrecte ou incomplète des caractères multioctets
Je vais avoir quelques problèmes à l'aide du code suivant sur la saisie de l'utilisateur:
htmlentities($string, ENT_COMPAT, 'UTF-8');
Quand une séquence de caractères est détecté PHP lance un avis:
PHP Warning: htmlentities(): Invalid séquence multi-octets en argument /path/to/file.php sur la ligne 123
Ma première pensée a été de supprimer l'erreur, mais c'est lent et mauvaises pratiques:
http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html
Ma deuxième pensée a été d'utiliser la ENT_IGNORE drapeau, mais même le manuel PHP suggère de ne pas utiliser ce:
Ignorer silencieusement code non valide unité de séquences au lieu de renvoyer une chaîne vide. L'utilisation de cette option n'est pas recommandée, car elle » peut avoir des répercussions sur la sécurité.
Un peu de raison qui m'a conduit vers le morceau de code suivant:
//detect encoding
$encoding = mb_detect_encoding($query);
if($encoding != 'UTF-8') {
$query = mb_convert_encoding($query, 'UTF-8', $encoding);
} else {
//strip out invalid utf8 sequences
$query = iconv('UTF-8', 'UTF-8//IGNORE', $query);
}
Malheureusement iconv aussi jette un E_NOTICE lorsqu'il supprime/ignore les caractères non valides:
Si vous ajoutez la chaîne de caractères //TRANSLIT à out_charset translittération est activé. Cela signifie que lorsqu'un personnage ne peut pas être représenté dans la cible de jeu de caractères, il peut être approximée par une ou plusieurs de la même façon à la recherche des personnages. Si vous ajoutez la chaîne de caractères //IGNORER, les caractères qui ne peuvent pas être représentés dans la cible de jeu de caractères sont ignorés. Sinon, str est coupé à partir du premier caractère illégal et un E_NOTICE est généré.
Donc, je suis fondamentalement d'options ici. Je préfère utiliser un essayé et testé bibliothèque pour gérer ce genre de choses que d'essayer avec un peu de l'expression régulière en fonction des solutions que j'ai vu flottait autour.
Donc ce qui m'amène à ma dernière question:
Comment puis-je supprimer séquence de caractères, de manière efficace, en toute sécurité, sans avis/avertissements/erreurs?
ENT_IGNORE
, vous ne voulez pas utiliser //IGNORE
. Ils font la même chose et ont les mêmes implications en matière de sécurité. Cela peut être un point évident et un paresseux, mais... ne devrait pas vous cacher ces erreurs dans la production de toute façon? Le point de ces situations jeter un E_NOTICE
est ainsi que l'administrateur du serveur est conscient des problèmes potentiels avec le serveur - caractères non valides ne serait présent si quelqu'un était de les envoyer à des fins malveillantes ou une partie des données a été corrompue, qui exigent tous deux de l'administrateur de l'attention. C'est un extrême à cas en tout cas.Est rejetant validement encodé en UTF-8 une option? Si c'est cassé, vous ne devriez pas l'utiliser pour commencer.
Dave, ouais, les erreurs sont cachés, mais nous sommes à la recherche dans les journaux. C'est un cas limite où quelqu'un était en train d'envoyer de mauvais paramètres, pour une raison ou une autre.
connexes: stackoverflow.com/questions/2327219/...
À partir de article: en PHP 5.4, heureusement, ce problème a disparu. L'erreur ne sera pas plus généré. lire ce
OriginalL'auteur Dean | 2012-03-09
Vous devez vous connecter pour publier un commentaire.
Bien, comme vous l'avez déjà indiqué dans votre question sur votre propre (ou au moins liés), la suppression de la clause de nullité séquence d'octets(s) n'est pas une option.
Au lieu de cela, il devrait être probablement remplacé par le remplacement de caractères U+FFFD. Depuis PHP 5.4.0, vous pouvez faire usage de la
ENT_SUBSTITUTE
drapeau pourhtmlentities
. C'est probablement la plus sûre si vous ne voulez pas de rejeter la chaîne.iconv
toujours de vous donner d'avertissement dans les dernières versions de PHP, si ce n'est la suppression de l'ensemble de la chaîne. De sorte qu'il ne ressemble pas à une bonne alternative pour vous.OriginalL'auteur hakre
iconv('UTF-8', "ISO-8859-1//IGNORE", $string);
a très bien fonctionné pour moi. Ne semble pas générer de tout avis.
OriginalL'auteur Nicholas Pickering