Прогоресс бар выполнение задачи ajax+php

249
03 марта 2018, 21:49

есть такая задача: необходимо сделать прогресс бар для выполнения функции в php. есть такой цикл php

 function new()
{
    $url = " ";
    $html = curl_get($url);
    $dom = str_get_html($html);
    for ($i = 0; $i < 14; $i++) {
        $aux = $dom->find('h3.media-heading a', $i);                                // ищем название статьи
        $data['name'][] = $aux->plaintext;                                          // записываем название статьи
        $data['links'][] = " " . $aux->href;                                // записывавем ссылку на статью
        $aux = $dom->find('div.article-info time', $i);                             // находим дату
        $str1 = $aux->plaintext;                                                    // обрабатываем
        $str1 = str_replace(' / ', ' ', $str1);                                     //          дату
        $data['date'][] = date("Y-m-d H:i:s", strtotime($str1));                    // записываем дату
        $aux = $dom->find('span.icon-comments', $i);                                // находим количество комментариев
        $data['num_comm'][] = str_replace('"', '', $aux->plaintext);                // записываем коичество комментариев
        $aux = $dom->find('span.icon-views', $i);                                   // находим количество просмотров
        $data['num_views'][] = str_replace('"', '', $aux->plaintext);               // записываем коичество просмотров

    }
    for ($i = 0; $i < count($data['links']); $i++) {
        $html = curl_get($data['links'][$i]);                                       // переходим по
        $dom = str_get_html($html);                                                 //      сылкам на
        $aux = $dom->find('div.pull-left a', 0);                                    //          статей и
        $data['article'][] = $aux->plaintext;                                       //      засисываем раздел
        $aux = $dom->find('div.field-items', 0);                                    // выбираем содржание статьи и
        $data['content'][] = str_replace('&nbsp;', ' ', $aux->plaintext);           //      записываем
    }

при нажатии на кнопку должно появляться модальное окно, в котором написано : сбор данных начался,а по завершении должно появляться выполнено. Может кто подкинет идеи по реализации ajax. Спасибо.

Answer 1

Через AJAX не совсем правильно: тут инициатором должен быть сервер, а не браузер. Для этого лучше использовать веб-сокеты: не нужно постоянно дергать сервер, и все оперативно. Веб-сокеты на ура делаются на NodeJS, на PHP все очень печально.

На AJAX можно сделать так:

  • в data пишем уникальный токен и запускаем действие longaction.php
  • на beforeSend вешаем tickProgress = setInterval(progressBar, 1000);
  • в progressBar через AJAX, используя токен, получаем текущее состояние. Для чего делается PHP скрипт (tickprogress.php) "взяли токен, залезли в БД, отправили цифру"
  • взаимодействие между скриптом, который делает работу longaction.php, и tickprogress.php - через любую базу, в том числе мемкеш. Через файл не советую.
  • при достижении 100% делаем clearTimeout(tickProgress)

Пример:

HTML страница index.html:

<!DOCTYPE html>
<html lang="ru-RU">
<head>
  <meta charset="utf-8">
  <script
    src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
  <script type="text/javascript">
    $(document).ready(function(){
      inProgress = false;
      $('.js-submit').on('click', function(){
        // защита от повторного нажатия кнопки
        if(inProgress) return;
        inProgress = true;
        var tickProgress;
        var token = Math.random();
        $.ajax({
          data: {
              token: token
          },
          url: '/longaction.php', // долгая операция
          beforeSend: function() {
              // запускаем получение прогресса
              console.log('beforeSend');
              tickProgress = setInterval(function(){
                  $.ajax({
                    data: {
                      token: token
                    },
                    // скрипт получение прогресса по токену
                    url: '/tickprogress.php',
                    success: function(progressResp) {
                      $('.js-progress').html(progressResp.progress);
                      console.log(progressResp);
                    }
                  });
              }, 1000);
          },
          success: function() {
              // операция завершена
              console.log('success');
          },
          complete: function() {
              // сбрасываем получение прогресса в любом случае - успех, ошибка
              console.log('complete');
              inProgress = false;
              clearTimeout(tickProgress);
          }
        });
      });
    });
  </script>
</head>
<body>
  <button class="js-submit">Run</button>
  <p class="js-progress">--</p>
</body>
</html>

Скрипт долгой операции longaction.php

<?php
// Скрипт долгой операции
$token = (string)$_REQUEST['token'];
$key = 'progress-' . $token;
$fileName = '/tmp/' . $key;
// Вариант с Memcache
// $memcache_obj = memcache_connect('localhost', 11211);
for($i = 1; $i <= 10; $i++) {
  // Вариант с Memcache
  // $memcache_obj->set($key, $i, false, 600);
  file_put_contents($fileName, $i);
  sleep(1);
}
$ret = [
  'token' => $token,
  'success' => 1
];
header("Content-type:application/json");
die(json_encode($ret));

Получение прогресса долгой операции tickprogress.php

<?php
// Получение прогресса долгой операции
$token = (string)$_REQUEST['token'];
$key = 'progress-' . $token;
$fileName = '/tmp/' . $key;
// Вариант с Memcache
// $memcache_obj = memcache_connect('localhost', 11211);
// $progress = $memcache_obj->get($key);
$progress = file_exists($fileName) ? file_get_contents($fileName) : 0;

$ret = [
  'progress' => $progress,
  'token' => $token,
  'success' => 1
];
header("Content-type:application/json");
die(json_encode($ret));
READ ALSO
Ошибка при NPM RUN BUILD

Ошибка при NPM RUN BUILD

Работаю над проектом, где ReactJS-frontdend и Django-backendИспользую модуль coreapi (npm i coreapi) для работы с API на frontend'e

189
не работает расширение mysqli на debian 9

не работает расширение mysqli на debian 9

Настраиваю LAMP на Debian 9, поставил apache2 + php 7( расширение php-myslqnd установил), но при попытке подключится к базе через mysqli_connect апач в логе пишет - PHP Fatal error:...

246
Сравнить 2 массива отметив совпадение

Сравнить 2 массива отметив совпадение

Добрый деньПодскажите, мне нужно вывести один массив в виде checkbox, отметив те флажки, значения которых есть во втором массиве

272
VS Code и PHP 5.6

VS Code и PHP 5.6

Возможно ли нормально настроить VS Code для работы с PHP 56? Сколько ни пытался - ничего не выходит

319