6

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;
}
user2428118
  • 7,935
  • 4
  • 45
  • 72
Erik S
  • 1,939
  • 1
  • 18
  • 44
  • I see that submitting this from my phone caused some ugly formatting, will fix this asap. – Erik S Mar 28 '14 at 12:48
  • Formatting looks OK on browser. – Albzi Mar 28 '14 at 12:48
  • Are you using the [download helper](http://ellislab.com/codeigniter/user-guide/helpers/download_helper.html) or doing it manually? – stormdrain Mar 28 '14 at 13:13
  • Can you post the code you are using? – stormdrain Mar 28 '14 at 13:52
  • And you said you tried `$contents = str_replace("\n","", $contents);` before the `echo`? – stormdrain Mar 28 '14 at 16:54
  • Yes, I did. This just caused all contents to be on the 2nd line. – Erik S Mar 29 '14 at 03:36
  • Are you using any flags when creating the file ? FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES – Philip Mar 31 '14 at 09:36
  • No, it's a simple file_put_contents without flags. – Erik S Mar 31 '14 at 09:55
  • Did you try `$contents = str_replace(array("\r", "\n"),"", $contents);` before `echo`..? just in case – Hecke29 Mar 31 '14 at 13:26
  • Yup... It really seems to come from before the script this code is in, which limits it to a few hundred files. – Erik S Mar 31 '14 at 13:29
  • Maybe you could start output-buffering `ob_start();` before including 100 files and drop the buffer before creation of the file? But that's not the solution isn't it? You think the linebreak comes from `incasso_file()`? What about viewing the XML file in a HEX-Editor or stuff like that to see which char it is. – Hecke29 Mar 31 '14 at 14:03
  • Ob_buffer actually might be an option... Though I'd have to change core CI files to do that. Unless that will mess too much with output such as Ajax... – Erik S Mar 31 '14 at 15:26
  • You could have whitespace in any of the CodeIgniter files that are being called. Have you checked, index, controllers and models that are in use? – AJReading Apr 01 '14 at 02:17
  • Should be fairly easy to run a grep on the command line to find all closing PHP tags to see how many files you need to change. Obviously that doesn't help you with your need to update third party plugins/libraries, but you could at least remove them for the time being and see if that fixes the problem. – kevindeleon Apr 01 '14 at 18:47
  • Yea, i did the grep search, and found a lot in third party libs; I removed them from my own files. Especially Smarty really loves those tags... – Erik S Apr 01 '14 at 18:55
  • @ErikDolor know a ton of people ran into this problem using WordPress and Feedburner...This guy wrote a solution that goes at the very top of the WordPress index file...with some tweaking, you might be able to get it to work for CodeIgniter as well. Don't have time to work out in an answer, so I'll leave it as a comment. http://wejn.org/stuff/wejnswpwhitespacefix.php.html – kevindeleon Apr 01 '14 at 19:10
  • @kevindeleon I will try this fix soon, will let you know if that solved it. – Erik S Apr 02 '14 at 12:38
  • Sorry for the late response. @kevindeleon: Unfortunately, the script did not solve it. – Erik S Apr 04 '14 at 16:14

5 Answers5

3

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.

dAngelov
  • 830
  • 6
  • 10
  • This would, however, require modifying core Codeigniter files, and i'm afraid it could mess with output, such as error messages being printed or ajax being called, when the execution does not actually finish in the place where you'd normally expect it (At the end of the central index.php). – Erik S Apr 02 '14 at 12:51
  • The output would only be cleared when that function is called, so any other CI functionality would stay the same. As for errors, you don't want them being printed anyway, for security reasons - better to forward (store) them in an error log file or db. – dAngelov Apr 02 '14 at 12:54
  • Correct me if I'm wrong, but wouldn't the output only be printed after an `ob_flush()` or something similar? And I do get your point on security, however, this is an internally used tool, and pages where these error messages are used are not publicly accessible. – Erik S Apr 02 '14 at 13:00
  • Using `ob_end_clean();` you're closing that output buffer we opened, so what you're left with is the default buffer, which gets "flushed" when the script ends execution (most of the time) or as soon as output from your script fills up the server buffer, which then sends it to the client. Have you given it a try? – dAngelov Apr 02 '14 at 17:15
  • Apparently, it works a bit different than I thought, and it does not seem to break all of my site. Thanks! – Erik S Apr 04 '14 at 16:15
0

Vi editor (or vim) leaves an extra newline at the end of edited file. If you have used vi for any included file, that must be the issue.

Following answer describes removing newlines at the end of files in an easy way:

How can I delete a newline if it is the last character in a file?

Given command can be used together with linux find to remove all trailing newlines in php files.

for i in `find /path/to/project -name *.php`
do
    perl -i -pe 'chomp if eof' $i
done
Community
  • 1
  • 1
mesutozer
  • 2,839
  • 1
  • 12
  • 13
0

I did not understand your problem exactly, but since your $content is a string, You can simply use

echo trim($content)

To remove the new lines

ahmad
  • 2,709
  • 1
  • 23
  • 27
0

This works for me.

header('Content-type: text/xml');
print_r ($content);
Cory Charlton
  • 8,868
  • 4
  • 48
  • 68
Tony
  • 1
0

For php feed use this to remove space ob_end_clean();

   $data['encoding'] = 'UTF-8';       
   $data['query'] = $this->Feed_model->get_feeds();
   header("Content-Type: application/rss+xml");
   ob_end_clean();
   $this->load->view('rss',$data);