Script does not continue after command line

I have a problem with a command line script. The PHP script will never continue.

We tried to call the command line directly through putty, and it gives a lot of errors, but returns / ends instantly. Why doesn't it go back to PHP?

It works fine with other pdf files, but not with this

Pdf

http://docdro.id/b0M5vfw

the code

$Cmd = new Command; if($err = $Cmd->exec('/var/bin/poppler-0.51.0/utils/pdfimages -list /var/test.pdf')){ echo "ERR: $err\n"; } echo "continue\n"; 

the class

 class Command { private $descriptorspec; private $output = ''; private $process; private $pipes = []; public function __construct(){ $this->descriptorspec = [ 0 => ['pipe', 'r'], // stdin 1 => ['pipe', 'w'], // stdout 2 => ['pipe', 'w'] // stderr ]; } public function output(): string{ return $this->output; } public function close(){ foreach($this->pipes as $pipe){ if(is_resource($pipe)){ fclose($pipe); } } proc_close($this->process); } public function exec(string $syntax){ $this->process = proc_open($syntax, $this->descriptorspec, $this->pipes); fclose($this->pipes[0]); $this->output = stream_get_contents($this->pipes[1]); $stderr = stream_get_contents($this->pipes[2]); $this->close(); return $stderr; } } 

Mistake

 # /var/bin/poppler-0.51.0/utils/pdfimages -list /var/test.pdf page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio -------------------------------------------------------------------------------------------- 1 0 image 2154 303 rgb 3 8 jpeg yes [inline] 289 292 - - Syntax Error (50560): Illegal character '>' Syntax Error (50560): Unknown operator '<10><07><82>;w<ad><a2><b4>2r<1f><10><07><8f>~j<c4>Hq<cf>Z<86>' Syntax Error (50568): Unknown operator '<0f><b5>X<8f><ae><d0>:<d7>DU<91><cb>'v' Syntax Error (50568): Illegal character ')' ........ Syntax Error (66698): Illegal character <04> in hex string Syntax Error (66699): Illegal character <ff> in hex string Syntax Error (66699): Illegal character <c1> in hex string Syntax Error (66705): Unknown operator '<9b>' Syntax Error (66714): Illegal character ')' Syntax Error (66714): Unknown operator '<bc>q<ff>' Syntax Error (66720): Unknown operator '<05>6<f8><c2><fa><d7><c3>?<f8>' Syntax Error (66741): Unknown operator '<df><ec><99><e1>-' Syntax Error (66743): Unknown operator ']' Syntax Error (66762): Unknown operator '<cc>' Syntax Error: Unterminated string Syntax Error: End of file inside array Syntax Error: End of file inside array Syntax Error: Leftover args in content stream 
+8
command-line php pdf poppler
source share
3 answers

PDF is problematic - @dwarring already avoided this in the comments (quoted here to thank the commentator)

@dwarring said β€œjust fast,” I am sure that this PDF file is dying because the content stream contains an embedded image launched and β€œBI”, followed by random data and ending with β€œEI”. When Adobe engineers developed these operators, the problem is that situations arise where binary data randomly contains an "EI" and makes PDF impossible. Some tools can handle this better, but ideally, the manufacturer of this image should avoid using inline images. "

However, from a PHP point of view, a try / catch block is used instead of an if statement, and you must maintain control of the script.

 $Cmd = new Command; try { $err = $Cmd->exec('/var/bin/poppler-0.51.0/utils/pdfimages - list/var/test.pdf')){ } catch (Exception $e) { var_log($e); } echo "continue\n"; 
+7
source share

You can use stream_select in combination with feof to check which of the two read streams has data available, such as the following code.

I tested it (using PHP 7) and it does not block here (as amended).

  public function exec(string $syntax){ $this->process = proc_open($syntax, $this->descriptorspec, $this->pipes); fclose($this->pipes[0]); $stderr = ""; $num_changed_streams = NULL; while (!feof($this->pipes[1]) || !feof($this->pipes[2])) { $read = [$this->pipes[1], $this->pipes[2]]; $write = NULL; $err = NULL; $num_changed_streams = stream_select($read, $write, $err, 3); if ($num_changed_streams === false) { $this->close(); return $stderr; } else { if (isset($read[0])) { $this->output .= stream_get_contents($read[0]); echo "output: {$this->output} "; } if (isset($read[1])) { $stderr .= stream_get_contents($read[1]); echo "stderr: {$stderr}"; } } } $this->close(); return $stderr; } 

The stream_select and feof functions stream_select necessary because of the following (quoted from http://php.net/manual/en/function.stream-select.php ):

The stream specified in the read array will be scanned to see if the characters become readable (more precisely, to see if reading will be blocked - in particular, the stream resource is also ready for the end of the file, in this case fread () will return a string zero length).

+1
source share

The problem is that this program /var/bin/poppler-0.51.0/utils/pdfimages does not write anything to stdout , and your code hangs on $this->output = stream_get_contents($this->pipes[1]); , so your class is not suitable for this program. For programs that do not write anything to stdout , you should not read from $this->pipes[1] . You should have another class that is used for this type of application:

 class CommandWithNoOutput { private $descriptorspec; private $process; private $pipes = []; private $output = ''; public function __construct(){ $this->descriptorspec = [ 0 => ['pipe', 'r'], // stdin 1 => ['pipe', 'w'], // stdout 2 => ['pipe', 'w'] // stderr ]; } public function output(): string{ return (string)$this->output; } public function close(){ foreach($this->pipes as $pipe){ if(is_resource($pipe)){ fclose($pipe); } } proc_close($this->process); } public function exec($syntax){ $this->process = proc_open($syntax, $this->descriptorspec, $this->pipes); fclose($this->pipes[0]); $stderr = stream_get_contents($this->pipes[2]); $this->close(); $this->output = ob_get_clean(); return $stderr; } } $Cmd = new CommandWithNoOutput; if($err = $Cmd->exec('/usr/bin/pdfimages -list test.pdf')){ echo "ERR: $err\n"; } echo "continue\n"; 

This code outputs this:

 ERR: Syntax Error (50560): Illegal character '>' Syntax Error (50560): Unknown operator '<10><07><82>;w<ad><a2><b4>2r<1f><10><07><8f>~j<c4>Hq<cf>Z<86>' Syntax Error (50568): Unknown operator '<0f><b5>X<8f><ae><d0>:<d7>DU<91><cb>'v' Syntax Error (50568): Illegal character ')' Syntax Error (50570): Unknown operator '<15><c7>=j<c4>X<f4><e8>' .....a lot of errors..... Syntax Error (66762): Unknown operator '<cc>' Syntax Error: Unterminated string Syntax Error: End of file inside array Syntax Error: End of file inside array Syntax Error: Leftover args in content stream continue Process finished with exit code 0 

UPDATE: Another solution is to call stream_set_blocking($this->pipes[1], 0); immediately after calling proc_open , so the code will not wait for the exit.

0
source share

All Articles