从PHP脚本调用python脚本

时间:2012-09-10 03:42:29

标签: php python

我需要从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

1 个答案:

答案 0 :(得分:0)

以防万一,答案对任何人都很重要:

发生错误是因为你在python脚本有机会编写它之前立即关闭$pipes[1],很可能甚至在它开始运行之前。我的系统(Mac)上的错误是:

close failed: [Errno 32] Broken pipe

(出于好奇,你正在运行什么类型的系统给你那个奇怪的信息?)

无论如何,您可以通过在关闭之前读取管道来避免错误,例如

stream_get_contents($pipes[1]);

保证python脚本在管道仍然打开时有机会写入管道(至少一次)。

如果你是python脚本的作者,除非你的PHP脚本要读取它写的内容,否则写入输出并没有多大意义。

另一方面,如果python脚本不是你的,并且它写了你不关心的输出,你可能能够通过播放来避免读取输出使用pcntl_wait()pcntl_waitpid()的游戏 - 虽然我不会赌它。更安全的选择可能只是读取输出流并将它们扔到地板上。

(提出了一个有趣的问题,无论你是否关心输出:如果你不知道先验输出的结尾是什么样的,并且子流程赢了' t退出,直到你关闭管道并调用proc_close(),你怎么知道子进程何时实际完成了你所谓的操作?)

另一个选项(到目前为止我未经测试)可能是将您不关心的任何输出流连接到以下描述符:

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

或您系统中等效的/dev/null