10

I am uploading a csv file and then parsing it using str_getcsv. All works great except that I need a way to cycle through them. Ideally, it'd be great to have the array come back and look like this:

Array (      
    [1] => Array
       (
            [0] => 1 // first id in csv
            [1] => name
            [2] => address
            [3] => town
            [4] => state
            [5] => zip
            [6] => phone
            [7] => website
            [8] => other
            [9] => other
        )
    [22] => Array
       (
            [10] => name
            [11] => address
            [12] => town
            [13] => state
            [14] => zip
            [15] => phone
            [16] => website
            [17] => other
            [18] => other
        )
    [24] => Array
       (
            [19] => name
            [20] => address
            [21] => town
            [22] => state
            [23] => zip
            [24] => phone
            [25] => website
            [26] => other
            [27] => other
        )
)

However the data comes back like the following:

Array
(
    [0] => 1 // first id in csv
    [1] => name
    [2] => address
    [3] => town
    [4] => state
    [5] => zip
    [6] => phone
    [7] => website
    [8] => other
    [9] => other
22 // id field
    [10] => name
    [11] => address
    [12] => town
    [13] => state
    [14] => zip
    [15] => phone
    [16] => website
    [17] => other
    [18] => other
24// id field
    [19] => name
    [20] => address
    [21] => town
    [22] => state
    [23] => zip
    [24] => phone
    [25] => website
    [26] => other
    [27] => other

Any suggestions on how to fix this to look like the array at the top? right now I'm doing:

$csvfile = file_get_contents($targetFile);
$csv = str_getcsv($csvfile);
2
  • possible duplicate of PHP CSV string to array Commented Dec 1, 2014 at 20:58
  • I've marked this as a duplicate despite the fact that this question is earlier just because that question is far more popular Commented Dec 1, 2014 at 20:58

3 Answers 3

17

str_getcsv() expects the string passed as parameter to be one record.
But since your source is a file anyway the easiest way is probably to use fgetcsv() instead of str_getcsv()

$data = array();
$fp = fopen($targetFile, 'rb');
while(!feof($fp)) {
    $data[] = fgetcsv($fp);
}
fclose($fp);

self-contained example:

<?php
$targetFile = 'soTest.csv';
setup($targetFile);

$data = array();
$fp = fopen($targetFile, 'rb');
while(!feof($fp)) {
    $data[] = fgetcsv($fp);
}
var_dump($data);


function setup($targetFile) {
    file_put_contents($targetFile, <<< eot
1,name,address,town,state,zip,phone,website,other,other
2,name,address,town,state,zip,phone,website,other,other
3,name,address,town,state,zip,phone,website,other,other
eot
    );
}

prints

array(3) {
  [0]=>
  array(10) {
    [0]=>
    string(1) "1"
    [1]=>
    string(4) "name"
    [2]=>
    string(7) "address"
    [3]=>
    string(4) "town"
    [4]=>
    string(5) "state"
    [5]=>
    string(3) "zip"
    [6]=>
    string(5) "phone"
    [7]=>
    string(7) "website"
    [8]=>
    string(5) "other"
    [9]=>
    string(5) "other"
  }
  [1]=>
  array(10) {
    [0]=>
    string(1) "2"
    [1]=>
    string(4) "name"
    [2]=>
    string(7) "address"
    [3]=>
    string(4) "town"
    [4]=>
    string(5) "state"
    [5]=>
    string(3) "zip"
    [6]=>
    string(5) "phone"
    [7]=>
    string(7) "website"
    [8]=>
    string(5) "other"
    [9]=>
    string(5) "other"
  }
  [2]=>
  array(10) {
    [0]=>
    string(1) "3"
    [1]=>
    string(4) "name"
    [2]=>
    string(7) "address"
    [3]=>
    string(4) "town"
    [4]=>
    string(5) "state"
    [5]=>
    string(3) "zip"
    [6]=>
    string(5) "phone"
    [7]=>
    string(7) "website"
    [8]=>
    string(5) "other"
    [9]=>
    string(5) "other"
  }
}

edit2: For using the first element of each record as the key in the result array:

<?php
$targetFile = 'soTest.csv';
setup($targetFile);

$data = array();
$fp = fopen($targetFile, 'rb');
while(!feof($fp)) {
    $row = fgetcsv($fp);
    $id = array_shift($row);
    $data[$id] = $row;
}
var_dump($data);


function setup($targetFile) {
    file_put_contents($targetFile, <<< eot
1,name,address,town,state,zip,phone,website,other,other
2,name,address,town,state,zip,phone,website,other,other
3,name,address,town,state,zip,phone,website,other,other
eot
    );
}
Sign up to request clarification or add additional context in comments.

3 Comments

this returns the same thing still for me. I need it to look like the array on the top of the question
@Drew : Then maybe you have a problem with php not detecting the line-endings within the file. see docs.php.net/…
I would say double check your csv and make sure each record isn't separated by a comma too. I haven't run this code but it looks good. and should result in the array you're looking for. oh, and each record should be on a newline too.
0

Not the pretties thing on this world but I think it works.

//make the arrays needed
$csvtmp = array();
$csvFinal = array();

$csvfile = file_get_contents('test.csv');
$csv = str_getcsv($csvfile,"\n"); //make an array element for every record (new line)

//Loop through the result 
foreach ($csv as $key => $item) 
{
    array_push($csvtmp, str_getcsv($item,";")); //push each record to the csv temp array

    //here's the messy part. This set the key of the csvFinal array to the first field in the current record and for the value it gives it the array we got from the previous str_getcsv.
    $csvFinal[$csvtmp[$key][0]] = $csvtmp[$key]; 
    //Here we just unset the id row in the final array
    unset($csvFinal[$csvtmp[$key][0]][0]);

}

echo "<pre>";
    print_r($csvFinal);
echo "</pre>"; 

result of the code:

Array
(
    [22] => Array
        (
            [1] => name1
            [2] => address1
            [3] => town1
            [4] => state1
            [5] => zip1
            [6] => phone1
            [7] => website1
            [8] => other1
            [9] => other1
        )

    [23] => Array
        (
            [1] => name2
            [2] => address2
            [3] => town2
            [4] => state2
            [5] => zip2
            [6] => phone2
            [7] => website2
            [8] => other1
            [9] => other1
        )

    [24] => Array
        (
            [1] => name3
            [2] => address3
            [3] => town3
            [4] => state3
            [5] => zip3
            [6] => phone3
            [7] => website3
            [8] => other1
            [9] => other1
        )
}

Hope this helps

1 Comment

Should not use \n as determining a new row in the csv, \n will break if any columns row has multiple lines in it.
0

Well, just count the number of items an entry has then make a loop inside a loop

// loop on all items; $i+=$ITEM_SIZE go to the next item each outer loop
// (10 elements for ITEM in Opening Post's case)

// this for loops between all items
for ($i=0;$i<=$ARRAY_LENGHT;$i+=10)
{
    // this for loops between each item's elements
    for($c=1; $c<=10;$c++)
    {
        switch($c)
        {
            case 1:
              $id = $array[$i+$c];
              break;

            case 2:
              $name = $array[$i+$c];
              break;

            case 3:
              $address = $array[$i+$c];
              break;

            //etc to 10th element:

            case 10:
              $other = $array[$i+$c];
              break;

        }
    }

    // When the item is all done use the item
    // it as you need, example:

    echo "id: {$id}\nname: {$name}\naddress: {$adress}"; //etc

    // then unset($id,$name,$address, $etc);
    // for the next iteration of loop (next item)
}

That is what I just did and works very well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.