简体   繁体   中英

call python script from PHP script

I need to call python script from PHP script and return result back to PHP. I playing with proc_open function. But it does not work. Do you know why? This is PHP script:

$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' script

import sys
print 'in python script'

data = sys.stdin.readlines()
print data

Output is :

in php script
proc is closed

I have error in error.log:

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

Just in case the answer still matters to anyone:

The error occurs because you're closing $pipes[1] immediately, before the python script has a chance to write it, and quite likely even before it has even started running. The error on my system (a Mac) is:

close failed: [Errno 32] Broken pipe

(Just out of curiosity, what type of system are you running on that's giving you that strange message?)

Anyway, you can avoid the error by reading the pipe before closing it, eg,

stream_get_contents($pipes[1]);

which guarantees that the python script will get a chance to write the pipe (at least once) while the pipe is still open.

If you are the author of the python script, there's not much point in having it write output unless your PHP script is going to read what it writes.

On the other hand, if the python script isn't of your making, and it writes output that you don't care about, you might be able to avoid reading the output by playing some games with pcntl_wait() or pcntl_waitpid() -- though I wouldn't bet on it. A safer option is probably to just read the output streams and throw them on the floor.

(Kind of raises an interesting question, whether or not you care about the output: if you don't know a priori what the end of the output will look like, and the subprocess won't exit until you close the pipes and call proc_close() , how will you know when the subprocess has actually finished doing what you called it to do?)

Another option (untested by me so far) might be to connect any output streams you don't care about to a descriptor like:

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

or whatever the equivalent of /dev/null is on your system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM