Question

I have a CSV file with several headers.

I only need about 5 of these columns.

I'm trying to get these into a more manageable format (variables?) so I can then do a check on their values.

I have the following code:

    $headers    = array('NAME', 'EMAIL');
    $picked     = array();
    $theData    = array();
    $isFirstRow = true;
    if (($handle = fopen($uploadedFile, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $numCols = count($data);
            $row     = array();

            if($isFirstRow) {
                for($c=0; $c<$numCols; $c++) {
                    if(!in_array($data[$c], $headers)) {
                       continue;
                    } else {
                        $picked[] = $c;
                        $isFirstRow = false;
                    }
                }
            } else {
                for($c=0; $c < $numCols; $c++) {
                    if(in_array($c, $picked)) {
                        $row[] = $data[$c];
                        $theData[] = $row;
                    }
                }
            }
        }
        fclose($handle);


    }
    var_dump($theData);

This outputs the following:

array (size=xxxxxx)
  0 => 
    array (size=1)
      0 => string 'John Doe' (length=8)
  1 => 
    array (size=2)
      0 => string 'John Doe' (length=8)
      1 => string 'johndoe@test.com' (length=16)
  2 => 
    array (size=1)
      0 => string 'Jane Doe' (length=8)
  3 => 
    array (size=2)
      0 => string 'Jane Doe' (length=8)
      1 => string 'janedoe@test.com' (length=16)

Obviously this isn't the expected output

I'd like something more like:

array (size=xxxx)
  0 =>
    array (size=1)
      0 => string 'John Doe' (length=8)
      1 => string 'johndoe@test.com' (length=16)
  1 =>
    array (size=2)
      0 => string 'Jane Doe' (length=8)
      1 => string 'janedoe@test.com' (length=16)

I'not sure why its adding the extra arrays.

Anyone have an idea?

Thanks

EDIT

My CSV looks like this;

NAME,EMAIL
John Doe,johndoe@test.com
Jane Doe,janedoe@test.com
Was it helpful?

Solution

Edit: New answer.

So there's a somewhat convoluted solution that does this:

  • Takes your CSV data
  • Combine the numeric key data with ALL available headers, giving you a key => value array
  • Intersect this with your ALLOWED headers
  • Add this to the final data array
  • Removes the header row

There we go. It's awful to read, but it seems to be fine. As all the array manipulation is C based, it should be faster than manipulating thousands of rows in PHP.

    $availableHeaders = array('NAME', 'THING', 'EMAIL');
    $headers    = array('NAME', 'EMAIL');
    $theData    = array();

    if (($handle = fopen($uploadedFile, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $theData[] = array_intersect_key(array_combine(array_values($availableHeaders), array_values($data)), array_flip($headers));
        }
        fclose($handle);
    }

    array_shift($theData); // Remove headers

OTHER TIPS

Example .csv:

IGNORE1,NAME,EMAIL,IGNORE2,IGNORE3
-1,John Doe,johndoe@test.com,-1,-1
-1,Jane Doe,janedoe@test.com,-1,-1

Code:

$headers    = array('3' => 'NAME', '4' => 'EMAIL');
$theData    = array();
$isFirstRow = true;
$rowsToKeep = array();
if (($handle = fopen($uploadedFile, "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        if ( $isFirstRow ) {
            $rowsToKeep = array_intersect($data, $headers);
            $theData[] = $rowsToKeep;
            $isFirstRow = false;
        } else {    
            $theData[] = array_intersect_key($data, $rowsToKeep);
        }
    }
    fclose($handle);
}

Produces:

Array
(
    [0] => Array
        (
            [1] => NAME
            [2] => EMAIL
        )

    [1] => Array
        (
            [1] => John Doe
            [2] => johndoe@test.com
        )

    [2] => Array
        (
            [1] => Jane Doe
            [2] => janedoe@test.com
        )

)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top