I'm attempting to capture the output of fputcsv()
in order to use gzwrite()
to actually write to a tab-delimited file. Basically, I'm querying a database and I want to put these rows into a gzipped CSV file and I'd rather use fputcsv()
than actually append "\t"
and " "
everywhere. Can I somehow do this with output buffering or something similar?
Here's the basic outline of what I have:
$results = get_data_from_db();
$fp = gzopen($file_name, 'w');
if($fp) {
foreach ($results as $row) {
???//something with gzwrite() ?
}
gzclose($fp);
}
Thanks!
EDIT: My understanding was that gzwrite()
needs to be used to actually write to the file in order for it to actually be gzipped - is this not correct?
Maybe I'm misunderstanding the question but fputcsv()
operates on a file handle, which is what gzopen returns, so you can do this:
$results = get_data_from_db();
$fp = gzopen($file_name, 'w');
if($fp) {
foreach ($results as $row) {
fputcsv($fp, $row);
}
gzclose($fp);
}
I've tested this and it works fine.
You can do it by writing your own stream handler to intercept the writes to the underlying file.
Edit: After reading the spec example 3 on this page sounds like it might be of interest to you
As read on php.net, you could try this little trick:
<?php
// output up to 5MB is kept in memory, if it becomes bigger
// it will automatically be written to a temporary file
$csv = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
fputcsv($csv, array('blah','blah'));
rewind($csv);
// put it all in a variable
$output = stream_get_contents($csv);
?>
This is actually what you tried to avoid (capturing the output), but capturing is a very powerful tool, so why not use it?
Don't forget you can always do this manually without using the csv function without doing anymore work already. I had to do this recently so I could take the same data and either output a CSV as tab delimited, comma delimited or something a browser could display.
All you need to do is use basic arrays and implode (here's a basic example, you need to add some vars to support proper HTMl table output such as column head and tail, row head and tail, etc... but you get the idea:
switch ( $_GET['mode'] )
{
case "csv":
$wrapper = "'";
$delimiter = ",";
$nextrow = "
";
break;
case "txt":
$wrapper = "";
$delimiter = "\t";
$nextrow = "
";
break;
case "html":
$wrapper = "'";
$delimiter = ",";
break;
}
$output = array();
$sql = "SELECT * FROM table";
$result = mysql_query($sql);
while ( $row = mysql_fetch_assoc($result) )
{
$line = array();
foreach ( $row as $column => $value )
{
$line[] = $wrapper . $value . $wrapper;
}
$output[] = implode("", $line) . $nextrow;
}
print implode("",$output);