Extra empty rows when serving CSV file I'm building a CSV file and serving it up as a downloadable file.  Pretty straightforward.  Thing is, I get 18 leading empty rows in my csv file.  Any ideas?  I've stripped the code down to just about nothing - should I be looking for problems somewhere else?

/**
 * Implementation of hook_menu
 */
  ...
  $items['providers/dashboard/generate-csv/%/%'] = array(
   'title' =&gt; t('Export CSV Data'),
   'page callback' =&gt; 'generate_csv',
   'page arguments' =&gt; array(3, 4),
   'access arguments' =&gt; array('administer module_name content'),
   'type' =&gt; MENU_CALLBACK
  );
  return $items;
}

/**
 * MENU_CALLBACK function
 */
function generate_csv($source_type, $include_unpublished = FALSE) {

  // start up headers
  $csv_name = $source_type . '-csv_' . date('Y-m-d') . '.csv';
  header('Content-Type: text/x-comma-separated-values');
  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  header('Cache-Control: private', false); // required for certain browser
  header('Content-Disposition: attachment; filename="' . $csv_name . '"');

  // write csv data   
  $test_output = "test,test,test";
  print $test_output;
}


EDIT - Looks like it is an issue with the headers, not the content.  If I write the contents of my output to a file, I do not have any extra space at the beginning.  Does anyone know:


What's up with the headers that could be causing the extra spaces?  Or..
How can I ditch any output and start over fresh with my headers?
The comments for my question were pretty much the answer, but I'll elaborate here.

The root of the problem was one of the included files had an ending PHP tag.  However, it wasn't in my code and I had no idea where else to look.

I ended up using something similar, to the following code.

watchdog("Module_name", "Check these files: !files", array("!files" =&gt; implode(get_included_files(), ', ')));


This gave me a list of all the files that Drupal had included in order to run my code.  There were about 140 of them.  

The best way to figure out which might have superfluous end tags would be to cycle through each file programmatically, as Luke Redpath suggests on http://www.designerstalk.com/forums/programming/8005-php-finding-occurences-string-file.html.

In my case the file permissions were giving me trouble, so I brute forced it until I found an unrelated (but custom) module that had a bunch of ?&gt; tags.