Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty line in PHP (CodeIgniter) file download

On my CodeIgniter-based site (a member management system), there is functionality to create direct debit files. These are downloaded by setting the headers, as explained here: http://www.richnetapps.com/the-right-way-to-handle-file-downloads-in-php/. However, for some reason, an empty line is always outputted before my own output. I've tried replacing all newlines in the string I was returning with no success. The output is an XML file, and my bank does not accept the file as valid XML because of this empty line.

I've already found posts saying this is likely because of PHP closing tags in files before the current file. This might be the cause, but Several third party libraries are loaded, and manually removing all closing PHP tags in each file is undoable if you still want to keep the option to update your libraries. It seems that especially Smarty is fond of these closing tags.

Directly accessing the file itself is also not really an option, because CodeIgniter does not allow this by default, and because this method imposes quite a security problem (publically accessible files with bank account details in them are a big no-no).

Therefore, I come to you: do you know another possible solution to this problem?

Edit: This is the code used for the download.

function incasso_archive($creditor, $date, $time, $extension)
{
    $date = str_replace("_", "-", $date);

    $fn = $this->incasso->incasso_file($creditor, $date, $time, $extension);

    $contents = file_get_contents($fn);
    $name = "Incasso $date.$extension";

    header('Content-Type: application/octet-stream');
    header('Content-Transfer-Encoding: Binary');
    header('Content-disposition: attachment; filename="'.$name.'"');
    echo $contents;
}
like image 268
Erik S Avatar asked Mar 28 '14 12:03

Erik S


1 Answers

If $contents in your function does not have a newline, try using the output buffer functions.

At the beginning of your file, before including any other files, call ob_start();. Then, inside your function, before echo $contents;, add ob_end_clean();. This will make sure none of the output from other scripts is sent.

like image 133
dAngelov Avatar answered Sep 27 '22 22:09

dAngelov