I have a dataset of in a particular format in CSV
key=value,key2=value,key3=value
key=value,key2=value,key4=value,key3=value
I want to convert it to:
key,key2,key3,key4
value,value,value,null
value,value,value,value
But there are array mismatches in output csv.
I need to sort the header columns, ensure that subsequent row values are in the right columns, and if a given column value is missing use the string null
.
This is my coding attempt:
if (($handle = fopen("sheet4.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$cols = explode(",", $data[0]);
$num = count($cols);
for ($c = 0; $c < $num; $c++) {
$colData = explode("=", $cols[$c]);
$outputHeaders[$row][$colData[0]] = $colData[0];
$output[$row][$colData[0]] = $colData[1];
}
$csvOutput[$row] = array_combine($outputHeaders[$row], $output[$row]);
$row++;
}
fclose($handle);
}
foreach ($csvOutput as $row => $rowData) {
$extractHeaders[] = array_keys($rowData);
}
$mergedHeaders = array_unique(call_user_func_array('array_merge', $extractHeaders));
$fp = fopen('sheet4out.csv', 'wa');
fputcsv($fp, $mergedHeaders);
foreach ($csvOutput as $key => $fields) {
$rowKeys = array_keys($fields);
if (count($mergedHeaders) == count($rowKeys)) {
} else {
$differntKeys = array_diff($mergedHeaders, $rowKeys);
$fields = array_merge($fields, array_fill_keys($differntKeys, 'banana'));
}
fputcsv($fp, $fields);
}
You shouldn't call
explode(',', $data[0])
.fgetcsv()
already exploded the line, so$data[0]
is just the first field.While you're reading the input CSV, just add each field name to the headers array. You can keep this small by calling
array_unique()
after each row.When creating the output row, you can use the null coalescing operator to provide
null
as a default value for missing keys in a row.