2011-01-26 43 views
26

我見過很多關於如何獲取CSV文件的示例,然後創建一個以標題作爲關鍵字的關聯數組。CSV到關聯數組

例如:

Brand,Model,Part,Test 
Honda,Civic,123,244 
Honda,Civic,135,434 
Toyota,Supra,511,664 

凡將創建一個數組,如Array[$num][$key]其中$key將是品牌,型號,部件,測試。

所以如果我想訪問測試值「434」我會循環數組中的每個索引,然後忽略不本田任何品牌,而不是公民的任何模型


我需要做的是直接訪問這個值,而不是通過遍歷每個$ num索引的for循環。我希望能夠訪問值測試「434」有:

Array['Honda']['Civic']['135']

或通過每一個模型本田具有循環控制的語句...像

foreach $model in Array['Honda']

至少我需要能夠通過已知品牌的每個模型,並訪問每個模型的所有相關信息。

編輯:

只是爲了確認我設置了這個例子。我的實際數據有類似的報頭:

brand model part price shipping description footnote

,而我需要訪問捆綁到部分(價格,運費,遞減,腳註)

+1

[例(一個或多個)怎麼做,用'SplFileInfo'(http://stackoverflow.com/a/10181302/367456) – hakre

回答

48

碾過由線CSV文件行的所有信息,並插入到陣列,如:

$array = $fields = array(); $i = 0; 
$handle = @fopen("file.csv", "r"); 
if ($handle) { 
    while (($row = fgetcsv($handle, 4096)) !== false) { 
     if (empty($fields)) { 
      $fields = $row; 
      continue; 
     } 
     foreach ($row as $k=>$value) { 
      $array[$i][$fields[$k]] = $value; 
     } 
     $i++; 
    } 
    if (!feof($handle)) { 
     echo "Error: unexpected fgets() fail\n"; 
    } 
    fclose($handle); 
} 
+0

作品爲例如OP提供的,但是要注意,csv文件可以在文本字段中包含逗號,例如:field1,「field two」,「field,3」,field4。 – xelco52

+1

@ xelco52:'fgetcsv()'會處理得很好。 – BoltClock

+0

你對我改變fgetcsv –

15

創建關聯列表陣列使用類似:

$keys = fgetcsv($f); 
while (!feof($f)) { 
    $array[] = array_combine($keys, fgetcsv($f)); 
} 

,並過濾通過特定的屬性遍歷和寫這樣一個功能:

function find($find) { 
    foreach ($array as $row) { 
     if (array_intersect_assoc($row, $find) == $find) { 
      $result[] = $row; 
     } 
    } 
} 

如果你將與$find = array(Brand=>Honda, Model=>Civic, Part=>135)調用它來過濾掉搜索模式。另一個位置數組結構看起來不太可行,除非你只想訪問「Test」屬性。

2

這是通過指定本地文件或URL來工作的解決方案。您也可以打開和關閉關聯。希望這有助於。

class CSVData{ 
    public $file; 
    public $data; 
    public $fp; 
    public $caption=true; 
    public function CSVData($file=''){ 
     if ($file!='') getData($file); 
    } 
    function getData($file){ 
     if (strpos($file, 'tp://')!==false){ 
      copy ($file, '/tmp/csvdata.csv'); 
      if ($this->fp=fopen('/tmp/csvdata.csv', 'r')!==FALSE){ 
       $this->readCSV(); 
       unlink('tmp/csvdata.csv'); 
      } 
     } else { 
      $this->fp=fopen($file, 'r'); 
      $this->readCSV(); 
     } 
     fclose($this->fp); 
    } 
    private function readCSV(){ 
     if ($this->caption==true){ 
      if (($captions=fgetcsv($this->fp, 1000, ","))==false) return false; 
     } 
     $row=0; 
     while (($data = fgetcsv($this->fp, 1000, ",")) !== FALSE) { 
      for ($c=0; $c < count($data); $c++) { 
       $this->data[$row][$c]=$data[$c]; 
       if ($this->caption==true){ 
        $this->data[$row][$captions[$c]]=$data[$c]; 
       } 
      } 
      $row++; 
     } 
    } 
} 

試試這個用法:

$o=new CSVData(); 
$o->getData('/home/site/datafile.csv'); 
$data=$o->data; 
print_r($data); 
+0

博客鏈接已關閉 –

4

試試這個簡單的算法:

 $assocData = array(); 

     if(($handle = fopen($importedCSVFile, "r")) !== FALSE) { 
      $rowCounter = 0; 
      while (($rowData = fgetcsv($handle, 0, ",")) !== FALSE) { 
       if(0 === $rowCounter) { 
        $headerRecord = $rowData; 
       } else { 
        foreach($rowData as $key => $value) { 
         $assocData[ $rowCounter - 1][ $headerRecord[ $key] ] = $value; 
        } 
       } 
       $rowCounter++; 
      } 
      fclose($handle); 
     } 

     var_dump($assocData); 
23

太多的長期解決方案。我一直覺得這是最簡單的:

<?php 
    /* Map Rows and Loop Through Them */ 
    $rows = array_map('str_getcsv', file('file.csv')); 
    $header = array_shift($rows); 
    $csv = array(); 
    foreach($rows as $row) { 
     $csv[] = array_combine($header, $row); 
    } 
?> 
+0

簡單而動態 - 極好的解決方案。謝謝! – domdambrogia

+0

感謝Buddy,很棒的解決方案。 – GuRu

+0

這工作得很好,我從來沒有使用過數組合,但是工作真棒!謝謝! –