Обнаружение кодировки файлов в PHP
У меня есть script, который объединяет несколько файлов в один, и он ломается, когда один из файлов имеет кодировку UTF8. Я полагаю, что при чтении файлов я должен использовать функцию utf8_decode()
, но я не знаю, как определить, какая необходимость декодировать.
Мой код в основном:
$output = '';
foreach ($files as $filename) {
$output .= file_get_contents($filename) . "\n";
}
file_put_contents('combined.txt', $output);
В настоящее время в начале файла UTF8 он добавляет эти символы в вывод: 
Ответы
Ответ 1
Попробуйте использовать функцию mb_detect_encoding
. Эта функция проверит вашу строку и попытается "угадать" ее кодировку. Затем вы можете конвертировать его по желанию. Однако, как предположил Брулак, вам, вероятно, лучше перейти на UTF-8, чем на сохранение данных, которые вы передаете.
Ответ 2
Чтобы убедиться, что вывод 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!
Ответ 3
Функция mb_detect_encoding
должна быть вашим последним выбором. Это может вернуть неправильную кодировку. Командный file -i/path/myfile.txt
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;
}
Ответ 4
Это мое решение, которое работает как шарм:
//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
}
Ответ 5
Как вы собираетесь обрабатывать символы не ASCII из файла UTF-8 или 16 или 32?
Я спрашиваю, потому что я думаю, что у вас может быть проблема дизайна здесь.
Я бы преобразовал ваш выходной файл в UTF-8 (или 16 или 32), а не наоборот.
Тогда у вас не будет этой проблемы.
Рассматривали ли вы также вопросы безопасности, которые могут возникнуть при преобразовании кода UTF-8, которому удалось избежать? Смотрите этот комментарий:
Обнаружение многобайтового кодирования
Выясните, в какой кодировке находится ваш исходный файл, затем конвертируйте его в UTF-8, и все будет хорошо.
Ответ 6
Я недавно столкнулся с этой проблемой, и mb_convert_encoding()
функции mb_convert_encoding()
был UTF-8.
Взглянув на заголовки ответа, ничего не упоминало о типе кодировки, поэтому я обнаружил, что для HTTP-заголовка Set UTF-8 используется PHP, что предлагает следующее:
<?php
header('Content-Type: text/html; charset=utf-8');
После добавления этого в верхнюю часть PHP файла все забавные символы исчезли, и он рендерился, как и должно быть. Я не уверен, что это проблема, которую искал оригинальный постер, но я нашел это, пытаясь решить проблему самостоятельно, и решил, что поделюсь.
Ответ 7
Для серверов Linux я использую эту команду:
$file = 'your/file.ext'
exec( "from='file -bi $file | awk -F'=' '{print $2 }'' && iconv -f \$from -t utf-8 $file -o $file" );
Ответ 8
Сканирует весь файл, находит любую кодировку из 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;
}