Jump to content

csv_to_array and array_combine


big0mike

Recommended Posts

I can't remember where I found this csv_to_array function but I've used it with no problem until just recently.

function csv_to_array($filename, $delimiter=',', $enclosure='"', $escape = '\\') {

    if(!file_exists($filename) AND !is_readable($filename)) {echo "File does not exist or is not readable."; return false;}

    $header = null;
    $values = array();
    $data = array();
    $lines = file($filename);

    foreach($lines as $line) {
        $values = str_getcsv($line, $delimiter, $enclosure, $escape);
        $values = array_map('trim', $values);
        if(!$header) {$header = $values;
        var_dump($header);
        echo "<br><br>";
        var_dump($values);
        echo "<br><br>";
        }
        else $data[] = array_combine($header, $values);
    }

    return $data;
}

I am now getting the "array_combine(): Both parameters should have an equal number of elements" error but I can't figure out how rows of the same CSV are coming up with different numbers of columns. Several columns have a fair amount of text including commas and I've formatted those columns as TEXT so they get quotes around them and I've taken the CSV, renamed it as a TXT file, and imported it back into Excel and all rows seem to have the correct number of columns. If they didn't it would be obvious as the data in the columns bounce around.

I noticed in file that double quotes in the TEXT columns are escaped with another double quote. In the function it says the escape is \ so I did a search and replace "" > \\" but that had no effect.

The var_dump section spits out two rows of the array. I went to row 45 in the CSV and see nothing out of the ordinary.

array(46) { [0]=> string(6) "PartNo" [1]=> string(7) "Company" [2]=> string(6) "Status" [3]=> string(10) "DateEdited" [4]=> string(8) "Comments" [5]=> string(6) "Photos" [6]=> string(11) "VehicleType" [7]=> string(4) "Make" [8]=> string(5) "Model" [9]=> string(9) "BodyStyle" [10]=> string(9) "Driveline" [11]=> string(10) "LiftHeight" [12]=> string(7) "MaxTire" [13]=> string(9) "YearStart" [14]=> string(7) "YearEnd" [15]=> string(9) "Trademark" [16]=> string(6) "Series" [17]=> string(8) "Category" [18]=> string(11) "SubCategory" [19]=> string(12) "3SubCategory" [20]=> string(18) "AssociatedComments" [21]=> string(8) "Max 2000" [22]=> string(11) "Application" [23]=> string(8) "Max 2000" [24]=> string(11) "Daystar App" [25]=> string(12) "ExtendedDesc" [26]=> string(7) "Max 240" [27]=> string(13) "MarketingDesc" [28]=> string(8) "Max 2000" [29]=> string(16) "FeaturesBenefits" [30]=> string(3) "MAP" [31]=> string(4) "MSRP" [32]=> string(14) "PriceEffective" [33]=> string(11) "DateUpdated" [34]=> string(3) "UPC" [35]=> string(9) "BoxLength" [36]=> string(8) "BoxWidth" [37]=> string(9) "BoxHeight" [38]=> string(9) "BoxWeight" [39]=> string(5) "Color" [40]=> string(7) "Country" [41]=> string(6) "Carded" [42]=> string(9) "ScheduleB" }

array(46) { [0]=> string(6) "PartNo" [1]=> string(7) "Company" [2]=> string(6) "Status" [3]=> string(10) "DateEdited" [4]=> string(8) "Comments" [5]=> string(6) "Photos" [6]=> string(11) "VehicleType" [7]=> string(4) "Make" [8]=> string(5) "Model" [9]=> string(9) "BodyStyle" [10]=> string(9) "Driveline" [11]=> string(10) "LiftHeight" [12]=> string(7) "MaxTire" [13]=> string(9) "YearStart" [14]=> string(7) "YearEnd" [15]=> string(9) "Trademark" [16]=> string(6) "Series" [17]=> string(8) "Category" [18]=> string(11) "SubCategory" [19]=> string(12) "3SubCategory" [20]=> string(18) "AssociatedComments" [21]=> string(8) "Max 2000" [22]=> string(11) "Application" [23]=> string(8) "Max 2000" [24]=> string(11) "Daystar App" [25]=> string(12) "ExtendedDesc" [26]=> string(7) "Max 240" [27]=> string(13) "MarketingDesc" [28]=> string(8) "Max 2000" [29]=> string(16) "FeaturesBenefits" [30]=> string(3) "MAP" [31]=> string(4) "MSRP" [32]=> string(14) "PriceEffective" [33]=> string(11) "DateUpdated" [34]=> string(3) "UPC" [35]=> string(9) "BoxLength" [36]=> string(8) "BoxWidth" [37]=> string(9) "BoxHeight" [38]=> string(9) "BoxWeight" [39]=> string(5) "Color" [40]=> string(7) "Country" [41]=> string(6) "Carded" [42]=> string(9) "ScheduleB"  }

And, the whole thing seems to loop indefinitely. A get hundreds of rows of the array_combine error followed by hundreds of rows of "Trying to access array offset on value of type bool" followed by hundreds of rows of "undefined index".

When I replace the CSV I'm working on with the CSV that worked in the past I don't get the array_combine error. The CSVs are similar but with different data. The only difference that I know of being that the NEW file has several columns with soft returns to created spacing between paragraphs. I supposed that could be the problem but I'd think Excel would throw a fit when I try to import that data. 

I'm at a loss as to how I can figure this out.

Any thoughts?

Thanks, Mike

Link to comment
Share on other sites

If array_combine is finding that the two arrays ($header and $values) have different lengths then you should troubleshoot for when those two arrays have different lengths.

As in

if (count($header) != count($values)) {
	print_r(["headers" => $header, "values" => $values]);
}

 

Link to comment
Share on other sites

18 hours ago, requinix said:

If array_combine is finding that the two arrays ($header and $values) have different lengths then you should troubleshoot for when those two arrays have different lengths.

As in


if (count($header) != count($values)) {
	print_r(["headers" => $header, "values" => $values]);
}

 

I will give that a shot!

BtW, nice to see a familiar name. When I found out DevShed took a dump I was like, "What do I do now? I have no idea where to go!" Thanks!

Link to comment
Share on other sites

It outputs:

Warning: array_combine(): Both parameters should have an equal number of elements in C:\xampp\htdocs\DCISession.php on line 26
Array ( [headers] => Array ( [0] => PartNo [1] => Company [2] => Status [3] => DateEdited [4] => Comments [5] => Photos [6] => VehicleType [7] => Make [8] => Model [9] => BodyStyle [10] => Driveline [11] => LiftHeight [12] => MaxTire [13] => YearStart [14] => YearEnd [15] => Trademark [16] => Series [17] => Category [18] => SubCategory [19] => 3SubCategory [20] => AssociatedComments [21] => Max 2000 [22] => Application [23] => Max 2000_1 [24] => KitDesc [25] => ExtendedDesc [26] => Max 240 [27] => MarketingDesc [28] => Max 2000_2 [29] => FeaturesBenefits [30] => MAP [31] => MSRP [32] => PriceEffective [33] => DateUpdated [34] => UPC [35] => BoxLength [36] => BoxWidth [37] => BoxHeight [38] => BoxWeight [39] => Color [40] => Country [41] => Carded [42] => ScheduleB ) [values] => Array ( [0] => 4001101 [1] => Daystar [2] => [3] => [4] => [5] => 4001101.jpg [6] => Truck [7] => Ford [8] => F-150 [9] => Truck [10] => 2/4WD [11] => 4 [12] => 35 [13] => 2017 [14] => 2019 [15] => Daystar [16] => 4.0 Tactical Lift [17] => Suspension [18] => Lift Kits [19] => [20] => Not for Raptor [21] => 14 [22] => 2017-2019 Ford F-150 2/4WD [23] => 26 [24] => 4.0 Tactical Lift Kit, Not for Raptor [25] => 2017-2019 Ford F-150 2/4WD 4.0 Tactical Lift Kit, Not for Raptor [26] => 64 [27] => Daystar 4.0 Series Tactical Lift Kits is a 4" lift and leveling system designed by enthusiast engineers for consumers who want just enough lift to clear 33" to 35" tires, depending on the vehicle. These lift kits give you more clearance so you can run larger tires on stock or aftermarket wheels. ) )
Warning: array_combine(): Both parameters should have an equal number of elements in C:\xampp\htdocs\DCISession.php on line 26
Array ( [headers] => Array ( [0] => PartNo [1] => Company [2] => Status [3] => DateEdited [4] => Comments [5] => Photos [6] => VehicleType [7] => Make [8] => Model [9] => BodyStyle [10] => Driveline [11] => LiftHeight [12] => MaxTire [13] => YearStart [14] => YearEnd [15] => Trademark [16] => Series [17] => Category [18] => SubCategory [19] => 3SubCategory [20] => AssociatedComments [21] => Max 2000 [22] => Application [23] => Max 2000_1 [24] => KitDesc [25] => ExtendedDesc [26] => Max 240 [27] => MarketingDesc [28] => Max 2000_2 [29] => FeaturesBenefits [30] => MAP [31] => MSRP [32] => PriceEffective [33] => DateUpdated [34] => UPC [35] => BoxLength [36] => BoxWidth [37] => BoxHeight [38] => BoxWeight [39] => Color [40] => Country [41] => Carded [42] => ScheduleB ) [values] => Array ( [0] => ) )
Warning: array_combine(): Both parameters should have an equal number of elements in C:\xampp\htdocs\DCISession.php on line 26
Array ( [headers] => Array ( [0] => PartNo [1] => Company [2] => Status [3] => DateEdited [4] => Comments [5] => Photos [6] => VehicleType [7] => Make [8] => Model [9] => BodyStyle [10] => Driveline [11] => LiftHeight [12] => MaxTire [13] => YearStart [14] => YearEnd [15] => Trademark [16] => Series [17] => Category [18] => SubCategory [19] => 3SubCategory [20] => AssociatedComments [21] => Max 2000 [22] => Application [23] => Max 2000_1 [24] => KitDesc [25] => ExtendedDesc [26] => Max 240 [27] => MarketingDesc [28] => Max 2000_2 [29] => FeaturesBenefits [30] => MAP [31] => MSRP [32] => PriceEffective [33] => DateUpdated [34] => UPC [35] => BoxLength [36] => BoxWidth [37] => BoxHeight [38] => BoxWeight [39] => Color [40] => Country [41] => Carded [42] => ScheduleB ) [values] => Array ( [0] => Installation requires no cutting [1] => no welding [2] => and no chassis alterations providing no metal-on-metal contact. Your vehicle will maintain the factory ride quality [3] => stability controls [4] => and towing capacity while being FMVSS126 compliant and carrying Daystar's Lifetime Go Everywhere Warranty!" [5] => 587 [6] => 4" lift height ) )
Warning: array_combine(): Both parameters should have an equal number of elements in C:\xampp\htdocs\DCISession.php on line 26
Array ( [headers] => Array ( [0] => PartNo [1] => Company [2] => Status [3] => DateEdited [4] => Comments [5] => Photos [6] => VehicleType [7] => Make [8] => Model [9] => BodyStyle [10] => Driveline [11] => LiftHeight [12] => MaxTire [13] => YearStart [14] => YearEnd [15] => Trademark [16] => Series [17] => Category [18] => SubCategory [19] => 3SubCategory [20] => AssociatedComments [21] => Max 2000 [22] => Application [23] => Max 2000_1 [24] => KitDesc [25] => ExtendedDesc [26] => Max 240 [27] => MarketingDesc [28] => Max 2000_2 [29] => FeaturesBenefits [30] => MAP [31] => MSRP [32] => PriceEffective [33] => DateUpdated [34] => UPC [35] => BoxLength [36] => BoxWidth [37] => BoxHeight [38] => BoxWeight [39] => Color [40] => Country [41] => Carded [42] => ScheduleB ) [values] => Array ( [0] => Kevlar-infused polyurethane ) )
Warning: array_combine(): Both parameters should have an equal number of elements in C:\xampp\htdocs\DCISession.php on line 26
Array ( [headers] => Array ( [0] => PartNo [1] => Company [2] => Status [3] => DateEdited [4] => Comments [5] => Photos [6] => VehicleType [7] => Make [8] => Model [9] => BodyStyle [10] => Driveline [11] => LiftHeight [12] => MaxTire [13] => YearStart [14] => YearEnd [15] => Trademark [16] => Series [17] => Category [18] => SubCategory [19] => 3SubCategory [20] => AssociatedComments [21] => Max 2000 [22] => Application [23] => Max 2000_1 [24] => KitDesc [25] => ExtendedDesc [26] => Max 240 [27] => MarketingDesc [28] => Max 2000_2 [29] => FeaturesBenefits [30] => MAP [31] => MSRP [32] => PriceEffective [33] => DateUpdated [34] => UPC [35] => BoxLength [36] => BoxWidth [37] => BoxHeight [38] => BoxWeight [39] => Color [40] => Country [41] => Carded [42] => ScheduleB ) [values] => Array ( [0] => Run larger tires on stock or aftermarket wheels for more ground clearance ) )
Warning: array_combine(): Both parameters should have an equal number of elements in C:\xampp\htdocs\DCISession.php on line 26

It's crapping out on my carriage returns and the commas within cells. Lovely... The third line array[0] to [4] is part of the [27]  column from above it. I'm sure I can figure out a search and replace for line feed to something else but what? I'd like to keep separate paragraphs in one column and another column is a list of items so I can't really make a sentence out of them. In the original file that works I was using <br><br> between paragraphs (thought I had used soft returns in places but I guess not). In the original there were 9 columns of features which I've combined into one. I was hoping to keep the readable by normal people and the end use isn't necessarily gonna be HTML.

I know Excel magic is out likely of the scope of this forum but if you have any ideas I'd love to hear them...

Thanks,

Mike

Link to comment
Share on other sites

2 hours ago, big0mike said:

BtW, nice to see a familiar name. When I found out DevShed took a dump I was like, "What do I do now? I have no idea where to go!" Thanks!

Yeah, it was fun times back then. They tried to get us all on one of their other forums, but... ugh. I had been on here before they shut DevShed down and I recommended it to anyone else (who cared about PHP). There are a couple other DS alumni somewhere around here, too.

It's definitely good to have people maintaining the forum you use. People who actually, you know, care about it. Who aren't just letting it sit there accumulate ad revenue while running years-old software.

Link to comment
Share on other sites

Awesome. Thanks. I found a sample down on the fgetcsv page and was actually surprised that I was able to make it work by turning it into

$handle = fopen($DaystarCSV, "r");
while (($data = fgetcsv($handle)) !== false) {
    $DaystarDCIImport[] = $data;
}

As usual, I don't necessarily understand what's happening or why but it appears to be working and everything I need to do with that data I actually do know how to do so the rest of this should be a cakewalk.

Link to comment
Share on other sites

Ahhhhh... spoke to soon. I knew there was no way I was gonna get it first try! I'm now getting an array with 1447 rows and 43 columns where row 0 is the headers of the CSV but I actually need those values to be the KEYs of each column in the array.

I could probably spend an hour writing something that makes a new array based on those keys and then loop through and assign the values of rows 1+ to the new array but I'm guessing there's a function for that?

I'll start googling but you may reply before I stumble upon an answer.

Link to comment
Share on other sites

I didn't mean for you to throw away the code you had before... I meant, you had a specific thing that tried to read each CSV line from the line, using str_getcsv, and instead you replace that with a call to fgetcsv (plus add in fopen/fclose because you have to).

Definitely keep the array_combine and whatever.

Link to comment
Share on other sites

I know I'm not getting better at this because I have to do it so infrequently. So, I must then assume that I'm becoming lucky...

function csv_to_array($filename, $delimiter=',', $enclosure='"', $escape = '\\') {

	if(!file_exists($filename) AND !is_readable($filename)) {echo "File does not exist or is not readable."; return false;}

	$header = null;
    $handle = fopen($filename, "r");
    while (($csv = fgetcsv($handle)) !== false) {
		if(!$header) {
            $header = $csv;
		}
		else {
            $data[] = array_combine($header, $csv);
        }
    }

    fclose($handle);
	return $data;
}

I wasn't sure how to work in the array_map trim but it's data I'm creating and will never come from anywhere else so I know there is likely no white space to trim.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.