1

I'm trying to make a progress bar to watch a long PHP function (+/- 5mint). This long PHP function read a CSV file and inserting each row in a SQL database.

Here, I'm testing with a sample PHP long function (+/- 10s). For each loop passed, a value is incremented in db 'app_loader'.

This function is started asynchronly with ajax call (POST).

I have make a PHP function to "watch" this sample long PHP function. It query the database 'app_loader' table to get fields 'loader_state' and 'loader_total'. This function return (echo) json array with the 'load' percentage and the 'ended' state (true or false).

This function is started asynchronly with ajax call (GET) and is repeated each 500ms.

My problem is : The watcher ajax call work but return value only at the end of the long task ajax call. So thats little bit boring to maked a loader bar with nothing returned when the long ajax call is started :(

Attended result of ajax watcher (each 500ms) : 1, 2, [...], 99, 100%

Thanks a lot in advance!


The PHP long task sample function:

function read_csv($name, $path)
{
    $row = 1;
    while($row < 10)
    {
        // Process (read CSV file and do something) 

        // Set progression in db
        $query = "UPDATE app_loader SET loader_state = :loader_state, loader_total = :loader_total WHERE loader_name = :loader_name";
        $query = self::$db->prepare($query);
        $query->bindValue(':loader_name', 'csv_read', \PDO::PARAM_STR);
        $query->bindValue(':loader_state', $row, \PDO::PARAM_INT);
        $query->bindValue(':loader_total', 9, \PDO::PARAM_INT);
        $query->execute();
        $query = null;

        sleep(1);

        $row++;
    }

    echo json_encode(array('task_ended' => true));
}

The PHP watcher function:

function read_csv_progress()
{
    $query = "SELECT loader_state, loader_total FROM app_loader WHERE loader_name = :loader_name";
    $query = self::$db->prepare($query);
    $query->bindValue(':loader_name', 'csv_read', \PDO::PARAM_STR);
    $query->execute();
    $row = $query->fetch(\PDO::FETCH_OBJ);
    $query = null;

    if($row->loader_state == $row->loader_total)
    {
        echo json_encode(array('load' => self::progress_percent(($row->loader_total), $row->loader_state), 'ended' => true));
    }else{
        echo json_encode(array('load' => self::progress_percent(($row->loader_total), $row->loader_state), 'ended' => false));
    }
 }

The ajax long task call function:

function processLongPHPTask(filename, filepath) {
    // Launch watcher
    checkProgress();

    $.ajax({
        type: 'POST',
        url: '/api/map/read/csv/global',
        data: 'name=' + filename + '&path=' + filepath,
        dataType: 'json',
        beforeSend: function (xhr) {
            xhr.setRequestHeader(
                'Authorization',
                'Bearer ' + JWT
            );
        },
        success: function (data) {
            if (data.task_ended) {
                console.log('task ended');
            }
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.log({
                type: 'error',
                trace: 'processLongPHPTask',
                message: {'status': xhr.status, 'error': thrownError}
            });
        }
    });
}

The ajax watcher call function:

function checkProgress() {

    // Where I call read_csv_progress() from PHP

    $.ajax({
        type: 'GET',
        url: '/api/map/read/csv/global',
        dataType: 'json',
        beforeSend: function (xhr) {
            xhr.setRequestHeader(
                'Authorization',
                'Bearer ' + JWT
            );
        },
        success: function (data) {
            if (data.ended) {
                console.log('data process ended');
            } else {
                console.log('data progress : ' + data.load);

                // Restart the watcher each 500 ms
                setTimeout( checkProgress, 500 );
            }
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.log({
                type: 'error',
                trace: 'checkProgress',
                message: {'status': xhr.status, 'error': thrownError}
            });
        }
    });
}
  • Is your PHP code using Sessions? (Not necessarily specifically inside that read_csv function, but “around” it.) – CBroe Aug 17 '17 at 09:25
  • 1
    Please have a look at this great answer: https://stackoverflow.com/a/18964123/1532004 – Zim84 Aug 17 '17 at 09:25
  • Where is you call to read_csv_progress? I do not see it being called, so something is missing. – RWC Aug 17 '17 at 10:06
  • @RWC "read_csv_progress" is called on checkProgress() ajax function :) – BloodMotion Aug 17 '17 at 12:34
  • @Zim84 I use just a "session_start()" in header, but I can remove it because my auth system is based on cookie ... You think start a session prevent the well run of this two simultaneous ajax queries (processLongPHPTask() & checkProgress()) ? – BloodMotion Aug 17 '17 at 12:46
  • @BloodMotion: Where? I don't see it in your code. – RWC Aug 18 '17 at 10:55
  • @RWC Here, router make difference between a GET or POST for the same API endpoint -> url: '/api/map/read/csv/global' :) – BloodMotion Aug 18 '17 at 16:51

0 Answers0