how to redirect STDOUT to a file in PHP?

Viewed 65206

The code below almost works, but it's not what I really meant:

ob_start();
echo 'xxx';
$contents = ob_get_contents();
ob_end_clean();
file_put_contents($file,$contents);

Is there a more natural way?

8 Answers

No, output buffering is as good as it gets. Though it's slightly nicer to just do

ob_start();
echo 'xxx';
$contents = ob_get_flush();
file_put_contents($file,$contents);

I understand that this question is ancient, but people trying to do what this question asks will likely end up here... Both of you.

If you are running under a particular environment...

  • Running under Linux (probably most other Unix like operating systems, untested)
  • Running via CLI (Untested on web servers)

You can actually close all of your file descriptors (yes all, which means it's probably best to do this at the very beginning of execution... for example just after a pcntl_fork() call to background the process in a daemon (which seems like the most common need for something like this)

fclose( STDIN );  // fd 3
fclose( STDERR);  // fd 2
fclose( STDOUT ); // fd 1

And then re-open the file descriptors, assigning them to a variable that will not fall out of scope and thus be garbage collected. Because Linux will predictably open them in the proper order.

$kept_in_scope_variable_fd1 = fopen(...); // fd 1
$kept_in_scope_variable_fd2 = fopen(...); // fd 2
$kept_in_scope_variable_fd3 = fopen( '/dev/null', ... ); // fd 3

You can use whatever files or devices you want for this. I gave /dev/null as the example for STDIN (fd3) because that's probably the most common case for this kind of code.

Once this is done you should be able to do normal things like echo, print_r, var_dump, etc without specifically needing to write to a file with a function. Which is useful when you're trying to background code that you do not want to, or aren't able to, rewrite to be file-pointer-output-friendly.

YMMV for other environments and things like having other FD's open, etc. My advice is to start with a small test script to prove that it works, or doesn't, in your environment and then move on to integration from there.

Good luck.

Related