PHP code example of takuya / php-process-exec

1. Go to this page and download the library: Download takuya/php-process-exec library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

takuya / php-process-exec example snippets


// prepare
$p1arg = new ExecArgStruct("cat /etc/passwd ");
$p2arg = new ExecArgStruct('grep takuya');
// pipe 
$p1 = new ProcessExecutor($p1arg);
$p2 = $p1->pipe($p2arg);
$p2->start();
echo $p2->getOutput();


$executor = new ProcessExecutor(['bash']);
$executor->setInput('
for i in {0..4}; do
  echo $i
done;
');
$executor->start();
//blocking io
echo $executor->getOutput();


$arg = new ExecArgStruct('php');
$src =<<<'EOS'

foreach(range(0,4) as $i){
  printf("%d\n",$i);
}
EOS;
$arg->setInput( $src );
$executor = new ProcessExecutor( $arg );
$executor->onStdOut(function ($line){ //=> each line.
  echo $line.PHP_EOL;
});
$executor->start();


// process argument as class
$arg = new ExecArgStruct();
$arg->setCmd( ['php'] );
$src = <<<'EOS'
 echo 'Hello World';
EOS;
$arg->setInput( $src );
// run callback by running status.
$observer = new ProcessObserver();
$observer->addEventListener( ProcessErrorOccurred::class, fn()=> fwrite("php://stderr","エラー") );
$observer->addEventListener( ProcessFinished::class, fn($ev) =>print($ev->getExecutor()->getOutput()) );
// start process.
$executor = new ProcessExecutor( $arg );
$executor->addObserver( $observer );
$executor->start();


# avoid Shell Injection vulnerability by pass as array
# Skip shell escaping.
$file_name = 'my long spaced doc.txt';
proc_open(['cat',$file_name]...);


# avoid Directory traversal vulnerability by check path.
$file_name = '../../../../../../../../etc/shadow';
$file_name = realpath('/my/app_root/'.basename($file_name);
proc_open(['cat',$file_name]...);


## using proc_open as Class
$proc = new ProcOpen(['cat',$fname]);
$proc->start();
echo stream_get_contents($proc->stdout());


##  command option as struct
$struct = new ExecArgStruct(['cat',$fname]);
$proc = new ProcessExecutor($struct);
$proc->start();
echo $proc->getOutput();
// reusable ARGS and easy to run multiple times.
$proc = new ProcessExecutor($struct);
$proc->start();
echo $proc->getOutput();


class RestrictedArg extends ExecArgStruct {
  public function __construct(...){
    // check allow command.
    $this->check() || throw new InvalidArgumentException();
  }
}
// InvalidArgumentException
$struct = new RestrictedArg(['passwd',$name]);


class MyFFmpegStruct extends ExecArgStruct {
  public function __construct(...){
    // check command options.
    $this->checkOptions() || throw new \Exception('you need "-f" option ');
  }
}
//-> InvalidArgumentException
$struct = new MyFFmpegStruct(['ffmpeg','-i',$name]);


// define Struct of CMD
$arg = new ExecArgStruct('php -i');
$executor = new ProcessExecutor($arg);
// Observer( aggregate of Listener ).
$observer = new ProcessObserver();
$observer->addEventListener(ProcessStarted::class, fn()=>dump('started')));
$observer->addEventListener(ProcessSuccess::class, fn()=>dump('successfully finisihed')));
$observer->addEventListener(ProcessRunning::class, fn()=>dump('running')));
$observer->addEventListener(ProcessRunning::class, function(ProcessRunning $ev){
  // Listeners can be added per Event.
  printf("pid=%d",$ev->getExecutor()->getProcess()->info->pid);
});
// Second Observer.
$streamObs = new ProcessObserver();
$streamObs->addEventListener(StdoutChanged::class, fn()=>dump('stdout changed')));
// Bind Observer with CMD executor
$executor->addObserver($observer);
$executor->addObserver($streamObs);
$executor->start();


## simple listener.
$executor = new ProcessExecutor( new ExecArgStruct(['cat','file']) );
$executor->onStdOut(function ($line){
  echo $line.PHP_EOL;
});
$executor->start();



$executor = new ProcessExecutor( new ExecArgStruct(['cat','-']) );
$executor->setInput(fopen('file','r'));
$executor->onInputProgress(fn($percent)=>printf("%s%%\n",$percent));
$executor->start();


$p1_fd_res = [['pipe','r'],['pipe','w'],['pipe','w']];
$p1 = proc_open(['ls','/etc'],$p1_fd_res,$p1_pipes);
fclose($p1_pipes[0]);
$p2_fd_res = [$p1_pipes[1],['pipe','w'],['pipe','w']];
$p2 = proc_open(['grep','su'],$p2_fd_res,$p2_pipes);

while(proc_get_status($p1)["running"]){
usleep(100);
}
while(proc_get_status($p2)["running"]){
usleep(100);
}
//
$str = fread($p2_pipes[1],1024);
var_dump($str);


$p1 = new ProcOpen(['/bin/echo',' echo "Hello";']);
$p1->start();
$p2 = new ProcOpen(['/usr/bin/php']);
$p2->setInput($p1->stdout());
$p2->start();
$p1->wait();
$p2->wait();
//
echo stream_get_contents($p2->stdout()); //=> Hello


$arg1 = new ExecArgStruct('bash');
$arg1->setInput( <<<EOS
  echo -n ' echo "Hello World".PHP_EOL;';
  EOS );
$e1 = new ProcessExecutor( $arg1 );
$e2 = new ProcessExecutor( new ExecArgStruct('php') );
$e1->pipe($e2);
$out = $e2->getOutput();
echo $out


// Pipe process
$pv = new ExecArgStruct( 'pv -f -L 2M work.mp4' );
$ffmpeg = new ExecArgStruct('ffmpeg -i pipe:0 -s 1280x720 -movflags faststart out.mp4');
$p1 = new ProcessExecutor( $pv );
$p2 = new ProcessExecutor( $ffmpeg );
$p1->pipe( $p2 );
// Each STDERR can be access.
$p1->onStderr( fn( $progress ) => dump("pv: ".$progress) , "\r" );
$p2->onStderr( fn( $enc_stat ) => dump("ffmpeg: ".$enc_stat), "\r" );


// stopped by IO Blocking at stdout.
$arg = ExecArgStruct('ffmpeg -i input.mp4 -s 1280x720 -f mp4 pipe:1');
$ffmpeg = new ProcessExecutor( $arg );
$ffmpeg->start();// blocked

// not stopped,
// stdout will be written to FILE(output.bin) 
$arg = ExecArgStruct('ffmpeg -i input.mp4 -s 1280x720 -f mp4 pipe:1');
$arg->setStdout(fopen('output.bin','w'));
$ffmpeg = new ProcessExecutor( $arg );
$ffmpeg->start();// not blocked
sh
// ffprobeを起動するだけでもめんどくさい。
//
$args = $this->buildCmd( $path, $opts );
if ( !is_readable($path)){
  throw new \RuntimeException("path is not readable ( {$path} ) ");
}
$p = new ProcessExecutor( $args );
$out_buff='';
$p->onStdout(function($line)use(&$out_buff){ $out_buff.=$line.PHP_EOL;}, PHP_EOL );
$p->start();
return [1 => $out_buff, 2 => $p->getErrout()];