Generate file path for created file so it can be downloaded I'm writing a module based on this Jeff Geerling post that will allow the user to use a form to select some data, and then use the Batch API to generate a large .csv file with the desired data and download it from the browser. I have the form and batch processing working fine, but I can't figure out how to determine the path for the created file, as referenced in this code snippet:

/**
 * Interim download step for downloading CSV file.
 */
function MYMODULE_download_csv_file_interim($list_id) {
  global $base_url;

  if (empty($_SESSION['csv_download_filename']) || empty($_SESSION['csv_download_file'])) {
    return t('Please visit your list subscribers page to begin a list download.');
  }

  $list = node_load($list_id);

  // Redirect to the download file.
  $redirect = base_path() . 'path/to/download/csv/' . $list_id;
  drupal_add_js('setTimeout(function() { window.location.href = "' . $redirect . '"; }, 2000);', 'inline');

  $download_link = l(t('click here to download the file'), 'path/to/download/csv/' . $list_id);
  $output = '&lt;p&gt;' . t('Your subscriber list is now ready for download. The download should begin automatically. If it does not begin downloading within 5 seconds, please !download_link.', array('!download_link' =&gt; $download_link)) . '&lt;/p&gt;';
  $output .= '&lt;p&gt;' . l(t("&amp;#8592; Back to %list subscribers", array('%list' =&gt; $list-&gt;title)), 'node/' . $list_id . '/subscribers', array('html' =&gt; TRUE)) . '&lt;/p&gt;';
  return $output;
}


At this point in the code, $_SESSION['csv_download_file'] is tmp/my_file.csv. I've tried to figure how to make this a valid url for downloading the file, but can't. For instance, I've tried using file_create_url(), but it just returns the same path.

What do I need to use to make this a valid URL to pass to the browser?
/tmp is outside of webroot so apache (or whatever) can't serve files from there.

You have 2 options:


Move the file from /tmp to your public files directory. This will mean anyone will have access to it (if they know the url). See file_unmanaged_move().


Eg.

$source = '/tmp/my_file.csv';
$destination = 'public://csv/my_file.csv';
file_unmanaged_move($source, $destination);



Stream the file to the browser via php. This means only people who can access your php script can get access to the file.


Eg.

header('Content-type: text/csv');
header('Content-disposition: attachment;filename=my_file.csv');
return readfile('/tmp/my_file.csv');