2009-09-03 41 views

risposta

32

A partire da PHP 5.3, è possibile utilizzare str_getcsv() per leggere singole righe utilizzando delimitatori diversi.

$someCondition = someConditionToDetermineTabOrComma(); 

$delimiter = $someCondition ? "," : "\t"; 

$fp = fopen('mydata.csv', 'r'); 

while (!feof($fp)) 
{ 
    $line = fgets($fp, 2048); 

    $data = str_getcsv($line, $delimiter); 

    doSomethingWithData($data); 
}        

fclose($fp); 
+0

Sono arrivato a una soluzione simile. Ho letto il file e cercato la scheda in esso; se non si trova, presumo che il delimitatore sia una virgola. Quindi usa getscv come versione di php è 5.2. Anche se vedo alcuni difetti in questo, non riesco a pensare a qualcosa di meglio. – veli

+0

Forse conteggiare tab e virgole (e altri delimitatori potenziali) sulla prima riga, quindi confrontarli con la seconda riga e così via. Qualunque sia la più consistente è il tuo probabile delimitatore. Una soluzione a due passaggi, sfortunatamente, ma spesso è il modo in cui si ha una tale sconosciuta. – Rikki

0

Leggere l'intero file o riga per riga e dividerlo utilizzando split.

È possibile includere un'espressione regolare con delimitatori arbitrari. Non ho PHP qui per testare una dichiarazione, ma php.net -> cerca split(). C'è anche un commento relativo alla regex.

+0

Ma questo metodo eliminerebbe la funzionalità recinto del getcsv, probabilmente sconfiggendo lo scopo di tutti, ma il più semplice dei file CSV. – dimo414

0

si può provare explode

explode (string $delimiter , string $string [, int $limit ]); 
+0

In un file separato da virgole può essere inserita una virgola tra virgolette che non è considerata un delimitatore. Ecco perché voglio usare getscv, dato che gestisce correttamente tutto ciò. – veli

+0

Questa è ancora una soluzione valida fintanto che si è a conoscenza dei dati con cui si sta lavorando. Inoltre, in genere i dati sono formati csv è qualificato doppia citazione - questo impedisce problemi con l'esplosione. Non degno di un voto negativo. Anche questo codice è molto comune in the wild per l'analisi dei dati CSV ... – Radmation

9

È possibile specificare un delimitatore per fgetcsv(). Questo è un esempio di lettura di file delimitati da tabulazioni,

while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) { 
    ... 
} 
+0

Sì, ma può anche essere un file csv. Il problema è come capire con certezza se è csv o tab delemited. – veli

2

Ecco un esempio che leggerà mydata.txt campi CSV

$tab = "\t"; 

$fp = fopen('mydata.txt', 'r'); 

while (!feof($fp)) 
{ 
    $line = fgets($fp, 2048); 

    $data_txt = str_getcsv($line, $tab); 

    //Get First Line of Data over here 
    print_r($data_txt); 
    exit; 
}        

fclose($fp); 
+0

Questo è bello. –

0

Ecco la funzione che ho aggiunto alla mia biblioteca utilità per un utilizzo futuro. L'ho derivato da NSSec's answer.

Questa soluzione consente di specificare se si desidera utilizzare la prima riga come chiavi per l'array. Probabilmente aggiungerò la possibilità di passare un array da utilizzare per le chiavi per il parametro $ first_line_keys ad un certo punto.

/** 
* Converts a CSV file into an array 
* NOTE: file does NOT have to have .csv extension 
* 
* $file - path to file to convert (string) 
* $delimiter - field delimiter (string) 
* $first_line_keys - use first line as array keys (bool) 
* $line_lenght - set length to retrieve for each line (int) 
*/ 
public static function CSVToArray($file, $delimiter = ',', $first_line_keys = true, $line_length = 2048){ 

    // file doesn't exist 
    if(!file_exists($file)){ 
     return false; 
    } 

    // open file 
    $fp = fopen($file, 'r'); 

    // add each line to array 
    $csv_array = array(); 
    while(!feof($fp)){ 

     // get current line 
     $line = fgets($fp, $line_length); 

     // line to array 
     $data = str_getcsv($line, $delimiter); 

     // keys/data count mismatch 
     if(isset($keys) && count($keys) != count($data)){ 

      // skip to next line 
      continue; 

     // first line, first line should be keys 
     }else if($first_line_keys && !isset($keys)){ 

      // use line data for keys 
      $keys = $data; 

     // first line used as keys 
     }else if($first_line_keys){ 

      // add as associative array 
      $csv_array[] = array_combine($keys, $data); 

     // first line NOT used for keys 
     }else{ 

      // add as numeric array 
      $csv_array[] = $data; 

     } 

    } 

    // close file 
    fclose($fp); 

    // nothing found 
    if(!$csv_array){ 
     return array(); 
    } 

    // return csv array 
    return $csv_array; 

} // CSVToArray() 
0
$filePath = "somefile.txt"; 
$delimiter = "\t"; 

$file = new \SplFileObject($filePath); 
while (!$file->eof()) { 
    $line = $file->fgetcsv($delimiter); 
    print_r($line); 
} 
+0

Aggiungi alcune spiegazioni alla tua risposta per renderla più preziosa per gli altri utenti. – wmk

Problemi correlati