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 кодировки для входного файла.