Book HomePHP CookbookSearch this book

18.23. Reading Standard Output from a Program

18.23.1. Problem

You want to read the output from a program; for example, you want the output of a system utility such as route(8) that provides network information.

18.23.2. Solution

To read the entire contents of a program's output, use the backtick (') operator:

$routing_table = `/sbin/route`;

To read the output incrementally, open a pipe with popen( ):

$ph = popen('/sbin/route','r') or die($php_errormsg);
while (! feof($ph)) {
    $s = fgets($ph,1048576)    or die($php_errormsg);
}
pclose($ph)                    or die($php_errormsg);

18.23.3. Discussion

The backtick operator (which is not available in safe mode), executes a program and returns all its output as a single string. On a Linux system with 448 MB of RAM, this command:

$s = `/usr/bin/free`;

puts this multiline string in $s:

             total       used       free     shared    buffers     cached
Mem:        448620     446384       2236          0      68568     163040
-/+ buffers/cache:     214776     233844
Swap:       136512          0     136512

If a program generates a lot of output, it is more memory-efficient to read from a pipe one line at a time. If you're printing formatted data to the browser based on the output of the pipe, you can print it as you get it. This example prints information about recent Unix system logins formatted as an HTML table. It uses the /usr/bin/last command:

// print table header
print<<<_HTML_
<table>
<tr>
 <td>user</td><td>login port</td><td>login from</td><td>login time</td>
 <td>time spent logged in</td>
</tr>
_HTML_;

// open the pipe to /usr/bin/last
$ph = popen('/usr/bin/last','r') or die($php_errormsg);
while (! feof($ph)) {
    $line = fgets($ph,80) or die($php_errormsg);

    // don't process blank lines or the info line at the end
    if (trim($line) && (! preg_match('/^wtmp begins/',$line))) {
        $user = trim(substr($line,0,8));
        $port = trim(substr($line,9,12));
        $host = trim(substr($line,22,16));
        $date = trim(substr($line,38,25));
        $elapsed = trim(substr($line,63,10),' ()');
        
        if ('logged in' == $elapsed) {
            $elapsed = 'still logged in';
            $date = substr_replace($date,'',-5);
        }
        
        print "<tr><td>$user</td><td>$port</td><td>$host</td>";
        print "<td>$date</td><td>$elapsed</td></tr>\n";
    }
}
pclose($ph) or die($php_errormsg);

print '</table>';

18.23.4. See Also

Documentation on popen( ) at http://www.php.net/popen, pclose( ) at http://www.php.net/pclose, and the backtick operator at http://www.php.net/language.operators.execution; safe mode is documented at http://www.php.net/features.safe-mode.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.