PHP to get long running process progress dynamically

  Pi Ke        2012-06-04 07:29:37       60,147        10          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

在網頁應用程式中,我們經常會向後端系統發出請求,這可能會觸發一個長時間運行的程序,例如搜尋大量數據或長時間運行的資料庫程序。然後前端網頁可能會掛起並等待程序完成。在此過程中,如果我們可以向用戶提供一些關於後端程序進度的信息,則可以改善用戶體驗。不幸的是,在網頁應用程式中,這似乎並不容易,因為網頁腳本語言不支持多線程,而 HTTP 是無狀態的。現在我們可以使用 AJAX 來模擬實時程序。今天我們將使用 PHP+jQuery 來模擬一個程序,以動態獲取長時間運行的程序的進度。

我們需要三個文件:

<?php
    //long_process.php
    for($i=1;$i<=10;$i++){
        session_start();
        $_SESSION["progress"]=$i;
        session_write_close();
        sleep(1);
    }
?>


以上代碼是 long_process.php,它模擬長時間運行的程序,實際上它有一個 for 循環,該循環將從 1 循環到 10,並且在每次循環後將休眠一秒鐘。這裡最重要的事情是我們使用一個會話變量 $_SESSION["progress"] 來存儲進度,也不要忘記在每次循環後使用 session_write_close(),因為會話數據通常在腳本終止後存儲,而無需調用 session_write_close(),但是由於會話數據被鎖定以防止併發寫入,因此任何時候只允許一個腳本操作會話。當將框架集與會話一起使用時,由於這種鎖定,您將體驗到框架一個接一個地加載。您可以通過在對會話變量完成所有更改後立即結束會話來減少加載所有框架所需的時間。

另一個文件是 progress.php

<?php
    //progress.php
    session_start();
    echo $_SESSION["progress"];
?>

它的作用非常簡單,只是將進度回顯給客戶端。此進度變量是在 long_process.php 中更新的會話變量。

最後一個 PHP 文件:

<script type="text/javascript">
    //開始長時間運行的程序
    $.ajax({
        url: 'long_process.php',
        success: function(data) {
        }
    });
    //開始接收進度
    function getProgress(){
        $.ajax({
            url: 'progress.php',
            success: function(data) {
                $("#progress").html(data);
                if(data<10){
                    getProgress();
                }
            }
        });
    }
    getProgress();
</script>
<div id="progress"></div>

以上代碼只包含內部的代碼(我省略了其餘代碼),它實際上是模擬的入口,它使用 AJAX 向服務器發送兩個請求,一個是初始化長時間運行的程序,另一個是輪詢服務器以獲取進度。獲取進度後,它會在頁面上更新進度。

當然,還有其他方法可以存儲進度變量,例如資料庫或 xml 文件等。您可以選擇您喜歡的或您認為最有效的方法。此外,除了純 PHP 代碼之外,您還可以擁有 Flash 或 Java 小程序通過許多網站使用的 TCP 或 UDP 來處理和輪詢長時間運行的程序。

如果您有比這更好的方法,可以與我們分享。

PHP  AJAX  DEMO  PROGRESS  LONG PROCESS 

       

  RELATED


  10 COMMENTS


Yongd [Reply]@ 2014-04-17 09:27:24

Thank you,this's very helpful to me!

Pi Ke [Reply]@ 2014-04-17 09:54:56

It's my pleasure

Alexander Avakov [Reply]@ 2015-02-17 06:03:56

Nice tutorial. Thank you!

alea123 [Reply]@ 2015-05-07 02:22:51

rly nice.. thank you!

samas [Reply]@ 2015-06-23 02:14:36

nice article, care to put up a complete working demo... full source code which can be easily adapted...?

verjas [Reply]@ 2015-08-21 02:51:53

I've just tested it on a project.

Works like a charm! Good job! 

Patrick [Reply]@ 2015-11-25 08:40:26

Very nice!!! Saved me hours!

Maksim Pol [Reply]@ 2016-01-10 02:55:16

It sometimes starts wrong. After page refresh, progress percent stays, but script working in background. If i make refresh again, then will run 2 scripts at one time. 

Anonymous [Reply]@ 2020-07-19 04:04:26

I had this similar issue.

I solved it by;

1. If() statement to prevent the long running script starting when the session variables already exist.

2. Unset() the session variables when the long script is complete and the last Ajax request has been called.

Maksim Pol [Reply]@ 2016-01-10 02:55:55

How it can be fixed? Anyway, thanks for the tutorial. :)



  RANDOM FUN

Consequence of not doing functional test