【问题标题】:Display progress of running process in modal window在模态窗口中显示运行进程的进度
【发布时间】:2015-09-08 20:56:44
【问题描述】:

我目前正在尝试使网页看起来更现代一些,但在向模式窗口添加一些相对简单的功能时遇到了一些麻烦。

在我的网页上,用户首先上传一个文件,然后在点击提交时,该文件由一个 shell 脚本处理(这可能需要几秒钟到几分钟,具体取决于文件大小)。

为了显示进程状态,我一直在做的是使用 php 执行以下代码:

$cmd = "script.bash -i $input_file";

$PID = shell_exec($cmd . " >> $log 2>&1  & echo $!");

while(is_process_running($PID)){
   echo(" . ");
   ob_flush(); flush();
   sleep(3);
}

除了显示的一些其他信息(未显示)之外,这将简单地打印出一个“。”每隔几秒钟给用户一个进程正在运行的指示。完成后,会出现一个下载链接,以便检索处理后的数据。

我现在想做的是在模式窗口中加载这些信息。创建模态窗口(使用 boostrap 和 javascript)并向其添加下载功能没有问题,但是只有在通过 php 执行的 $cmd 完成后才能执行此操作。我想做的是执行$cmd,加载模态窗口,然后查询进程状态并在模态窗口中显示某种指示器,最后在进程完成时创建下载链接。我相信这需要通过 AJAX 来完成,但我对如何做到这一点有点困惑。这是我更详细的代码:

<?
    if($theaction == "run_script" and !$error_msg){
        $cmd = "script.bash -i $input_file";

        $PID = shell_exec($cmd . " >> $log 2>&1  & echo $!");

        while(is_process_running($PID)){ #ensure the process is compete before loading the html
            echo("");
            ob_flush(); flush();
            sleep(3);
        }

        echo "
            <script type=\"text/javascript\">
                $(function() { $(\"#myModalProcess\").modal('show') })
            </script>


            <div class=\"modal fade\" id=\"myModalProcess\" tabinex=\"-1\" role=\"dialog\" aria-hidden=\"true\">
                <div class=\"modal-dialog\">
                    <div class=\"modal-content\">
                        <div class=\"modal-header\">
                            <h4><b>Process ID: $PID</b></h4>
                            <hr>
                            <p>Other stuff here</p>
                            <a type=\"button\" class=\"btn btn-primary\" href='".$_SERVER['PHP_SELF']."?theaction=download&workDir=$workDir&out_folder=$out_folder'>Download Results</a>
                        </div>
                    </div>
                </div>
            </div>
        ";
    }
?>

【问题讨论】:

  • is_process_running 是什么?
  • 对不起,这只是一个返回进程状态的javascript函数。
  • 不能用php调用js函数

标签: javascript php ajax twitter-bootstrap


【解决方案1】:

我会为你阐明流程,但我不会给你代码,因为它写得太长了,我认为你最好先了解理论来了解你需要开发什么。

所以,第一个错误是在运行 php 脚本后尝试执行 javascript 和 html(模态)代码。

你应该做的是使用ajax,所以你可以通过“ajax”运行你的php脚本(里面有你的shell脚本),并且再次使用ajax你可以在php脚本运行时询问进度。

所有这一切都应该有点简单,我知道,但问题是你在这里混合了复杂的东西:

  1. 您不能离开页面。如果您使用 multipart-form/data 提交表单来上传文件,浏览器会开始上传,发出请求,当 php 脚本完成时,整个页面会重新加载。在那里您失去了对页面的控制权,您只需将控制权传递给浏览器即可。
  2. 您有 2 个需要时间且需要进度状态的进程:文件上传和脚本进程。但是让我们跳过第一个。
  3. 为避免在提交表单时离开页面,您需要通过 ajax 提交。这是一个link 了解如何操作。
  4. 要获得进度,您有两种方法:第一种是使用jQuery ajax progress via xhr,第二种是在 javscript 中“设置一个间隔”,通过 ajax 每隔 {x 时间}(即:每 3 秒)检查一次进度当该过程完成时,清除该间隔以停止检查。您可以通过对路径执行 ajax 请求进行检查,在该路径中您有一个返回进度的脚本(它可以是一个 php 文件 -> 即:www.yourhost.com/your_action/progress.php)。
  5. 脚本运行时,您需要将进度保存在“用户全局上下文”中(即:cookie、带有用户 ID 的文件、一些缓存等),因此当您“检查进度”时(第 4 步) ,您将发出请求并要求任何请求都可以访问用户数据的值。或者只是使用“通过 xhr 的 jQuery ajax 进度”,阅读文档并使其以这种方式工作:)
  6. 您的流程完成后,只需停止显示或询问进度,显示链接或结果,您无需重新加载页面!

希望对您有所帮助,如果您有任何其他具体问题,请询问:)

【讨论】:

  • 谢谢山姆。我在理论方面很弱,所以非常感谢你澄清正在发生的事情以及我需要做什么。如果我遇到任何问题,我会看看我能做些什么并回复你。
  • 当然,我认为您需要将代码在视图(html + js)逻辑和后端(php)逻辑之间分开,并尝试同时拥有这两个功能 -> 1. 运行脚本 2. 获取进度地位。然后,您可以从您的视图逻辑中提交文件并运行 1. 并在 1. 运行时检查 2.。尝试编写您的代码,如果您有任何具体问题,我会帮助您:)
猜你喜欢
  • 2014-06-29
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多