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