web-dev-qa-db-ja.com

PHPでファイルエンコーディングを検出

多数のファイルを1つに結合するスクリプトがあり、ファイルの1つにUTF8エンコードが含まれていると壊れます。私は、ファイルを読み取るときにutf8_decode()関数を使用する必要があると考えていますが、デコードの必要性を判断する方法がわかりません。

私のコードは基本的に:

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

現在、UTF8ファイルの開始時に、次の文字が出力に追加されます:

24
nickf

mb_detect_encoding function 。この関数は文字列を調べ、そのエンコーディングが何であるかを「推測」しようとします。その後、必要に応じて変換できます。 brulak推奨 のように、送信するデータを保持するためにfromよりもto UTF-8に変換する方がおそらく良いでしょう。 。

29
Ben Blank

出力がUTF-8であることを確認するには、入力の種類に関係なく、これを使用します 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関数は最後に選択する必要があります。 wrong encodingを返す可能性があります。 Linuxコマンドfile -i /path/myfile.txtはうまく機能しています。 PHPで使用できます:

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

これは魅力のように働いた私のソリューションです:

//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

最近この問題に遭遇し、mb_convert_encoding()関数の出力はUTF-8でした。

応答ヘッダーを確認した後、エンコードタイプに言及するものは何もなかったため、PHPを使用してHTTPヘッダーをUTF-8に設定 、次を提案します:

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

それをPHPファイルの先頭に追加すると、ファンキーなキャラクターはすべて消えて、本来のようにレンダリングされました。それが元のポスターが求めていた問題かどうかはわかりませんが、私はこの問題を自分で解決しようとしていることに気付き、共有したいと思いました。

1
Amereservant

すべてのファイルをスキャンし、mb_list_encodingsからあらゆる種類のエンコーディングを見つけます。パフォーマンスは良好です。

    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

Linuxサーバーの場合、次のコマンドを使用します。

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

UTF-8または16または32ファイルの非ASCII文字をどのように処理しますか?

ここでデザインの問題があるかもしれないと思うので、お願いします。

出力ファイルを他の方法ではなくUTF-8(または16または32)に変換します。

その後、この問題は発生しません。

エスケープされたUTF-8コードの変換から生じる可能性のあるセキュリティの問題についても考慮しましたか? このコメントを参照

マルチバイトエンコーディングの検出

ソースファイルのエンコーディングを把握し、UTF-8に変換すれば、準備完了です。

1
cbrulak