Aller au contenu

Détection encodage de fichier


Sujets conseillés

Posté

Une question, somme toute très bête :

Peut-on détecter l'encodage d'un fichier en PHP ?

ou Comment savoir que tel fichier est écrit en UTF-8, en ISO-8859-x, en "Windows" ???

S'il est possible de forcer l'encodage en paramètre, par exemple : la function htmlentities(), c'est que la détection se fait, puisqu'il existe aussi des fonctions utf8_***

Alors comment est-il possible avant de lire un fichier de connaître son encodage ?!

Guest fandeholly
Posté

je ne vois pas trop l'interet de detecter l'encodage pour un script php, de toute façon tu ne peux qu'inclure des fichiers que tu possède donc normalement tu connais l'encodage...c'est surtout pour les navigateurs que c'est utile, et dans ce cas là les balises meta sont utiles.

Posté
je ne vois pas trop l'interet de detecter l'encodage pour un script php, de toute façon tu ne peux qu'inclure des fichiers que tu possède donc normalement tu connais l'encodage...c'est surtout pour les navigateurs que c'est utile, et dans ce cas là les balises meta sont utiles.

Justement, si je pose la question, c'est que j'y ai un intérêt...

Et, justement, pour l'explication, je développe en ce moment un "produit"...

normalement, avec des fichiers txt en encodage UTF-8, mais il permet l'intégration de fichiers qui ne sont pas miens...

Hors, je ne peux être sûr que l'utilisateur final, créera et fera l'effort d'un encodage similaire !

D'où la raison de ma question !?!

Posté

Une solution serait de vérifier la présence des chaines utf-8 les plus courantes dans ton fichier (ie. chercher les "é", "à", "è", etc.). Ce n'est pas super-propre, mais ça doit marcher.

Pour être propre, tu devrais vérifier que le fichier, au niveau binaire, est valide "utf8-ment parlant", c'est à dire que les octets 10xxxxxx sont uniquement présent après des octets 11xxxxxxxx (à moins que ce ne soit l'inverse), et des trucs dans le genre. Seulement ça doit être bien moins rapide que la première solution, et pas forcément plus efficace.

C'est toutes les idées qui me viennent à l'instant... C'est pas très "bon" mais c'est tout.

Il n'y a pas de propriété intrinsèque au fichier qui permette de savoir si c'est de l'utf-8 ou non (à part les éventuels premiers octets optionnels déclarant un encodage UTF-8, voir topic récent à ce sujet), c'est bêtement parce que les fichiers textes sont une suite de bits sans structure complexe. Donc tu ne pourras jamais que faire une estimation plus ou moins correcte du jeu de caractère. Ceci dit, un texte ne comportant que les caractères ASCII peut être considéré comme UTF-8 ou iso-8859-1 sans distinction.

Posté

On peut facilement récuperer le format d'un fichier en analysant ses header.

Je fais référence à ceci :

http://xethorn.net/articles/1/page-3.html.

Dans ton header, tu auras un

Content-Type: text/html; charset=ISO-8859-1

C'est ce qui te permettra de définir : le type de ta page (fichier html, png et j'en passe) ainsi que l'encodage utilisé.

Bonne fin de journée,

Xethorn

Posté
Ceci dit, un texte ne comportant que les caractères ASCII peut être considéré comme UTF-8 ou iso-8859-1 sans distinction.

Tout le soucis est là...

Si le caractère est un caractère accentué, encodé en ISO-8859 et non UTF-8, bonjour les hyeroglyphes :blush: !

Je vais étudier ta solution...

  • 2 semaines plus tard...
Posté

Ça c'est une petite fonction que j'ai faite pour un site qui travaille avec des fichiers texte en utf-8. Ça peut peut-être être utile pour savoir si un fichier est en utf-8 valide. Ça retourne true si l'utf-8 est valide, false sinon. Désolé, le forum fait sauter les tabulations <_<

function XhtmlSpecialChars($str)
{
$str = str_replace('&', '&', $str);
$str = str_replace('<', '<', $str);
$str = str_replace('>', '>', $str);

return $str;
}

function VerifyUtf8($str)
{
$nLength = strlen($str);
$iDst = 0;
$nByteSequence = 0;
$nUcs4 = 0;

for($iSrc = 0; $iSrc < $nLength; ++$iSrc)
{
 $nByte = ord($str[$iSrc]);

 if( $nByteSequence == 0)
 {
 $nUcs4 = 0;

 if( $nByte <= 0x7F)
 {
   // ascii
   $iDst++;
 }
 else if( ($nByte & 0xE0) == 0xC0)
 {
   // 110xxxxx 10xxxxxx
   $nUcs4 = $nByte & 0x1F;
   $nByteSequence = 1;
 }
 else if( ($nByte & 0xF0) == 0xE0)
 {
   // 1110xxxx 10xxxxxx 10xxxxxx
   $nUcs4 = $nByte & 0x0F;
   $nByteSequence = 2;
 }
 else if( ($nByte & 0xF8) == 0xF0)
 {
   // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
   $nUcs4 = $nByte & 0x07;
   $nByteSequence = 3;
 }
 else if( ($nByte & 0xFC) == 0xF8)
 {
   // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
   $nUcs4 = $nByte & 0x03;
   $nByteSequence = 4;
 }
 else if( ($nByte & 0xFE) == 0xFC)
 {
   // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
   $nUcs4 = $nByte & 0x01;
   $nByteSequence = 5;
 }
 else
 {
   // Bad byte sequence starter
   $strBeg = substr($str, 0, $iSrc);
   $strBeg = XhtmlSpecialChars($strBeg);
   echo "<p>$strBeg <-- BAD UTF-8 SEQUENCE STARTER</p>";
   return false;
 }
 }
 else
 {
 // Remaining bytes
 if( ($nByte & 0xC0) != 0x80)
 {
   // Bad byte in sequence
   $strBeg = substr($str, 0, $iSrc);
   $strBeg = XhtmlSpecialChars($strBeg);
   echo "<p>$strBeg <-- BAD UTF-8 SEQUENCE BYTE</p>";
   return false;
 }

 $nUcs4 <<= 6;
 $nUcs4 |= ($nByte & 0x3F);
 $nByteSequence--;

 if( $nByteSequence == 0)
 {
   // OK - Store
   //nUcs4
   $iDst++;
 }
 }
}
return true;
}

Posté (modifié)

Bonjour,

Je croyais que mon message avait été validé mais non :(

Donc, il est possible d'afficher l'encodage sans detection des caractères. On peut le faire par protocole HTTP, il suffit de se connecter au fichier en emetant la supposition que ce soit distant.

Les header reçu avant le contenu du fichier seront comme ça :

HTTP/1.1 200 OK

Date: Sun, 06 Jun 2004 07:36:49 GMT

Server: Apache/2.0.49 (Unix) DAV/2 PHP/5.0.0RC2

X-Powered-By: PHP/5.0.0RC2

Connection: close

Content-Type: text/html; charset=ISO-8859-1

La ligne Content-Type contient le charset.

Si je ne fais pas d'erreurs, voici un script qui te sera utile :

<?php
// Ouverture du socket
$fp = fsockopen("www.webmaster-hub.com", 80, $errno, $errstr, 30);
// En cas d'erreur
if (!$fp) {
// Affichage
 echo "$errstr ($errno)<br />\n";
}
else {
// Envoi des informations
 $out = "GET / HTTP/1.1\r\n";
 $out .= "Host: www.webmaster-hub.com\r\n";
 $out .= "Connection: Close\r\n\r\n";
 fwrite($fp, $out);

 // Lecture du header
while ($str = _AT_trim(@fgets($fp, 4096)))
$headers .= "$str\n";
echo $headers;
 // Fermeture
 fclose($fp);
}
?>

Ensuite, essaye avec mon site (le mien est encodé en UTF-8), adresse : www.xethorn.net.

En esperant que ce mp n'aura pas été inutile,

Xethorn

Modifié par Xethorn

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...