DarkLeafyGreen
DarkLeafyGreen

Reputation: 70426

Using array_combine to store data read from csv

From a csv file I need to extract the header and the values. Both are later accessed in frontend.

$header = array();
$contacts = array();

if ($request->isMethod('POST')) {

   if (($handle = fopen($_FILES['file']['tmp_name'], "r")) !== FALSE) {
        $header = fgetcsv($handle, 1000, ",");

        while (($values = fgetcsv($handle, 1000, ",")) !== FALSE) {

            // array_combine
            // Creates an array by using one array for keys
            // and another for its values
            $contacts[] = array_combine($header, $values);
        }
        fclose($handle);
   }
} 

It works with csv files that look like this

Name,Firstname,Organisation,
Bar,Foo,SO,

I just exported my gmail contacts and tried to read them using the above code but I get following error

Warning: array_combine() [function.array-combine]: Both parameters should have an equal number of elements

The gmail csv looks like this

Name,Firstname,Organisation
Bar,Foo,SO

Is the last missing , the reason for the error? What is wrong and how to fix it?

I found this on SO

function array_combine2($arr1, $arr2) {
    $count = min(count($arr1), count($arr2));
    return array_combine(array_slice($arr1, 0, $count),
                         array_slice($arr2, 0, $count));
}

This works but it skips the Name field and not all fields are combined. Is this because the gmail csv is not realy valid? Any suggestions?

Upvotes: 0

Views: 1306

Answers (2)

lazyreader
lazyreader

Reputation: 48

Although this isn't the answer to the question you asked, it might be the answer to the source of the problem. I recently had this problem and realized I was making a silly error because I didn't understand the fgetcsv() function's parameters:

That 1000 up there denotes the maximum line length of a single line in the csv you're taking content from. Longer than that, and the function returns null! I don't know why the version given in the examples is so stingy, but it's not required; setting it to 0 allows fgetcsv() to read lines of any length. (The documentation warns this is slower. For most use cases of fgetcsv() I can hardly imagine it's slow enough to notice.)

Upvotes: 1

DarkLeafyGreen
DarkLeafyGreen

Reputation: 70426

I managed this by expanding the array size or slicing it depending on the size of the header.

if (count($header) > count($values)) {
    $contacts = array_pad($values, count($header), null);
} else if (count($header) < count($values)) {
    $contacts = array_slice($values, 0, count($header));
} else {
    $contacts = $values;
}

Upvotes: 1

Related Questions