0

I'm trying to get some data from Ajax request when already PHP running a long script ;

but when the Ajax has been answered that script in PHP is completed, and I need to get Ajax response during running other scripts .

JS

setInterval(function(){
    $.post( 'progress.php','',
    function(data){
        $('.-info-').html(data);
    }); 
},100);

progress.php

session_start();
echo $_SESSION['progress'].'%';

running.php

session_start();
$i=0;
while($i<99){
    $i++;
    $_SESSION['progress'] = $i;
    //sleep(1);
    //flush();
}

Is there any way to response when "while" is running?

talkhabi
  • 2,669
  • 3
  • 20
  • 29
  • wow, wow, see update for my answer – Vasiliy vvscode Vanchuk Oct 20 '14 at 15:48
  • Writes about `$_SESSION` to disk don't happen till the end of the process. The Session file is anyways locked to the *serving process*, which means the **progress.php** process will hang till **running.php** finishes. You'll have to write the progress to your own file and read from there in **progress.php**. – András Gyömrey Oct 20 '14 at 15:49

4 Answers4

1

use flush() to send output to browser and onreadystatechange to get response at client side

$i=0;
while($i<99){
    $i++;
    echo $i; 
    flush();
    sleep(1);
}

an onreadystatechange will be call on every portion of wata from your script ( http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp )

you should check state 3 - State 3 LOADING Downloading; responseText holds partial data. so you easily can use it - you can check it here developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

Vasiliy vvscode Vanchuk
  • 7,007
  • 2
  • 21
  • 44
  • did you notice which script is he calling from jquery and which one is locking the session file? – András Gyömrey Oct 20 '14 at 15:54
  • `onreadystatechange` is fired when the *state* of the connection changes - *not* when the content of the page changes. – dognose Oct 20 '14 at 15:57
  • if he'll be print out current status - there is no need to use session - so he can just close session and work with data independently – Vasiliy vvscode Vanchuk Oct 20 '14 at 15:57
  • and state changed on every portion of data wile page loading – Vasiliy vvscode Vanchuk Oct 20 '14 at 15:57
  • @VasilVanchuk There is *no* content Available, until you hit readystate 4 and status 200. And then you would know its `100%` without even reading the content. – dognose Oct 20 '14 at 15:59
  • you should not wait readystate 4 and status 200 - this is markers that page already loaded. But you cat track state 3 ( http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp ) – Vasiliy vvscode Vanchuk Oct 20 '14 at 16:01
  • State 3 LOADING Downloading; responseText holds partial data. so you easily can use it - you can check it here https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest – Vasiliy vvscode Vanchuk Oct 20 '14 at 16:03
  • 1
    well, you are somewhat right. but this will fail for many browsers... IE does not support it at all: `Remarks You cannot call the responseText property to obtain partial results (readyState = 3). Doing so will return an error, because the response is not fully received. You must wait until all data has been received. ` http://msdn.microsoft.com/en-us/library/ie/ms534361(v=vs.85).aspx – dognose Oct 20 '14 at 16:45
  • yep, it's true. But we can just count every state 3 ( as flag that server side send some data ). But as i see - topic starter already got answer. So we can finish discussion – Vasiliy vvscode Vanchuk Oct 20 '14 at 16:48
1

PHP doesn't dump out a copy of the saved session data every time you update $_SESSION. The session file is actually LOCKED by PHP when any particular process is using it.

You'd need to do:

while($i<99){
    session_start();  // start session
    $i++;
    $_SESSION['progress'] = $i;

    session_write_close();  // save session data, release session file lock

    sleep(...);
}

In other words, your code would never work, as your running script would keep the session open/locked, preventing progress from ever accessing it.

Marc B
  • 356,200
  • 43
  • 426
  • 500
1

Edit: Marc B is right. The session will be locked and not updated as required. So you need to store the progress in an system you can access asynchronously from multiple connections - maybe the database?

running.php:

session_start();
$i=0;
while($i<99){
    $i++;
    // Store progress in Database
}

progress.php:

 session_start();
 //read progress from Database
dognose
  • 20,360
  • 9
  • 61
  • 107
  • I tested all answers , so I got that storing into Database is easy and better .tanQ – talkhabi Oct 20 '14 at 18:51
  • I have using progress for copying ,by saving progress in Database and read it by Ajax ... that works fine **for small files**. but when I chose a file (about more than 100MB) to copy , after a few seconds the all `Ajax`s not working .can you help please ? sorry for my bad english – talkhabi Oct 21 '14 at 18:08
0

You can use a global var but the better in mind is make a static or singleton class

class counter {
  private $_progress=0;

  public static function doProgress() {
    $i=0;
    while($i<99){
    $i++;
    $this->_progress = $i;
    }
  }

  public static function getProgress() {
    return $this->_progress;
  }

so in progress.php do

 echo Counter::getProgress()

and in you javascript you must use setinterval() function in my mermory to call at intervaled time the process.php script

Shadar
  • 22
  • 4