2011-10-06 33 views
5

Hay algunas formas de leer archivos CSV con PHP. Solía ​​usar la función explotar para poner cada línea en una matriz y luego explotar comas y usar recortar para eliminar las comillas de alrededor de los datos. Era desordenado ...PHP leyendo un archivo csv efectivamente

En PHP 5 ahora hay fgetcsv y str_getcsv * * ... Supongo que esta es la mejor manera de hacerlo en estos días por lo que han azotado a algunos de código ..

$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])); 
    } 
} 

Parece que funciona, pero ¿hay un enfoque más seguro contra fallas? Por ejemplo, hacer que funcione si los saltos de línea son \ n o \ r ...

¡Cualquier entrada que pueda dar sería increíble!

Respuesta

2

Esto convierte el archivo CSV en una matriz anidada. Puede ser más fácil para usted tratar con:

<?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

También mencioné esto a Mario arriba, pero creo que tal vez haya algún problema con mi archivo CSV ... Aquí está un poco de eso bensinclair.co/import.csv ... Cuando uso este archivo con su código, muestra mis datos como qué pasa con el código de marios anterior img192.imageshack.us/img192/2483/screenshot20111006at123b.png He creado el archivo CSV en Microsoft Excel en Mac. ¿Estoy haciendo algo mal o hay algo que deba ajustarse en el código? –

+0

Veo el problema. Arreglará. – StackOverflowNewbie

+0

He actualizado el código. Se agregó 'ini_set ('auto_detect_line_endings', TRUE);'. Darle una oportunidad. – StackOverflowNewbie

6

Hay una función para leer archivos en línea: file(), que también funciona en ambos tipos de salto de línea.

Y el método más corto para leer en todo el archivo CSV es:

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

seguro de lo que su $num = count() se trataba.

+0

Hola Mario, gracias por la respuesta! El código que me has dado coloca cada celda en una matriz en lugar de cada línea en su propia matriz. Así que ahora tengo una matriz masiva con cada celda de cada línea. ¿Estoy teniendo sentido? ¿Cómo se divide cada línea en su propia matriz? –

+1

El fragmento anterior le daría un '$ data [$ line] [$ row]' bidimensional, la estructura de tabla comúnmente asumida. No estoy muy seguro de lo que quieres en su lugar. - Si solo quería ver cada línea una vez, use un foreach en su lugar: 'foreach (archivo ($ fn) como $ línea) {$ data = str_getcsv ($ línea); } ' – mario

+0

Creo que hay algo mal con mi archivo CSV ... Aquí está un tímido http: //bensinclair.co/import.csv ... Cuando utilizo este archivo con su código, se obtienen mis datos como este http : //img192.imageshack.us/img192/2483/screenshot20111006at123b.png –