2011-11-11 11 views
5

Sto caricando un file csv e quindi analizzandolo utilizzando str_getcsv. Tutto funziona alla grande, tranne che ho bisogno di un modo per attraversarli. Idealmente, sarebbe bello avere la matrice tornare e simile a questa:php str_getcsv array issue

Array (  
    [1] => Array 
     (
      [0] => 1 // first id in csv 
      [1] => name 
      [2] => address 
      [3] => town 
      [4] => state 
      [5] => zip 
      [6] => phone 
      [7] => website 
      [8] => other 
      [9] => other 
     ) 
    [22] => Array 
     (
      [10] => name 
      [11] => address 
      [12] => town 
      [13] => state 
      [14] => zip 
      [15] => phone 
      [16] => website 
      [17] => other 
      [18] => other 
     ) 
    [24] => Array 
     (
      [19] => name 
      [20] => address 
      [21] => town 
      [22] => state 
      [23] => zip 
      [24] => phone 
      [25] => website 
      [26] => other 
      [27] => other 
     ) 
) 

Tuttavia i dati ritorna come la seguente:

Array 
(
    [0] => 1 // first id in csv 
    [1] => name 
    [2] => address 
    [3] => town 
    [4] => state 
    [5] => zip 
    [6] => phone 
    [7] => website 
    [8] => other 
    [9] => other 
22 // id field 
    [10] => name 
    [11] => address 
    [12] => town 
    [13] => state 
    [14] => zip 
    [15] => phone 
    [16] => website 
    [17] => other 
    [18] => other 
24// id field 
    [19] => name 
    [20] => address 
    [21] => town 
    [22] => state 
    [23] => zip 
    [24] => phone 
    [25] => website 
    [26] => other 
    [27] => other 

Qualche suggerimento su come risolvere questo problema a guardare come la matrice in alto? In questo momento sto facendo:

$csvfile = file_get_contents($targetFile); 
$csv = str_getcsv($csvfile); 
+0

possibile duplicato di [PHP CSV stringa su matrice] (http://stackoverflow.com/questions/17761172/php-csv-string-to-array) – user

+0

Ho contrassegnato questo come un duplicato nonostante il fatto che questo la domanda è precedente solo perché quella domanda è molto più popolare – user

risposta

11

str_getcsv() aspetta la stringa passata come parametro da uno record.
Ma dal momento che la sorgente è un file in ogni caso il modo più semplice è probabilmente quello di utilizzare fgetcsv() invece di str_getcsv()

$data = array(); 
$fp = fopen($targetFile, 'rb'); 
while(!feof($fp)) { 
    $data[] = fgetcsv($fp); 
} 
fclose($fp); 

autosufficiente esempio:

<?php 
$targetFile = 'soTest.csv'; 
setup($targetFile); 

$data = array(); 
$fp = fopen($targetFile, 'rb'); 
while(!feof($fp)) { 
    $data[] = fgetcsv($fp); 
} 
var_dump($data); 


function setup($targetFile) { 
    file_put_contents($targetFile, <<< eot 
1,name,address,town,state,zip,phone,website,other,other 
2,name,address,town,state,zip,phone,website,other,other 
3,name,address,town,state,zip,phone,website,other,other 
eot 
    ); 
} 

stampe

array(3) { 
    [0]=> 
    array(10) { 
    [0]=> 
    string(1) "1" 
    [1]=> 
    string(4) "name" 
    [2]=> 
    string(7) "address" 
    [3]=> 
    string(4) "town" 
    [4]=> 
    string(5) "state" 
    [5]=> 
    string(3) "zip" 
    [6]=> 
    string(5) "phone" 
    [7]=> 
    string(7) "website" 
    [8]=> 
    string(5) "other" 
    [9]=> 
    string(5) "other" 
    } 
    [1]=> 
    array(10) { 
    [0]=> 
    string(1) "2" 
    [1]=> 
    string(4) "name" 
    [2]=> 
    string(7) "address" 
    [3]=> 
    string(4) "town" 
    [4]=> 
    string(5) "state" 
    [5]=> 
    string(3) "zip" 
    [6]=> 
    string(5) "phone" 
    [7]=> 
    string(7) "website" 
    [8]=> 
    string(5) "other" 
    [9]=> 
    string(5) "other" 
    } 
    [2]=> 
    array(10) { 
    [0]=> 
    string(1) "3" 
    [1]=> 
    string(4) "name" 
    [2]=> 
    string(7) "address" 
    [3]=> 
    string(4) "town" 
    [4]=> 
    string(5) "state" 
    [5]=> 
    string(3) "zip" 
    [6]=> 
    string(5) "phone" 
    [7]=> 
    string(7) "website" 
    [8]=> 
    string(5) "other" 
    [9]=> 
    string(5) "other" 
    } 
} 

EDIT2: Per utilizzare il primo elemento di ogni record come la chiave nella matrice risultato:

<?php 
$targetFile = 'soTest.csv'; 
setup($targetFile); 

$data = array(); 
$fp = fopen($targetFile, 'rb'); 
while(!feof($fp)) { 
    $row = fgetcsv($fp); 
    $id = array_shift($row); 
    $data[$id] = $row; 
} 
var_dump($data); 


function setup($targetFile) { 
    file_put_contents($targetFile, <<< eot 
1,name,address,town,state,zip,phone,website,other,other 
2,name,address,town,state,zip,phone,website,other,other 
3,name,address,town,state,zip,phone,website,other,other 
eot 
    ); 
} 
+0

questo restituisce la stessa cosa ancora per me. Ho bisogno che assomigli all'array in cima alla domanda –

+0

@Drew: Allora forse hai un problema con php che non rileva le terminazioni di riga all'interno del file. vedi http://docs.php.net/filesystem.configuration#ini.auto-detect-line-endings – VolkerK

+0

Non funziona ancora, ma tHanks per il tuo aiuto. –

0

Non la pretties cosa su questo mondo, ma penso che funziona.

//make the arrays needed 
$csvtmp = array(); 
$csvFinal = array(); 

$csvfile = file_get_contents('test.csv'); 
$csv = str_getcsv($csvfile,"\n"); //make an array element for every record (new line) 

//Loop through the result 
foreach ($csv as $key => $item) 
{ 
    array_push($csvtmp, str_getcsv($item,";")); //push each record to the csv temp array 

    //here's the messy part. This set the key of the csvFinal array to the first field in the current record and for the value it gives it the array we got from the previous str_getcsv. 
    $csvFinal[$csvtmp[$key][0]] = $csvtmp[$key]; 
    //Here we just unset the id row in the final array 
    unset($csvFinal[$csvtmp[$key][0]][0]); 

} 

echo "<pre>"; 
    print_r($csvFinal); 
echo "</pre>"; 

risultato del codice:

Array 
(
    [22] => Array 
     (
      [1] => name1 
      [2] => address1 
      [3] => town1 
      [4] => state1 
      [5] => zip1 
      [6] => phone1 
      [7] => website1 
      [8] => other1 
      [9] => other1 
     ) 

    [23] => Array 
     (
      [1] => name2 
      [2] => address2 
      [3] => town2 
      [4] => state2 
      [5] => zip2 
      [6] => phone2 
      [7] => website2 
      [8] => other1 
      [9] => other1 
     ) 

    [24] => Array 
     (
      [1] => name3 
      [2] => address3 
      [3] => town3 
      [4] => state3 
      [5] => zip3 
      [6] => phone3 
      [7] => website3 
      [8] => other1 
      [9] => other1 
     ) 
} 

Spero che questo aiuti

+0

Lo metterò alla prova più tardi oggi. grazie per l'aiuto! –

+0

Non si dovrebbe usare '\ n' per determinare una nuova riga in csv,' \ n' si interromperà se una riga di colonne ha più righe in essa. –

0

Beh, basta contare il numero di elementi di una voce ha poi fare un ciclo all'interno di un ciclo

// loop on all items; $i+=$ITEM_SIZE go to the next item each outer loop 
// (10 elements for ITEM in Opening Post's case) 

// this for loops between all items 
for ($i=0;$i<=$ARRAY_LENGHT;$i+=10) 
{ 
    // this for loops between each item's elements 
    for($c=1; $c<=10;$c++) 
    { 
     switch($c) 
     { 
      case 1: 
       $id = $array[$i+$c]; 
       break; 

      case 2: 
       $name = $array[$i+$c]; 
       break; 

      case 3: 
       $address = $array[$i+$c]; 
       break; 

      //etc to 10th element: 

      case 10: 
       $other = $array[$i+$c]; 
       break; 

     } 
    } 

    // When the item is all done use the item 
    // it as you need, example: 

    echo "id: {$id}\nname: {$name}\naddress: {$adress}"; //etc 

    // then unset($id,$name,$address, $etc); 
    // for the next iteration of loop (next item) 
} 

Questo è quello che ho appena fatto e funziona molto bene.