Domanda

Ho un semplice script che accetta un file CSV e legge ogni riga in un array. Quindi scorrevo ogni colonna della prima riga (nel mio caso contiene le domande di un sondaggio) e le stampino. Il sondaggio è in francese e ogni volta che il primo personaggio di una domanda è un personaggio speciale (É, ê, ç, ecc.) FGETCSV semplicemente lo omette.

I caratteri speciali nel mezzo del valore non sono interessati solo quando sono il primo personaggio.

Ho provato a eseguire il debug ma sono sconcertato. Ho fatto un var_dump con il contenuto del file e i personaggi sono sicuramente lì:

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

Ed ecco il mio codice:

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

    }
È stato utile?

Soluzione

Hai già verificato il Pagina manuale su FGETCSV? Non c'è nulla che parli di quel problema specifico, ma forse un numero di contributi che vale la pena esaminare se non arriva nulla qui.

C'è questo, per esempio:

NOTA: l'impostazione locale viene presa in considerazione da questa funzione. Se Lang è EG EN_US.UTF-8, i file nella codifica a un byte vengono letti errati da questa funzione.

Inoltre, visto che è sempre all'inizio della linea, potrebbe essere che questo sia davvero un problema di interruzione della linea nascosta? C'è questo:

Nota: se PHP non riconosce correttamente le finali della linea quando si legge i file accesi o creati da un computer Macintosh, abilitando l'opzione di configurazione di runtime AUTO_DETECT_LINE_ENDINGS può aiutare a risolvere il problema.

Potresti anche provare a salvare il file con terminazioni di linea diverse.

Altri suggerimenti

Stai impostando correttamente la tua locale prima di chiamare fgetcsv()?

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

Altrimenti, fgetcsv() non è sicuro multi-byte.

Assicurati di impostarlo su qualcosa che appare nel tuo elenco di locali disponibili. Su Linux (certamente su Debian) puoi vederlo facendo

locale -a

Dovresti ottenere qualcosa di simile ...

C
en_US.utf8
POSIX

Per il supporto UTF8 scegliere una codifica con UTF8 alla fine. Se il tuo input è codificato con qualcos'altro dovrai utilizzare la localizzazione appropriata, ma assicurati che il tuo sistema operativo lo supporti prima.

Se si imposta il locale su un locale che non è disponibile sul tuo sistema, non ti aiuterà.

Questo comportamento ha un riportare un errore presentato per questo, ma a quanto pare non è un bug.

Abbiamo visto lo stesso risultato con LANG impostato C, e ha lavorato attorno a esso garantendo che tali valori fossero avvolti in virgolette. Ad esempio, la linea

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

genera il seguente array quando è passato fgetcsv():

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

Naturalmente, dovrai sfuggire a eventuali virgolette nel valore raddoppiandoli, ma è molto meno seccata della riparazione dei personaggi mancanti.

Stranamente, questo accade con le codifiche UTF-8 e CP1252 per il file di input.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top