2017-02-26 4 views
8

J'ai un problème avec un script avec une ligne de commande .. Le script PHP ne continue ..ne continue pas après la ligne de commande

ont essayé d'appeler la ligne de commande directement par le mastic et sorties beaucoup d'erreurs mais retourne/se termine instantanément. Pourquoi ne retourne-t-il pas à PHP?

Il fonctionne très bien avec d'autres fichiers PDF, mais pas celui-ci

pdf

http://docdro.id/b0M5vfw

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"; 

classe

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; 
    } 
} 

erreur

# /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 
+0

Votre commande vous demande-t-elle des informations de la part de l'utilisateur (vous)? –

+0

@AdarshSojitra Non, il ne – clarkk

+1

pas rapidement, je suis sûr que ce PDF est en train de mourir parce que le flux de contenu contient une image en ligne commencée par et «BI» suivi de données aléatoires et se termine par «EI». Les ingénieurs d'Adobe avaient une journée creuse quand ils ont conçu ces opérateurs, le problème étant que des situations surviennent où les données binaires contiennent aléatoirement «EI» et rendent le PDF incomparable. Certains outils peuvent gérer cela mieux, mais idéalement le producteur de cette image devrait éviter l'utilisation d'images en ligne. – dwarring

Répondre

7

Le PDF est problématique - @dwarring déjà éludé à ce sujet dans les commentaires (cité ici pour créditer le commentateur)

@dwarring dit « Très rapidement, je suis assez sûr que ce PDF est en train de mourir parce que le flux de contenu contient une image en ligne commencée par et 'BI' suivi de données aléatoires et terminé par 'EI'. Les ingénieurs d'Adobe avaient une journée creuse quand ils ont conçu ces opérateurs, le problème étant que des situations surviennent où les données binaires contiennent aléatoirement «EI» et rendent le PDF incomparable. Certains outils peuvent gérer cela mieux, mais idéalement le producteur de cette image devrait éviter l'utilisation d'images en ligne. »

Du côté PHP des choses, si, au lieu d'une instruction if utiliser un bloc try/catch et vous devez garder le contrôle du 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"; 
1

vous pouvez utiliser stream_select conjointement avec feof pour vérifier lequel des deux flux lire des données étaient disponibles, comme le code suivant.

Je l'ai testé (en utilisant PHP 7) et ne bloque pas ici (avec les modifications apportées).

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; 
    } 

Les fonctions stream_select et feof sont nécessaires en raison de ce qui suit (cité de http://php.net/manual/en/function.stream-select.php):

Les flux qui sont listés dans le tableau de lecture seront surveillés pour vérifier si les caractères sont disponibles en lecture (plus précisément, pour voir si une lecture ne bloquera pas - en particulier, une ressource de flux est également prête en fin de fichier, auquel cas un fread() retournera une chaîne de longueur nulle).

0

Le problème est que ce programme /var/bin/poppler-0.51.0/utils/pdfimages ne pas écrire quoi que ce soit à l'stdout et votre code se bloque à $this->output = stream_get_contents($this->pipes[1]); donc votre classe est pas bon pour ce programme. Pour les programmes qui n'écrivent rien à stdout, vous ne devez pas lire $this->pipes[1].Vous devriez avoir une autre classe qui est utilisé pour ce type particulier d'applications:

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"; 

Ce code sorties ceci:

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 

MISE À JOUR: Une autre solution est d'appeler stream_set_blocking($this->pipes[1], 0); immédiatement après l'appel à proc_open si le code n'attendra aucune sortie.