2012-11-08 4 views
9

Utilizzando la funzione PHP 5.3 fgetcsv, sto riscontrando alcuni problemi dovuti a problemi di codifica. Si noti che quel file ha caratteri latini "speciali" spagnoli come accenti grafici á, é, í ï, ecc ...php fgetcsv - problemi di codifica del charset

Ottengo il file CSV esportando alcuni dati strutturati che ho in un file MS 2008 per Mac Excel.

Se lo apro con l'applicazione Mac OS X TextEdit, tutto sembra perfetto.

Ma quando arrivo al mio programma PHP e provo a leggere il CSV usando quella funzione PHP fgetcsv, non riesco a leggere correttamente il charset.

/** 
* @Route("/cvsLoad", name="_csv_load") 
* @Template() 
*/ 
public function cvsLoadAction(){ 
    //setlocale(LC_ALL, 'es_ES.UTF-8'); 
    $reader = new Reader($this->get('kernel')->getRootDir().'/../web/uploads/documents/question_images/2/41/masiva.csv'); 

    $i = 1; 
    $r = array("hhh" => $reader -> getAll()); 

    return new Response(json_encode($r, 200)); 
} 

Come potete vedere, ho cercato anche di utilizzare un setlocale-es_ES.UTF-8. Ma niente lo fa funzionare.

La parte lettura viene qui:

public function getRow() 
{ 
    if (($row = fgetcsv($this->_handle, 10000, $this->_delimiter)) !== false) { 
     $this->_line++; 
     return $this->_headers ? array_combine($this->_headers, $row) : $row; 
    } else { 
     return false; 
    } 
} 

Vedi quello che ho nella variabile $ fila dopo ogni lettura consecutive:

enter image description here

Quei ? personaggi si suppone siano le vocali con grafica accenti su di loro.

Qualsiasi indizio laggiù? Funzionerebbe se avessi usato MS Excel per Windows? Come posso sapere in tempo di esecuzione la codifica esatta del file e impostarlo prima di leggerlo?

(Per coloro che parlano spagnolo, non spaventarti con cose mediche così terribili in quei testi;)).

+1

stesso problema. Un file CSV con codifica UTF8 importa bene su un server ma non sull'altro. Finito per scrivere il mio lettore CSV. –

+0

FWIW, non puoi davvero * sapere * la codifica di un file senza che ti venga detto. Puoi indovinare quando lo leggi e lo converti di conseguenza, ma nulla è affidabile quanto la codifica. – cmbuckley

+0

Grazie cbuckley. Cosa intendi con "convertire di conseguenza", come cercare di indovinarlo e chiedere all'utente se approva l'importazione? E se no, continua a provare altre codifiche per l'origine? – ElPiter

risposta

28

Prova questo:

function convert($str) { 
    return iconv("Windows-1252", "UTF-8", $str); 
} 

public function getRow() 
{ 
    if (($row = fgetcsv($this->_handle, 10000, $this->_delimiter)) !== false) { 
     $row = array_map("convert", $row); 
     $this->_line++; 
     return $this->_headers ? array_combine($this->_headers, $row) : $row; 
    } else { 
     return false; 
    } 
} 
+2

+1. Nota su [docs] (http://php.net/manual/en/function.fgetcsv.php): se il file è codificato a byte singolo (come CP1252), ma la locale è multibyte, quindi fgetcsv non lavorare come previsto – cmbuckley

+0

Questo era quello !! :) Molte grazie. Solo alcuni commenti: in primo luogo, è necessario dichiarare come static la funzione convertita e mapparla in array_map come 'self: convert'; in secondo luogo, nel mio caso era iconv ("macintosh", "UTF-8", $ str), poiché MS Excel per Mac OS esporta in CSV usando Mac OS Roman. Infine, anche se questa è un'ottima risposta e mi ha davvero aiutato, non è ancora tutto ciò che risolve i miei bisogni, poiché non saprò se i miei utenti caricheranno un file da un Mac o da un PC o qualsiasi altra ... qualsiasi altro indizio su come individuare quale è la codifica del file caricato? Grazie ancora!! – ElPiter

+0

È necessario utilizzare l'euristica ..prima vedere se è UTF-8 o UTF-16 valido, se non lo è, determinare PC/MAC (dall'intestazione dell'agente utente) e utilizzare Windows-1252 per PC e Macintosh per Mac. Ovviamente, se l'utente non usa lo script latin, si usa Windows-1251 (Cyrillic per Windows) e così via. Qualcuno deve aver scritto una libreria per questo: D – Esailija

0

Questo è probabilmente il modo in cui Excel codifica il file durante il salvataggio.

prova a caricare il file .xls per Google Docs e scaricano come .csv

+0

Ho anche provato, ma va ancora peggio credo. Tuttavia, ci riproverò. Grazie per la risposta veloce. :) – ElPiter