gpt4 book ai didi

php - 提供从 Python 脚本到 PHP 的反馈

转载 作者:太空宇宙 更新时间:2023-11-04 09:45:28 27 4
gpt4 key购买 nike

假设一个执行大量操作的python脚本,并在运行时向用户输出进度报告:

$ script.py
Doing 1 of 100 operations...
Operation 1 succeeded with output "023948"
Doing 2 of 100 operations...
Operation 2 succeeded with output "893232"
Doing 3 of 100 operations...
Operation 3 succeeded with output "580217"
Doing 4 of 100 operations...
Operation 4 succeeded with output "228906"

每行输出在上一行之后显示大约 2-3 秒,因此整个脚本运行可能需要 300 秒以上。我想从 PHP 生成的网页运行此脚本,并在运行时向用户显示输出。我知道我可以从 AJAX 轮询 PHP 脚本并获取最新消息以更新到屏幕,但是如何在运行时从 Python 脚本获取实际输出exec()shell_exec() 等函数仅在脚本运行完成后返回输出

在最坏的情况下,我可以修改 Python 脚本以输出到一个文件,并让一个 AJAX 脚本连续 ping 一个 PHP 脚本,该脚本将读取文件并将其与上次读取的文件进行比较(也存储在文件系统中) .但出于各种原因,我宁愿不修改 Python 脚本,而且我并不特别喜欢在文件系统上维护两个额外文件的想法。

最佳答案

使用无缓冲的标准输出,在守护进程打开时将参数 -u 传递给 python 脚本(类似于 python -u(您的 python 脚本))

并且,在 PHP 中,使用诸如 proc_open 之类的东西来实时读取 Python 脚本打印的内容。

编辑

如评论中所述,我可以建议如下:

python :

import sys, atexit
sys.stdout = open(sys.argv.pop(), "w+") #Replaces stdout with a file returned from sys.argv (command line arguments)
def saveClose():
sys.stdout.write("--%s--"%sys.stdout.name) #Just to indicate if the script closed
atexit.register(saveClose) #Register with atexit to execute the function at...exit

PHP: (命名为 daemon.php)

<?php
function execInBackground($cmd) { // Put the program in background in Windows and *nix
if (substr(php_uname(), 0, 7) == "Windows"){ // Detect if Windows
pclose(popen("start /B ". $cmd, "r")); // Use start /B (windows only) to open a background program in Windows
}
else {
exec($cmd . " > /dev/null &"); // Open program as a daemon using & in *nix.
}
}
if(isset($_GET["verify_id"])){ // We have ID?
$content = file_get_contents($_GET["verify_id"]); // If yes, just load the file here (this is a security problem, but you can fix easily)
echo $content; // Simply echoes the content of the file
}
else if(isset($_GET["daemon"])){
$id = md5(uniqid(rand(), true)); // Create a unique hash
execInBackground($_GET["daemon"]." ".$id); // Execute in the background passing the hash as a argument
echo $id; // Echoes the hash
}
?>

Javascript:(命名为 daemon.js 并使用 jQuery)

var cmds = {}
function receiveResult(cmd, id, callback){ // This function effectively receives the result from the execution of the program.
var reg = new RegExp("--"+id+"--$");
cmds_interval[id] = setInterval(function(){
$.ajax({
url:"daemon.php",
dataType: "text",
data: {"verify_id":id},
success: function(msg){
if(reg.test(msg)){ // Is the script closed?
msg = msg.replace(reg, ""); // If yes, removes it from the end of the string
clearInterval(cmds_interval[id]); // And clear the interval
}
callback(msg, id, cmd); // Callback with the message from the stdout
}
});
}, 1000); // refreshes with a interval of 1 second
return cmds_interval[id];
}

function exec(cmd, callback){
$.ajax({
url:"daemon.php",
dataType: "text",
data: {"daemon":cmd},
success: function(id){
receiveResult(cmd, id, callback);
}
});
}

使用示例:

在 HTML 中:

<pre id="console"></pre>
<script language="javascript" type="text/javascript" src="path/to/jquery.js"></script>
<script language="javascript" type="text/javascript" src="path/to/daemon.js"></script>
<script language="javascript" type="text/javascript" src="path/to/demo.js"></script>

在 demo.js 中:(Javascript,也使用 jQuery):

exec("python script.py", function(msg){ 
$("#console").html(msg);
});

这应该有效。如果它不起作用,请等待明天,因为我现在正在退出。祝你好运。

PS:如果代码不起作用,您可以将代码视为您想要的算法示例。

PS 2:execInBackground 函数来自这里:http://www.php.net/manual/en/function.exec.php#86329

关于php - 提供从 Python 脚本到 PHP 的反馈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16716837/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com