fgetcsv() игнорирует специальные символы, когда они находятся в начале строки!

У меня есть простой скрипт, который принимает файл CSV и читает каждую строку в массив. Затем я перебираю каждый столбец первого ряда (в моем случае он содержит вопросы опроса) и распечатываю их. Опрос проводится на французском языке, и когда первым символом вопроса является специальный символ (é,ê,ç и т. Д.), Fgetcsv просто пропускает его.

Специальные символы в середине значения не затрагиваются, только когда они являются первым символом.

Я пытался отладить это, но я сбит с толку. Я сделал var_dump с содержимым файла, и символы определенно есть:

var_dump(utf8_encode(file_get_contents($_FILES['csv_file']['tmp_name'])));

И вот мой код:

if(file_exists($_FILES['csv_file']['tmp_name']) && $csv = fopen($_FILES['csv_file']['tmp_name'], "r"))
    {
        $csv_arr = array();

        //Populate an array with all the cells of the CSV file
        while(!feof($csv))
        {
            $csv_arr[] = fgetcsv($csv);
        }

        //Close the file, no longer needed
        fclose($csv);

        // This should cycle through the cells of the first row (questions)
        foreach($csv_arr[0] as $question)
        {
            echo utf8_encode($question) . "<br />";
        }

    }

4 ответа

Решение

Вы уже проверили страницу руководства на fgetcsv? Об этой конкретной проблеме ничего не говорится, но, возможно, стоит взглянуть на некоторые материалы, если здесь ничего не появится.

Вот это, например:

Примечание: настройка локали учитывается этой функцией. Если LANG, например, en_US.UTF-8, файлы в однобайтовой кодировке считываются неправильно этой функцией.

Кроме того, видя, как это всегда в начале строки, может ли быть, что это действительно скрытая проблема разрыва строки? Там это:

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

Вы также можете попробовать сохранить файл с разными окончаниями строки.

Вы правильно устанавливаете свой язык перед звонком fgetcsv()?

setlocale(LC_ALL, 'fr_FR.UTF-8');

Иначе, fgetcsv() не многобайтово безопасно.

Убедитесь, что вы установили что-то, что появляется в вашем списке доступных локалей. В Linux (конечно, в Debian) вы можете увидеть это, выполнив

locale -a

Вы должны получить что-то вроде...

C
en_US.utf8
POSIX

Для поддержки UTF8 выберите кодировку с utf8 в конце. Если ваши входные данные кодируются чем-то другим, вам нужно использовать соответствующий языковой стандарт, но сначала убедитесь, что ваша ОС поддерживает его.

Если вы установите язык, который не доступен в вашей системе, он вам не поможет.

Это поведение содержит отчет об ошибке, но, очевидно, это не ошибка.

Мы видели тот же результат с LANG установлен в Cи обойти это, убедившись, что такие значения были заключены в кавычки. Например, строка

a,"a",é,"é",óú,"óú",ó&ú,"ó&ú"

генерирует следующий массив при прохождении через fgetcsv():

array (
  0 => 'a',
  1 => 'a',
  2 => '',
  3 => 'é',
  4 => '',
  5 => 'óú',
  6 => '&ú',
  7 => 'ó&ú',
)

Конечно, вам придется избегать любых кавычек в значении, удваивая их, но это гораздо меньше хлопот, чем исправление недостающих символов.

Как это ни странно, это происходит с кодировками UTF-8 и cp1252 для входного файла.

Другие вопросы по тегам