J'ai créé un script PHP qui génère des fichiers CSV précédemment générés par un autre processus. Et puis, les fichiers CSV doivent être importés par un autre processus.
L'importation des anciens fichiers CSV fonctionne bien, mais lors de l'importation des nouveaux fichiers CSV, des problèmes se posent avec les caractères spéciaux.
Lorsque j'ouvre d'anciens CSV avec Notepad ++, il indique que le codage est UTF-8 et, lorsque j'ouvre les nouveaux CSV, il indique que leur codage est «ANSI en tant que UTF-8».
Quelle est la différence des deux?
Et comment puis-je faire en sorte que fopen et fputcsv utilisent le «pur»? Encodage UTF-8?
Merci!
Il n'y a rien de mal avec le fichier. "ANSI en tant que UTF-8" signifie qu'il n'y a pas de nomenclature, mais Notepad ++ a clairement identifié le codage comme étant UTF-8 en analysant les modèles d'octets. J'ai testé cela en créant un fichier avec du texte russe, grec et polonais et en l'enregistrant au format UTF-8 sans nomenclature. C'est ici:
# Russian
Следующая
# Greek
Επόμενη
# Polish
Więcej
Je l'ai fait dans un autre éditeur (EditPad Pro) et j'ai utilisé le mode hexadécimal pour m'assurer que la nomenclature n'y était pas. Lorsque je l'ai ouvert dans NPP, il affichait le codage "ANSI au format UTF-8" et tous les caractères étaient affichés correctement. Puis, toujours en mode hexadécimal, j'ai supprimé le premier octet du premier caractère russe. Lorsque je l'ai ouvert à nouveau dans NPP, il affichait le codage "ANSI" et les parties non-ASCII du texte sous la forme mojibake :
; Russian
¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ
; Greek
Επόμενη
; Polish
Więcej
Retour à EditPad, et cette fois j'ai ajouté une nomenclature mais n'ai pas réparé le caractère cyrillique. Cette fois, la centrale nucléaire a signalé le codage "UTF-8" et tout s’est affiché correctement, à l’exception du premier caractère russe, comme indiqué ci-dessous. "A1" est la représentation hexadécimale de ce qui aurait dû être le deuxième octet de ce caractère dans UTF-8. Il était affiché dans un jeu de couleurs inversé pour indiquer une erreur.
# Russian
A1ледующая
# Greek
Επόμενη
# Polish
Więcej
Pour résumer: En l'absence de nomenclature, Notepad ++ recherche les octets qui ne peuvent pas représenter les caractères ASCII car leurs valeurs sont supérieures à 127 (ou 7F
hex). S'il en trouve, mais qu'ils sont tous conformes aux modèles requis par UTF-8 , il décode le fichier au format UTF-8 et renvoie le codage dans la barre d'état sous le format "ANSI en tant que UTF-8".
Mais s'il trouve même un octet qui ne correspond pas à la ligne UTF-8, il décode le fichier en tant que "ANSI", ce qui signifie le codage à un octet par défaut pour la plate-forme sous-jacente. Si votre fichier avait été corrompu, c'est ce que vous verriez.
ÉDITER: Bien que votre fichier soit valide sans cela, vous pourriez ajouter une nomenclature en écrivant manuellement les trois octets "EF BB BF"
tout au début du fichier - mais il devrait y avoir un meilleur moyen. Comment générez-vous le contenu maintenant? Parce que est UTF-8, avec au moins un caractère non-ASCII dedans quelque part; sinon, la centrale les signalerait comme "ANSI".
Une autre possibilité à envisager: si vous avez une influence sur le processus consommant votre fichier CSV, vous pouvez peut-être le configurer pour qu'il attende UTF-8 sans nomenclature. Techniquement, tout logiciel capable de décoder UTF-8 avec une nomenclature mais pas sans un est en panne. Le consortium Unicode déconseille en fait l’utilisation de la nomenclature UTF-8, ce qui n’est à l’écoute de personne.
Selon les fils de Notepad ++ liés ici et ici , 'ANSI comme UTF-8' indique UTF-8 sans BOM, tandis qu'un «UTF-8» signifie simplement UTF-8 avec BOM. Alors peut-être que le processus de lecture du CSV a besoin de la marque Byte-order pour lire correctement le CSV en UTF-8.
Mais avant d'entrer dans cela, assurez-vous que votre script écrit bien UTF-8! Lorsque vous ouvrez les nouveaux fichiers CSV dans Notepad ++ (et qu'il indique "ANSI en tant que UTF-8"), tous les caractères "spéciaux" sont-ils affichés correctement? Sinon, vous devez adapter votre script pour écrire en UTF-8. Dans l'affirmative, vérifiez la différence de nomenclature.
Essayez de remplacer également votre script PHP par UTF-8. Parfois, il est nécessaire (même s’il peut être contourné) d’avoir le script dans le même encodage des données.
Problème similaire: PHP: Exploser en utilisant des caractères spéciaux
Il est intéressant de noter que ANSI comme UTF-8, c’est-à-dire UTF-8 sans la nomenclature est utile si vous formatez vos fichiers PHP en UTF-8. Si votre fichier PHP renvoie le code HTML au navigateur, la nomenclature est incluse dans la sortie HTML à laquelle le w3c validator met explicitement en garde:
Marque d'ordre d'octet trouvée dans le fichier UTF-8.
La marque de byte-order (BOM) Unicode dans les fichiers codés UTF-8 est connue pour causer des problèmes à certains éditeurs de texte et à des navigateurs plus anciens. Vous voudrez peut-être envisager d'éviter son utilisation jusqu'à ce qu'il soit mieux pris en charge.
De plus, j'ai remarqué que la nomenclature confondait le Firebug de Firefox qui pense maintenant que tout votre contenu <head>
est en réalité dans la balise <body>
.