2009-02-03 5 views
19

У меня есть скрипт, который объединяет несколько файлов в один, и он ломается, когда один из файлов имеет кодировку UTF8. Я полагаю, что при чтении файлов я должен использовать функцию utf8_decode(), но я не знаю, как определить, какая необходимость декодировать.Обнаружение кодировки файла в PHP

Мой код в основном:

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

В настоящее время, в начале файла UTF8, он добавляет эти символы в выходной: 

ответ

23

Попробуйте использовать mb_detect_encoding function. Эта функция проверит вашу строку и попытается «угадать», что такое ее кодировка. Затем вы можете преобразовать его по желанию. Однако, как и в случае brulak suggested, вы, вероятно, лучше конвертируете в UTF-8, а не от, чтобы сохранить данные, которые вы передаете.

+1

Я сдаюсь. Я не знаю, почему SO разрушает мои ссылки. Выглядит хорошо в предварительном просмотре. : -/ –

+0

Да, вау ... wtf продолжается. Приветствия за ссылку, хотя – nickf

+0

Кажется, была относительная связь, запутанная ... weird – bobince

1

Как вы собираетесь обрабатывать символы не-ASCII из файла UTF-8 или 16 или 32?

Я спрашиваю, потому что я думаю, что у вас может возникнуть проблема с дизайном.

Я бы преобразовал ваш выходной файл в UTF-8 (или 16 или 32), а не наоборот.

Тогда у вас не будет этой проблемы.

Вы также рассмотрели проблемы безопасности, которые могут возникнуть в результате преобразования сбежавшего кода UTF8? See this comment:

Detecting multi-byte encoding

Выяснить, какую кодировку исходного файла в, а затем преобразовать его в UTF8, и вы должны быть хорошо идти.

+0

ok, поэтому я должен преобразовать файлы не UTF-8 в UTF-8 ... как узнать, для чего нужен вызов utf_encode()? – nickf

+0

У вас нет. Вы должны знать, какие данные кодирования находятся. Нет надежного способа определить его, если вы этого не знаете. – troelskn

19

Чтобы убедиться в том, что вывод не является 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! 
+1

Спасибо ... это решило проблему кодирования файла, которую я часами бил головой о кирпичную стену !! – GuruJ

+0

@GuruJ Мне потребовались дни, чтобы получить эту функцию. – powtac

+1

Должно ли '$ content' во втором вызове' mb_convert_encoding' быть '$ output' тоже? В противном случае, откуда происходит '$ content'? – Oliver

1

я недавно столкнулся с этой проблемой, и выход на mb_convert_encoding() функции был UTF- 8. После взглянуть на заголовки ответа, не было ничего, упоминая тип кодирования, так что я нашел Set http header to utf-8 php, которая предлагает следующее:

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

После добавив, что в верхней части файла PHP, все из фанковые персонажи ушли, и они выглядели как следует. Не уверен, что это проблема, которую искал оригинальный плакат, но я нашел это, пытаясь решить проблему сам и подумал, что я поделюсь.

1

Это мое решение, которое работает как шарм:

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

mb_detect_encoding функция должна быть ваш последний выбор. Это может привести к ошибке WRONG. Команда 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; 
} 
+0

лучшее и безопасное решение! – Sangar82

1

Для серверов Linux, я использую эту команду:

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

сканы весь файл, находит любой вид кодирования от 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; 
} 
Смежные вопросы