2017-02-26 19 views
8

mam problem ze skryptu z linii poleceń .. Skrypt PHP nigdy kontynuować ..skrypt nie kontynuować po linii poleceń

próbowali wywołać bezpośrednio z linii poleceń za pomocą szpachli i wyprowadza dużo błędów ale zwraca/wykonuje natychmiast. Dlaczego nie powraca do PHP?

Współpracuje z innymi plikami PDF, ale nie ten

pdf

http://docdro.id/b0M5vfw

kod

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

klasa

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

błąd

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

Czy Twoje polecenie wymaga podania danych od użytkownika (ciebie)? –

+0

@AdarshSojitra no it does – clarkk

+1

szybko, jestem prawie pewien, że ten plik PDF umiera, ponieważ strumień treści zawiera obraz wbudowany rozpoczęty przez i "BI", po którym następują losowe dane i zakończony przez "EI". Inżynierowie firmy Adobe pracowali poza sezonem, kiedy projektowali tych operatorów. Problem polegał na tym, że sytuacje, w których dane binarne zawierają losowo "EI", powodują, że plik PDF staje się niemożliwy do odczytania. Niektóre narzędzia mogą sobie z tym poradzić lepiej, ale najlepiej, aby producent tego obrazu unikał stosowania obrazów śródliniowych. – dwarring

Odpowiedz

7

Plik PDF jest problematyczne - @dwarring już wymykał się do tego w komentarzach (cytowane tu do podpisywania jego autora)

@dwarring powiedział „tak szybko, jestem pewien, że ten plik PDF umiera, ponieważ strumień treści zawiera obraz wbudowany rozpoczęty przez i "BI", po którym następują losowe dane i zakończony przez "EI". Inżynierowie firmy Adobe pracowali poza sezonem, kiedy projektowali tych operatorów. Problem polegał na tym, że sytuacje, w których dane binarne zawierają losowo "EI", powodują, że plik PDF staje się niemożliwy do odczytania. Niektóre narzędzia mogą sobie z tym poradzić lepiej, ale najlepiej, aby producent tego obrazu unikał używania obrazów wbudowanych. "

Zamiast tego po stronie PHP zamiast instrukcji if użyj bloku try/catch i należy zachować kontrolę nad scenariuszem.

$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

można użyć stream_select w połączeniu z feof aby sprawdzić, które z nich mają czytać strumienie danych są dostępne, jak na poniższym kodzie.

Przetestowałem go (przy użyciu PHP 7) i nie blokuje się tutaj (z wprowadzonymi modyfikacjami).

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

W stream_select i feof funkcje są potrzebne z uwagi na następujące (cyt http://php.net/manual/en/function.stream-select.php)

Strumienie wymienione w tablicy odczytu będzie oglądany, aby sprawdzić, czy postacie stają się dostępne do odczytu (więcej dokładnie, aby zobaczyć, czy odczyt nie będzie blokował - w szczególności, zasób strumienia jest również gotowy na końcu pliku, w którym to przypadku fread() zwróci ciąg o zerowej długości).

0

Problemem jest to, że ten program /var/bin/poppler-0.51.0/utils/pdfimages nie pisze nic do stdout i kod wisi na $this->output = stream_get_contents($this->pipes[1]); stąd klasa nie jest dobre dla tego programu. W przypadku programów, które nie zapisują niczego do stdout, nie wolno czytać z poziomu $this->pipes[1].Powinieneś mieć inną klasę, która jest używana dla tego typu aplikacji:

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

Ten kod wysyła ten:

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: Innym rozwiązaniem jest wywołanie stream_set_blocking($this->pipes[1], 0); natychmiast po wywołaniu proc_open tak kod nie będzie czekać na żadne wyjście.

Powiązane problemy