Where can I save a CSV file that I construct dynamically to make it available for download? I dynamically construct a CSV file following that method:

$fp = fopen('export.csv', 'w');
foreach ($export as $fields) {
  fputcsv($fp, $fields);
}
fclose($fp);


A file 'export.csv' appears in the very root of my Drupal directory.

I display a link to a page, allowing user to download that CSV file:

drupal_set_message(l('Export to CSV', 'export-csv'));


In the page callback function, I make the file downloadable like this:

function grap_contact_export_csv_page() {
  header("Cache-Control: public");
  header("Content-Type: application/octet-stream");
  header("Cache-Control: no-store, no-cache, must-revalidate");
  header("Cache-Control: post-check=0, pre-check=0");
  header("Content-Disposition: attachment; filename=\"grape-export.csv\";" );
  header("Content-Transfer-Encoding: binary");
  $fp = fopen('export.csv', 'r') or die('Cannot access the file');
  echo fread($fp, filesize('export.csv'));
  fclose($fp);
  drupal_exit();
}


That works well.

What disturbs me is the location of the file. Of course, I know that I should not save it there. My question is: Where is the optimal location to save that kind of files? In the custom module's directory? In sites/default/files? What is the best practice?
The best practice is to use Drupal functions, not direct PHP functions, if there is Drupal API available. Particularly, here you may be interested in file_save_data and file_unmanaged_save_data.

If you want file available for short time, unmanaged file may be the way to go. But if you want periodic exports, archiving of prepared files, automatic clean-up etc, Managed is the way to go. If in doubt, try managed.

Examples for Developers offers a pretty good file_example.module, read it, play with it, and come back with more specific question.