3

長い文字列を含む変数があります。(具体的には、数キロバイトの JavaScript コードが含まれています)

この文字列を外部コマンド (この場合は javascript-compressor) に渡し、外部コマンド (圧縮された JavaScript) の出力を php でキャプチャして、変数に割り当てたいと考えています。

PHP に JavaScript を圧縮するためのクラスがあることは承知していますが、これは一般的な問題の一例にすぎません。

もともと使用していたもの:

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

これは小さな文字列に対して機能しますが、安全ではありません。(oldvar にシェルにとって特別な意味を持つ文字が含まれている場合、何かが起こる可能性があります)

escapeshellarg でエスケープするとそれが修正されますが、最大許容引数長に対する OS の制限により、解決策はより長い文字列に対して壊れます。

コマンドを使用して書き込もうとしpopen("command" "w")ました-これは機能しますが、コマンドからの出力は静かに無効になります。

概念的には、次のことと同等のことをしたいだけです:

$newvar = external_command($oldvar);
4

2 に答える 2

2

proc_open関数を使用すると、プロセスのstdoutとstdinの両方へのハンドルを取得して、データを書き込み、結果を読み取ることができます。

于 2011-09-07T10:11:21.343 に答える
0

rumpels の提案を使用して、うまく機能すると思われる次のソリューションを考案することができました。質問に興味のある他の人の利益のためにここに投稿します。

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

デッドロックの問題が発生する可能性があります: 送信するデータがパイプの合計サイズよりも大きい場合、外部コマンドはブロックされ、誰かがその標準出力から読み取るのを待ちますが、PHP はブロックされ、標準入力が読み取られるのを待ちます。より多くの情報を入力できるようにします。

おそらく PHP がこの問題を何らかの方法で処理しますが、パイプに収まらないほど多くのデータを送信 (または受信) する予定がある場合は、テストする価値があります。

于 2011-09-09T05:24:19.023 に答える