How to redirect STDOUT to a file in PHP?

The code below almost works, but this is 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?

+49
php stdin stdout
Jun 02 '09 at 1:53
source share
7 answers

You can write STDOUT directly to a file in PHP, which is much simpler and simpler than using output buffering.

Do this at the very beginning of your script:

 fclose(STDIN); fclose(STDOUT); fclose(STDERR); $STDIN = fopen('/dev/null', 'r'); $STDOUT = fopen('application.log', 'wb'); $STDERR = fopen('error.log', 'wb'); 

Why at the very beginning you can ask? No file descriptors need to be opened, because when you close the standard input, output, and error file descriptors, the first three new descriptors will become the NEW standard input, output, and error file descriptors.

In my example here, I redirected standard input to / dev / null and the descriptors of the output file and the error file to the log files. This is common practice when creating a daemon script in PHP.

To write the application.log file, this will be enough:

 echo "Hello world\n"; 

To write to error.log , you would need:

 fwrite($STDERR, "Something went wrong\n"); 

Note that when changing input, output, and error descriptors, the built-in PHP constants STDIN, STDOUT, and STDERR will not be available. PHP will not update these constants for new descriptors, and they are not allowed to override these constants (they are called constants for some reason).

+110
Sep 29 '10 at 15:17
source share

here's a way to reject OUTPUT, which seems like the original problem

 $ob_file = fopen('test.txt','w'); function ob_file_callback($buffer) { global $ob_file; fwrite($ob_file,$buffer); } ob_start('ob_file_callback'); 

more details here:

http://my.opera.com/zomg/blog/2007/10/03/how-to-easily-redirect-php-output-to-a-file

+14
Nov 06 '12 at 23:01
source share

No, output buffering is as good as it gets. Although it's a little better than just doing

 ob_start(); echo 'xxx'; $contents = ob_get_flush(); file_put_contents($file,$contents); 
+8
Jun 02 '09 at 2:24
source share

Here is an ugly solution that was useful for the problem I had (need to debug).

 if(file_get_contents("out.txt") != "in progress") { file_put_contents("out.txt","in progress"); $content = file_get_contents('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); file_put_contents("out.txt",$content); } 

The main disadvantage is that you better not use the $ _POST variables. But you should not put it at the very beginning.

+1
Nov 25
source share

You can install the Eio extension

pecl install eio

and duplicate file descriptor

 $temp=fopen('/tmp/my_stdout','a'); $my_data='my something'; $foo=eio_dup2($temp,STDOUT,EIO_PRI_MAX,function($data,$esult,$request){ var_dump($data,$esult,$request); var_dump(eio_get_last_error($request)); },$my_data); eio_event_loop(); echo "something to stdout\n"; fclose($temp); 

this creates a new file descriptor and overwrites the target STDOUT stream

it can also be done with STDERR

and constants STD [OUT | ERR] are still available

+1
Sep 09 '15 at 11:02
source share

Using eio pecl module eio is very simple, you can also write internal PHP errors, var_dump, echo, etc. In this code you can find some examples of different situations.

 $fdout = fopen('/tmp/stdout.log', 'wb'); $fderr = fopen('/tmp/stderr.log', 'wb'); eio_dup2($fdout, STDOUT); eio_dup2($fderr, STDERR); eio_event_loop(); fclose($fdout); fclose($fderr); // output examples echo "message to stdout\n"; $v2dump = array(10, "graphinux"); var_dump($v2dump); // php internal error/warning $div0 = 10/0; // user errors messages fwrite(STDERR, "user controlled error\n"); 

The eio_event_loop call is used to ensure that previous eio requests have been processed. If you need to add to the log by calling fopen, use the 'ab' mode instead of the 'wb'.

Installing the eio module is very simple ( http://php.net/manual/es/eio.installation.php ). I checked this example with version 1.2.6 of the eio module.

+1
May 31 '16 at 21:55
source share

None of the answers worked for my specific case, when I needed a cross-platform way of redirecting the output as soon as it was an echo, so that I could monitor the logs using tail -f log.txt or another application log viewer. I came up with the following solution:

 $logFp = fopen('log.txt', 'w'); ob_start(function($buffer) use($logFp){ fwrite($logFp, $buffer); }, 1); //notice the use of chunk_size == 1 echo "first output\n"; sleep(10) echo "second output\n"; ob_end_clean(); 

I did not notice any performance issues, but if you do, you can change chunk_size to large values.

Now just the tail is the log file:

 tail -f log.txt 
0
Feb 24 '17 at 18:56
source share



All Articles