2011-10-06 104 views
5

有幾種方法可以用PHP讀取CSV文件。我以前用爆炸函數把每行放入一個數組,然後爆炸逗號並用trim刪除數據周圍的引號。它很凌亂...PHP有效地讀取csv文件

在PHP 5中現在有fgetcsv和* str_getcsv * ...我猜這是最好的方式去做它,所以我一起攪了一些代碼.. 。

$fp = fopen($csv_file['file_path'], 'r');  
while (($data = fgetcsv($fp, 0, "\r", '"', "\r")) !== FALSE) { 
    $num = count($data); 
    for ($c=0; $c < $num; $c++) { 
     print_r(str_getcsv($data[$c])); 
    } 
} 

它似乎工作,但有沒有更安全的方法?例如,讓它工作,無論換行符是\ n還是\ r ...

任何輸入,你可以給出真棒!

回答

2

這將CSV轉換爲嵌套數組。可能對你更容易處理:

<?php 
    /** 
    * 
    */ 
    function csv_entry_to_array(array $row) 
    { 
     $column_count = count($row); 
     $csv_column_values = array(); 

     // Loop through the columns of the current CSV entry and store its value 
     for ($column_index = 0; $column_index < $column_count; $column_index++) 
     { 
      // Store the value of the current CSV entry 
      $csv_column_values[] = $row[$column_index]; 
     } 

     // Return 
     return $csv_column_values;  
    } 

    /** 
    * @param string $input_file_name   Filename of input CSV 
    * @param boolean $include_header_in_output Flag indicating whether the first entry in the CSV is included in the output or not. 
    * @param integer $length      Must be greater than the longest line (in characters) to be found in the CSV file (allowing for trailing line-end characters). 
    *            It became optional in PHP 5. Omitting this parameter (or setting it to 0 in PHP 5.0.4 and later) the maximum line length is 
    *            not limited, which is slightly slower. 
    * @param string $delimeter     Set the field delimiter (one character only). 
    * @param string $enclosure     Set the field enclosure character (one character only). 
    * @param string $escape      Set the escape character (one character only). Defaults as a backslash. 
    * $return array        Nested indexed array representing the CSV. Empty array on error (e.g. input file missing, input file not a CSV). 
    */ 
    function csv_file_to_array($input_file_name, $include_header_in_output = TRUE, $length = 1000, $delimeter = ',', $enclosure = '"', $escape = '\\') 
    { 
     // NOTE: this attempts to properly recognize line endings when reading files from Mac; has small performance penalty 
     ini_set('auto_detect_line_endings', TRUE); 

     $csv_array = array(); 

     // Warnings are supressed, but that's OK since the code handles such warnings 
     if (($handle = @fopen($input_file_name, "r")) !== FALSE) 
     { 
      $row_counter  = 0; 

      // Iterate over the CSV entries 
      while (($row = fgetcsv($handle, $length, $delimeter, $enclosure, $escape)) !== FALSE) 
      {   
       if ($row_counter === 0 && $include_header_in_output === TRUE) 
       { 
        // This is the first row in the CSV and it should be included in the output 
        $csv_array[] = csv_entry_to_array($row);     
       } 
       else if ($row_counter > 0) 
       { 
        // This is a row in the CSV that needs to be stored in the return array 
        $csv_array[] = csv_entry_to_array($row); 
       } 

       $row_counter++; 
      } 

      // Close file handler 
      fclose($handle); 
     } 
     else 
     { 
      // Input file: some error occured 
      return array(); 
     } 

     return $csv_array; 
    } 
+0

我也在上面提到過這個,但是我想可能是我的CSV文件出了問題......這裏有一個bensinclair.co/import.csv的co When ...當我用你的代碼使用這個文件時,它會輸出我的數據上面的marios代碼會發生什麼情況img192.imageshack.us/img192/2483/screenshot20111006at123b.png我在Mac上的Microsoft Excel中創建了CSV文件。我做錯了什麼或者需要在代碼中進行調整? –

+0

我看到了問題。將解決。 – StackOverflowNewbie

+0

我更新了代碼。增加了'ini_set('auto_detect_line_endings',TRUE);'。試一試。 – StackOverflowNewbie

6

有一個線性讀取文件的功能:file(),它也適用於兩種換行類型。

和最短的方法,在整個CSV文件讀的是:

$data = array_map("str_getcsv", file($filename)); 

不知道你的$num = count()約。

+0

嗨馬里奧,感謝您的答覆!您給我的代碼將每個單元格放入一個數組中,而不是將每行放入其自己的數組中。所以我現在有一個龐大的陣列,每個細胞都來自它的每一行。我有道理嗎?我如何將每一行分解成它自己的數組? –

+1

上面的代碼會給你一個二維的'$ data [$ line] [$ row]',這是一般假設的表結構。不太清楚你想要什麼。 - 如果你只想看看每一行,那麼用foreach代替:'foreach(file($ fn)as $ line){$ data = str_getcsv($ line); }' – mario

+0

我想也許我的CSV文件有問題...這是它的一個諷刺http://bensinclair.co/import.csv ...當我用你的代碼這個文件它輸出我的數據像這樣http ://img192.imageshack.us/img192/2483/screenshot20111006at123b.png –