Here is the situation: I have a unix program which outputs some lines and wouldn't terminate as it continuously listens. Now I would like to output the lines in a PHP script. I used the system() function but it was blocking the running of the rest of the code as the unix program doesn't terminate. I am thinking about the possibility of outputting the line once a line is output by the unix program in the console. How would I achieve this? Thank you.
- 
                    1vary interesting question. i'd start by looking into http://ca3.php.net/manual/en/function.proc-open.php and http://php.net/manual/en/function.stream-get-line.php – code_monk Nov 02 '14 at 02:00
 - 
                    May be you can redirect outputs to a log file and then use php to read this file. – akmozo Nov 02 '14 at 03:29
 
2 Answers
A good solution is to use proc_open(), because you can work with all pipes. Nice approach is demonstrated here: http://codehackit.blogspot.be/2012/04/automating-command-line-scripts-in-php.html
I am thinking about the possibility of outputting the line once a line is output by the unix program in the console.
Easy sentence - complicated problem.
This would involve monitoring the output buffer or output logfile for a change and then react on that . Event bound. Try to work with $proc->on() to detect things in your output buffer, in order to trigger a callback.
Referencing: Proper shell execution in PHP & https://stackoverflow.com/a/1533818/1163786
- 1
 - 1
 
- 39,862
 - 13
 - 113
 - 141
 
- 
                    1The code you've got in your first example doesn't actually work as intended. The `&` doesn't do anything here; the `exec()` blocks until the command exits. – Nov 02 '14 at 04:06
 - 
                    1
 
Here's a sample script which will do the trick for you:
 $cmd='/bin/ls -la';
 $gs="\n"; // this is the delimiter of each line. use "\r\n" in case of windows ...
 $pipesDescr=array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("file", "/tmp/error.log", "a"), );
 $p=proc_open($cmd, $pipesDescr, $pipes);
 if ($p)
 {
  stream_set_blocking($pipes[0],0);
  stream_set_blocking($pipes[1],0);
  $work=true; $buffer=''; $mode='idle'; $command=''; $idle=0;
  while ($work)
  {
   if ($mode=='idle')
   {
    if ($command<>'')
    {
     fwrite($pipes[0],$command."\n");
     $command='';
     $idle=0;
     $speed=500; // microseconds!
    }
    else
    {
     $speed=100000; // microseconds !
    }
   }
   $s=fread($pipes[1],1024);
   if ($s<>'')
   {
    $mode='action';
    $buffer.=$s;
    while (strstr($buffer,$gs))
    {
     $ex=explode($gs,$buffer,2);
     {
      $buffer=@$ex[1]; $line=@$ex[0];
      // here you can process the line with something ...
      print($line."<br/>\n");
      //
     }
    }
    $speed=500;
    $idle=0;
   }
   else
   {
    if (@$idle<1000)
    {
     $idle++; // did not idled for too long, let's still watch intensely for new data
    }
    else
    {
     $speed=100000; // it's been idle for a while, let's not overload the CPU for nothing ...
     $mode='idle';
    }
   }
   $status=proc_get_status($p);
   if (!$status["running"]) {$work=false;} // if the program has quited, we should do so as well ...
  } // end of $work loop
  proc_close($p);
 }
This example is using proc_open, and keeps running until your process terminates, or until you decide to quit. (in this case, you should set $work to false ...)
- 433
 - 3
 - 9