Frage

Ich habe eine Variable, die eine lange Zeichenfolge enthält. (Insbesondere enthält es einige Kilobyte Javascript-Code)

Ich möchte diesen String durch einen externen Befehl, in diesem Fall einen Javascript-Kompressor, übergeben und die Ausgabe des externen Befehls (des komprimierten Javascript) in PHP erfassen und einer Variablen zuweisen.

Ich bin mir bewusst, dass es Klassen zum Komprimieren von Javascript in PHP gibt, aber dies ist nur ein Beispiel für ein allgemeines Problem.

ursprünglich haben wir verwendet:

$newvar = passthru("echo $oldvar | compressor");

Dies funktioniert für kleine Zeichenfolgen, ist jedoch unsicher. (Wenn oldvar Zeichen mit besonderer Bedeutung für die Shell enthält, kann alles passieren)

Das Escaping mit Escapeshellarg behebt das Problem, aber die Lösung wird aufgrund längerer Zeichenfolgen aufgrund der Einschränkungen des Betriebssystems für die maximal zulässige Argumentlänge unterbrochen.

Ich habe versucht, popen("command" "w") zu verwenden und in den Befehl zu schreiben - dies funktioniert, aber die Ausgabe des Befehls verschwindet stillschweigend in der Leere.

Konzeptionell möchte ich nur das Äquivalent von: tun

$newvar = external_command($oldvar);

War es hilfreich?

Lösung

Mit der proc_open -Funktion können Sie Handles für beide stdout erhaltenund stdin des Prozesses und schreiben Sie daher Ihre Daten darauf und lesen Sie das Ergebnis.

Andere Tipps

Mit dem Vorschlag von Rumpels konnte ich die folgende Lösung entwickeln, die anscheinend gut funktioniert.Veröffentlichen Sie es hier zum Nutzen aller anderen, die an der Frage interessiert sind.

public static function extFilter($command, $content){
    $fds = array(
        0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
        1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
        2 => array("pipe", "w")   // stderr is a pipe that the child will write to
    );
    $process = proc_open($command, $fds, $pipes, NULL, NULL);
    if (is_resource($process)) {
        fwrite($pipes[0], $content);
        fclose($pipes[0]);
        $stdout =  stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        $return_value = proc_close($process);
        // Do whatever you want to do with $stderr and the commands exit-code.
    } else {
        // Do whatever you want to do if the command fails to start
    }
    return $stdout;
}

Es kann zu Deadlock-Problemen kommen: Wenn die von Ihnen gesendeten Daten größer sind als die kombinierten Pipes-Größen, wird der externe Befehl blockiert und wartet darauf, dass jemand von seinem Standard liest, während PHP blockiert ist und auf Standard wartetgelesen werden, um Platz für mehr Eingaben zu schaffen.

Möglicherweise kümmert sich PHP irgendwie um dieses Problem, aber es lohnt sich zu testen, ob Sie mehr Daten senden (oder empfangen) möchten, als in die Pipes passen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top