2011-10-06 111 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 –