0

PHPスクリプトからPythonスクリプトを呼び出し、結果をPHPに返す必要があります。関数で遊んでいproc_openます。しかし、うまくいきません。なぜなのかご存知ですか?これは PHP スクリプトです。

$msg = "this is a new message \n bla ble !@#$%^&*%(*))(_+=-";
$descriptorspec = array(
0 => array("pipe","r"),
1 => array("pipe","w"),
2 => array("file","./error.log","a")
) ;
$cwd = './' ;
$command = 'python ./upper.py ';
$proc = proc_open($command, $descriptorspec, $pipes, $cwd) ;
if ( is_resource( $proc ) ) {
    fwrite( $pipes[0], $msg );
    fclose( $pipes[0] );
    fclose( $pipes[1] );
    proc_close($proc);
    echo "proc is closed\n";
}
else {
    echo 'proc is not a resource';
}

Python `upper.py' スクリプト

import sys
print 'in python script'

data = sys.stdin.readlines()
print data

出力は次のとおりです。

in php script
proc is closed

error.log にエラーがあります:

close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
4

1 に答える 1

0

答えがまだ誰にとっても重要な場合に備えて:

エラーが発生する$pipes[1]のは、Python スクリプトがそれを書き込む機会を得る前に、そして実行を開始する前であっても、すぐに閉じているためです。私のシステム(Mac)のエラーは次のとおりです。

close failed: [Errno 32] Broken pipe

(ちょっとした好奇心から、あなたが実行しているシステムの種類で、その奇妙なメッセージが表示されますか?)

とにかく、パイプを閉じる前に読み取ることでエラーを回避できます。

stream_get_contents($pipes[1]);

これにより、パイプがまだ開いている間に、Python スクリプトが (少なくとも 1 回は) パイプを書き込む機会を得ることが保証されます。

あなたが Python スクリプトの作成者である場合、PHP スクリプトが書き込み内容を読み取らない限り、Python スクリプトに出力を書き込む意味はありません。

一方、python スクリプトがあなたが作成したものではなく、気にしない出力を書き込む場合は、 orでいくつかのゲームをプレイすることで、出力を読み取らないようにすることができるかもしれませんが、私はそうしません。それに賭けます。より安全なオプションは、おそらく出力ストリームを読み取って床に投げることです。pcntl_wait()pcntl_waitpid()

(出力を気にするかどうかに関係なく、興味深い質問が発生します。出力の最後がどのようになるかをアプリオリproc_close()に知らず、パイプを閉じて を呼び出すまでサブプロセスが終了しない場合、サブプロセスが呼び出した処理を実際に終了したことをどのように知ることができますか?)

別のオプション (これまでのところ私がテストしていません) は、気にしない出力ストリームを次のような記述子に接続することです。

array("file", "/dev/null", "w")

または、システム上にあるものと同等のもの/dev/null

于 2012-12-23T03:22:17.617 に答える