如何在没有 PHP Pusher 的情况下制作实时进度条

How To Make Realtime Progressbar Without PHP Pusher

我陷入了这个问题,关于在 php 上制作实时进度条(没有 php 推送器)

假设我有 10 行数据,这些数据将被插入到数据库中。

现在如何发送进度条数据,同时也插入到数据库中。

非常感谢您的回答。 谢谢

下面是我的代码示例:

// script.js (client)
// This function executed when user submit form
function store() {
  // Listen Server Side Event
  let event = new EventSource('controller/store')
  
  event.addEventListener('message', response => {
    // Then update progressbar
    updateProgressbar(response.percent)
  })
  
  // Ajax to save data to database
  $.ajax({
    url: baseUrl + 'controller/store',
    type: 'POST',
    dataType: 'JSON',
    data: $('#form').serializeArray(),
    success: function(response) {
      console.log(response)
    }
  })
}


// Controller.php (server)
public function store() {
  header("Content-Type: text/event-stream");
  header("Cache-Control: no-cache");
  header("Connection: keep-alive");
  
  $total_row = count($_POST['customer']);

  for ($i = 0; $i < $total_row; $i++) {
    usleep(100000);
      
    $this->db->insert('customers', $_POST['customer'][$i]);
    
    $percent = ($i + 1) * (100 / $total_row);

    echo "event: message\n";
    echo 'data: {"status": "loading", "percent": "' . $percent . '"}';
    echo "\n\n";

    ob_end_flush();
    flush();

    if (connection_aborted()) break;
  }

  echo "event: message\n";
  echo 'data: {"status": "done", "percent": "' . $percent . '"}';
  echo "\n\n";
}

Web 服务器和浏览器不会按照您想要的方式运行。

HTTP headers 包含内容长度,Web 服务器在将文档发送到客户端之前希望知道该长度。除非您已经确切知道文档 body 的长度,否则服务器将(通常)等到 PHP 脚本退出后再向客户端发送任何信息。

ob_end_flush()flush()不直接向客户端发送信息;将它发送到 Web 服务器,它仍然会缓存它,直到整个文档准备好发送。

并且,客户端 AJAX 请求也将等待,直到整个文档在 运行 success 函数之前被接收。

因此,您需要在服务器上设置一些东西来存储进度,供您调用的另一个脚本使用。

您的服务器端脚本应该发回一个随机令牌,然后 continue processing php after sending http response

然后您的客户端脚本将需要偶尔使用该令牌查询您的服务器,直到长期进程完成或失败。

您可以通过使用 WebSockets 更快地更新客户端,正如 Tuckbros 在评论中提到的那样(我很感谢提到我的服务器),但除非用户知道进程何时在几十秒内结束很重要毫秒,我建议保持正常 Web-PHP 和 AJAX,因为 WebSockets 需要对 CLI-PHP 和 HTTP 的额外细微差别有所了解。