¡FGETCSV () ignora los caracteres especiales cuando están al comienzo de la línea!

StackOverflow https://stackoverflow.com/questions/2238971

  •  19-09-2019
  •  | 
  •  

Pregunta

Tengo un script simple que acepta un archivo CSV y lee cada fila en una matriz. Luego recorro cada columna de la primera fila (en mi caso, contiene las preguntas de una encuesta) y las imprimo. La encuesta está en francés y cada vez que el primer personaje de una pregunta es un personaje especial (é, ê, ç, etc.) fgetcsv simplemente omite.

Los caracteres especiales en el medio del valor no se ven afectados solo cuando son el primer personaje.

Traté de depurar esto pero estoy desconcertado. Hice un var_dump con el contenido del archivo y los caracteres definitivamente están allí:

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

Y aquí está mi código:

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 />";
        }

    }
¿Fue útil?

Solución

¿Ya has revisado el página manual en fgetcsv? No hay nada que hable sobre ese problema específico, pero una serie de contribuciones tal vez valga la pena mirar si no sale nada aquí.

Ahí está esto, por ejemplo:

NOTA: Esta función tiene en cuenta la configuración local. Si Lang es EG EN_US.UTF-8, esta función leen mal los archivos en la codificación de un byte.

Además, ya que siempre está al comienzo de la línea, ¿podría ser que este es realmente un problema de descanso de línea oculta? Ahí está esto:

Nota: Si PHP no reconoce correctamente las terminaciones de línea al leer archivos o creado por una computadora Macintosh, habilitar la opción de configuración de tiempo de ejecución Auto_Detect_Line_endings puede ayudar a resolver el problema.

También puede intentar guardar el archivo con diferentes terminaciones de línea.

Otros consejos

¿Está configurando su localidad correctamente antes de llamar fgetcsv()?

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

De lo contrario, fgetcsv() no es seguro de múltiples bytes.

Asegúrese de establecerlo en algo que aparezca en su lista de lugares disponibles. En Linux (ciertamente en Debian) puedes ver esto haciendo

locale -a

Deberías obtener algo como ...

C
en_US.utf8
POSIX

Para UTF8 Support Elija una codificación con UTF8 al final. Si su entrada está codificada con algo más que necesitará usar la localidad apropiada, pero asegúrese de que su sistema operativo lo admita primero.

Si establece la configuración regional en un lugar que no está disponible en su sistema, no lo ayudará.

Este comportamiento tiene un informe de error lo solicitó, pero aparentemente no es un error.

Vimos el mismo resultado con LANG ajustado a C, y trabajó a su alrededor asegurando que tales valores estuvieran envueltos en comillas. Por ejemplo, la línea

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

genera la siguiente matriz cuando se pasa fgetcsv():

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

Por supuesto, tendrá que escapar de cualquier comilla en el valor duplicandolas, pero eso es mucho menos problemas que reparar los personajes faltantes.

Curiosamente, esto sucede con las codificaciones UTF-8 y CP1252 para el archivo de entrada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top