Convert array into csv
I'm using the following function for that; it's an adaptation from one of the man entries in the fputscsv comments. And you'll probably want to flatten that array; not sure what happens if you pass in a multi-dimensional one.
/**
* Formats a line (passed as a fields array) as CSV and returns the CSV as a string.
* Adapted from http://us3.php.net/manual/en/function.fputcsv.php#87120
*/
function arrayToCsv( array &$fields, $delimiter = ';', $enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');
$output = array();
foreach ( $fields as $field ) {
if ($field === null && $nullToMysqlNull) {
$output[] = 'NULL';
continue;
}
// Enclose fields containing $delimiter, $enclosure or whitespace
if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
$output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure;
}
else {
$output[] = $field;
}
}
return implode( $delimiter, $output );
}
A slight adaptation to the solution above by kingjeffrey for when you want to create and echo the CSV within a template (Ie - most frameworks will have output buffering enabled and you are required to set headers etc in controllers.)
// Create Some data
<?php
$data = array(
array( 'row_1_col_1', 'row_1_col_2', 'row_1_col_3' ),
array( 'row_2_col_1', 'row_2_col_2', 'row_2_col_3' ),
array( 'row_3_col_1', 'row_3_col_2', 'row_3_col_3' ),
);
// Create a stream opening it with read / write mode
$stream = fopen('data://text/plain,' . "", 'w+');
// Iterate over the data, writting each line to the text stream
foreach ($data as $val) {
fputcsv($stream, $val);
}
// Rewind the stream
rewind($stream);
// You can now echo it's content
echo stream_get_contents($stream);
// Close the stream
fclose($stream);
Credit to Kingjeffrey above and also to this blog post where I found the information about creating text streams.
My solution requires the array be formatted differently than provided in the question:
<?
$data = array(
array( 'row_1_col_1', 'row_1_col_2', 'row_1_col_3' ),
array( 'row_2_col_1', 'row_2_col_2', 'row_2_col_3' ),
array( 'row_3_col_1', 'row_3_col_2', 'row_3_col_3' ),
);
?>
We define our function:
<?
function outputCSV($data) {
$outputBuffer = fopen("php://output", 'w');
foreach($data as $val) {
fputcsv($outputBuffer, $val);
}
fclose($outputBuffer);
}
?>
Then we output our data as a CSV:
<?
$filename = "example";
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename={$filename}.csv");
header("Pragma: no-cache");
header("Expires: 0");
outputCSV($data);
?>
I have used this with several projects, and it works well. I should note that the outputCSV
code is more clever than I am, so I am sure I am not the original author. Unfortunately I have lost track of where I got it, so I can't give the credit to whom it is due.