PHP не может правильно проанализировать CSV (файл находится в UTF-16LE)

Я пытаюсь проанализировать файл CSV с помощью PHP.
Файл использует запятые как разделитель а также двойные кавычки для полей, содержащих запятую (и), как:

foo,"bar, baz",foo2

Проблема Я сталкиваюсь с тем, что я получаю поля, содержащие запятую (ы) разделены. Я получил:

  • "2
  • rue du ..."

Вместо: 2, rue du ...,


Кодирование:
Файл, кажется, не в UTF8. В начале странные чудовища (видимо не спецификация, выглядит так при преобразовании из ASCII в UTF8: ÿþ) и не отображает акценты.

  • Мой редактор кода (Atom) сообщает, что кодировка UTF-16 LE
  • с помощью mb_detect_encoding() на линиях CSV возвращает ASCII

Но он не может преобразовать:

  • mb_convert_encoding() преобразует из ASCII но возвращает азиатские символы из UTF-16LE
  • iconv() возвращается Примечание: iconv (): неправильная кодировка, преобразование из UTF-16LE/ASCII в UTF8 не допускается.

Синтаксический:
Я пытался разобраться с этим однострочником (см. эти 2 комментария) с помощью str_getcsv():

$csv = array_map('str_getcsv', file($file['tmp_name']));

Я тогда попробовал с fgetcsv() :

$f = fopen($file['tmp_name'], 'r');
while (($l = fgetcsv($f)) !== false) {
$arr[] = $l;
}
$f = fclose($f);

В обоих случаях я получаю свое поле адреса в 2 частях. Но когда я пробую этот пример кода, я получаю правильно проанализированные поля:

$str = 'foo,"bar, baz",foo2,azerty,"ban, bal",doe';
$data = str_getcsv($str);
echo '<pre>' . print_r($data, true) . '</pre>';

Подводя итог с вопросами:

  • Какие символы в начале файла?
  • Как я могу быть уверен в кодировке? (Атом читает файл с UTF-16 LE и не отображает странные символы в начале)
  • Что делает сбой функции синтаксического анализа CSV?
  • Если бы я мог положиться на что-то еще для анализа строк CSV, что я мог бы использовать?

1

Решение

Я наконец решил это сам

Я отправил файл на веб-сайты по обнаружению кодировки, которые вернулись UTF16LE. После проверки о том, что есть UTF16LE он говорит, что имеет BOM (метка байтового порядка).
Мои предыдущие попытки использовали file() который возвращает массив линий файла и с fopen() который возвращает ресурс, но мы все еще разбираем построчно.

Рабочее решение пришло мне в голову о конвертирование всего файла (каждая строка сразу) вместо преобразования каждой строки в отдельности. Вот рабочее решение:

$f = file_get_contents($file['tmp_name']);          // Get the whole file as string
$f = mb_convert_encoding($f, 'UTF8', 'UTF-16LE');   // Convert the file to UTF8
$f = preg_split("/\R/", $f);                        // Split it by line breaks
$f = array_map('str_getcsv', $f);                   // Parse lines as CSV data

Я больше не разделяю поля адреса на внутренние запятые.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector