web-dev-qa-db-fra.com

Détecter l'encodage des fichiers dans PHP

J'ai un script qui combine un certain nombre de fichiers en un seul, et il se casse lorsque l'un des fichiers a un codage UTF8. Je pense que je devrais utiliser la fonction utf8_decode() lors de la lecture des fichiers, mais je ne sais pas comment déterminer le besoin de décodage.

Mon code est essentiellement:

$output = '';
foreach ($files as $filename) {
    $output .= file_get_contents($filename) . "\n";
}
file_put_contents('combined.txt', $output);

Actuellement, au début d'un fichier UTF8, il ajoute ces caractères dans la sortie: 

24
nickf

Essayez d'utiliser le mb_detect_encoding fonction . Cette fonction examinera votre chaîne et tentera de "deviner" quel est son encodage. Vous pouvez ensuite le convertir comme vous le souhaitez. Comme Brulak suggéré , cependant, vous feriez probablement mieux de convertir en UTF-8 plutôt que de , pour conserver les données que vous transmettez.

29
Ben Blank

Pour m'assurer que la sortie est UTF-8, quel que soit le type d'entrée c'était, j'utilise ceci check :

if(!mb_check_encoding($output, 'UTF-8')
    OR !($output === mb_convert_encoding(mb_convert_encoding($output, 'UTF-32', 'UTF-8' ), 'UTF-8', 'UTF-32'))) {

    $output = mb_convert_encoding($content, 'UTF-8', 'pass'); 
}

// $output is now safely converted to UTF-8!
21
powtac

mb_detect_encoding la fonction devrait être votre dernier choix. Cela pourrait renvoyer le codage faux. Commande Linux file -i /path/myfile.txt fonctionne très bien. Dans PHP vous pouvez utiliser:

function _detectFileEncoding($filepath) {
    // VALIDATE $filepath !!!
    $output = array();
    exec('file -i ' . $filepath, $output);
    if (isset($output[0])){
        $ex = explode('charset=', $output[0]);
        return isset($ex[1]) ? $ex[1] : null;
    }
    return null;
}
17
yanek1988m

Voici ma solution qui a fonctionné comme un charme:

//check string strict for encoding out of list of supported encodings
$enc = mb_detect_encoding($str, mb_list_encodings(), true);

if ($enc===false){
    //could not detect encoding
}
else if ($enc!=="UTF-8"){
    $str = mb_convert_encoding($str, "UTF-8", $enc);
}
else {
    //UTF-8 detected
}
2
PapaKai

J'ai récemment rencontré ce problème et la sortie de la fonction mb_convert_encoding() était UTF-8 .

Après avoir jeté un œil aux en-têtes de réponse, il n'y avait rien mentionnant le type d'encodage, donc j'ai trouvé Définir l'en-tête HTTP sur UTF-8 en utilisant PHP, qui propose le suivant:

<?php
header('Content-Type: text/html; charset=utf-8');

Après avoir ajouté cela en haut du fichier PHP, tous les personnages géniaux sont partis et ils se sont rendus comme il se doit. Je ne sais pas si c'est le problème que l'affiche originale recherchait, mais J'ai trouvé cela en essayant de résoudre le problème moi-même et j'ai pensé partager.

1
Amereservant

Analyse tous les fichiers, trouve tout type d'encodage à partir de mb_list_encodings, bonnes performances ..

    function detectFileEncoding($filePath){

    $fopen=fopen($filePath,'r');

    $row = fgets($fopen);
    $encodings = mb_list_encodings();
    $encoding = mb_detect_encoding( $row, "UTF-8, ASCII, Windows-1252, Windows-1254" );//these are my favorite encodings

    if($encoding !== false) {
        $key = array_search($encoding, $encodings) !== false;
        if ($key !== false)
            unset($encodings[$key]);
        $encodings = array_values($encodings);
    }

    $encKey = 0;
    while ($row = fgets($fopen)) {
        if($encoding == false){
            $encoding = $encodings[$encKey++];
        }

        if(!mb_check_encoding($row, $encoding)){
            $encoding =false;
            rewind($fopen);
        }

    }

    return $encoding;
}
1
akakargul

Pour les serveurs Linux, j'utilise cette commande:

$file = 'your/file.ext'
exec( "from=`file -bi $file | awk -F'=' '{print $2 }'` && iconv -f \$from -t utf-8 $file -o $file" );
1
jgpATs2w

Comment allez-vous gérer les caractères non ASCII du fichier UTF-8 ou 16 ou 32?

Je demande parce que je pense que vous pouvez avoir un problème de conception ici.

Je convertirais votre fichier de sortie en UTF-8 (ou 16 ou 32) au lieu de l'inverse.

Vous n'aurez alors pas ce problème.

Avez-vous également pris en compte les problèmes de sécurité pouvant survenir lors de la conversion d'un code UTF-8 échappé? Voir ce commentaire :

Détection du codage multi-octets

Déterminez l'encodage de votre fichier source, puis convertissez-le en UTF-8, et vous devriez être prêt à partir.

1
cbrulak