I have a series of arrays, like similar:
$my_array = {"foo"=>"bar", "sudo"=>"make_sandwhich", "bam"=>"bang"};
and a csv like:
Header 1, Header 2, foo, Header 4 , bam , Header 5
Lorem. , Ipsum. , , cheesecake, Henrietta, Loreal
, , , , , New Hampshire
And I want the csv to look like this when I add the example line from the start...
Header 1, Header 2, foo, Header 4 , bam , Header 5 , sudo
Lorem. , Ipsum. , , cheesecake, Henrietta, Loreal ,
, , , , , New Hampshire,
, , bar, , bang , , make_sandwhich
I've tried messing with the fputcsv, but it doesn't seem to have anything near the functionality I need. Is there a way to do this?
It can be achieved with fgetcsv and fputcsv and "some" additional processing.
Read your csv file (first row are the headers), then add the new headers from your input row. Then read the rows, create missing data for new headers and add a new row with all the headers at the end. Then just write that data back to csv file.
a.csv - input:
Header 1, Header 2, foo, Header 4 , bam , Header 5
Lorem. , Ipsum. , , cheesecake, Henrietta, Loreal
, , , , , New Hampshire
code:
<?php
$myArray = ["foo"=>"bar", "sudo"=>"make_sandwhich", "bam"=>"bang"];
$readHandle = fopen("a.csv", "r");
// get headers (first row)
$headers = fgetcsv($readHandle);
$allHeaders = [];
foreach ($headers as $header) {
$allHeaders[] = trim($header);
}
// add missing headers from the input data (so to headers from file add sudo header)
foreach (array_keys($myArray) as $data) {
if (!in_array($data, $allHeaders)) {
$allHeaders[] = $data;
}
}
var_dump($allHeaders);
// read all rows from the file and add the new headers
$rows = [];
while($row = fgetcsv($readHandle)) {
foreach ($allHeaders as $k => $header) {
$row[$k] = isset($row[$k]) ? trim($row[$k]) : '';
}
$rows[] = $row;
}
// add the new row from input data
$newRow = [];
foreach ($allHeaders as $header) {
$newRow[] = $myArray[$header] ?? '';
}
$rows[] = $newRow;
var_dump($rows);
fclose($readHandle);
// now write headers and rows to csv file
$writeHandle = fopen('b.csv', 'w+');
fputcsv($writeHandle, $allHeaders);
foreach ($rows as $row) {
fputcsv($writeHandle, $row);
}
fclose($writeHandle);
$allHeaders:
array(7) {
[0]=>
string(8) "Header 1"
[1]=>
string(8) "Header 2"
[2]=>
string(3) "foo"
[3]=>
string(8) "Header 4"
[4]=>
string(3) "bam"
[5]=>
string(8) "Header 5"
[6]=>
string(4) "sudo"
}
$rows:
array(3) {
[0]=>
array(7) {
[0]=>
string(6) "Lorem."
[1]=>
string(6) "Ipsum."
[2]=>
string(0) ""
[3]=>
string(10) "cheesecake"
[4]=>
string(9) "Henrietta"
[5]=>
string(6) "Loreal"
[6]=>
string(0) ""
}
[1]=>
array(7) {
[0]=>
string(0) ""
[1]=>
string(0) ""
[2]=>
string(0) ""
[3]=>
string(0) ""
[4]=>
string(0) ""
[5]=>
string(13) "New Hampshire"
[6]=>
string(0) ""
}
[2]=>
array(7) {
[0]=>
string(0) ""
[1]=>
string(0) ""
[2]=>
string(3) "bar"
[3]=>
string(0) ""
[4]=>
string(4) "bang"
[5]=>
string(0) ""
[6]=>
string(14) "make_sandwhich"
}
}
b.csv - output:
"Header 1","Header 2",foo,"Header 4",bam,"Header 5",sudo
Lorem.,Ipsum.,,cheesecake,Henrietta,Loreal,
,,,,,"New Hampshire",
,,bar,,bang,,make_sandwhich
I hope you dont want the spaces in csv for formatting. It can also be done but you need to keep the amount of characters for the longest string in each column and pad the values to that lengths.