ob_start et al or fopen('php://output', 'r+')

I was coding some extra functionality into some of my classes, and started writing code which exports a MySQL table to various formats, amongst others, CSV.

Now, PHP has to lovely functions, fgetcsv and fputcsv. The only problem is they only output to a file, nothing else. So, if you want the CSV data as a string, it complicates things.

Not realy. You just open a stream stream to a temp file:

if (!count($list)) return '';
$fh = fopen('php://temp','r+');
if ($fh) {
	$size = 0;
	foreach($list as $row) {
		$row = (array)$row;
		$size += fputcsv($fh, $row);
	}
	fseek($fh, 0);
	$toret = fread($fh, $size);
	fclose($fh);
}


Just a few comments on the code:

  • $list is an array of either arrays or objects containing the values for the CSV file.
  • Each $row gets converted to an array to pass to fputcsv.
  • The fseek function ensures that we read from the beginning of the file.

Easy as 3.14159...

This got me thinking, though. What if I wanted to return the output of a print_r statement as a string? Just as easy. This is the default __toString function I use in my objects:

function __toString() {
	$fh = fopen('php://output', 'r+');
	$toret = '';
	if ($fh) {
		print_r($this);
		fseek($fh, 0);
		$toret = stream_get_contents($fh);
	}
	return $toret;
}

Before this, I used to do this:

function __toString() {
	ob_start();
	print_r($this);
	$toret = ob_get_contents();
	ob_end_clean();
	return $toret;
}


This seems simpler. I must say, I'm in two minds about which function works best. The first one is quite low level, but seems very complicated, while I don't like the use of the output buffering. Any comments?