0

I am making a javascript XMLHttpRequest() request to execute some php in the background. Now I know the callback will only receive the first response from php. How can I get output to send back what php is echoing as it is happening to show it on the main page as php is running in the background?

javascript

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {

        var phpResponse = this.responseText
        // i know this will only be the first thing echoed by php
    }
};
xhttp.open("GET", "scan.php?scanRoot=yes", true);
xhttp.send();

php run in the back ground

function rootDirFileSort($scanDir,$getID3){

//Sort stray files in root directory. Put them in a dir named by artist

$printFix = str_repeat(" ", 8157);

$files = array_diff(scandir($scanDir), array('.', '..'));

//Get files in dir. Only get flac and mp3 files
$FilesArray = array_diff(scandir($scanDir), array('.', '..'));
$FilesArray = preg_grep('~\.(flac|mp3)$~', $FilesArray);
$files = array_values($FilesArray);

foreach ($files as $file){

    $file_Basename = basename($file);

    // Get the metadata from file. Returns as an array
    $metaDataArray = $getID3->analyze($scanDir.$file);

    //Check for ID3v1 metadata container
    if (isset($metaDataArray['tags']['id3v1']['artist'][0])){
        $artist = $metaDataArray['tags']['id3v1']['artist'][0];
        $artist = str_replace(array('.',',','?','/','\\','$'), array('','','','','',''), ucwords($artist));
    }else{
        $artist = '';
    }

    //Check for vorbis comment metadata container
    if(isset($metaDataArray['tags']['vorbiscomment']['artist'][0])){
        $artist = $metaDataArray['tags']['vorbiscomment']['artist'][0]; echo $artist;
        $artist = str_replace(array('.',',','?','/','\\','$'), array('','','','','',''), ucwords($artist));
    }else{
        $artist = '';
    }   

    //If the artist meta tag is present move the file
    if(!empty($artist)){

        //Check if diretory exists before making one
        if(!is_dir($scanDir.$artist)){
            //If file DOES NOT exist
            mkdir($scanDir.$artist, 0755, true);
            rename($scanDir.$file, $scanDir.$artist.'\\'.$file);    
            echo $file.'<br>'.$artist.'<br>Moved To: '.$scanDir.$artist.'\\'.$file.'<br><br>'.$printFix;
        }else{
            //If file exists
            rename($scanDir.$file, $scanDir.$artist.'\\'.$file);
            echo $file.'<br>'.$artist.'<br>Moved To: '.$scanDir.$artist.'\\'.$file.'<br><br>'.$printFix;
        }

    }else{

        //Put failures in an array to show which failed when done
        $notProcessed[] = array('musicFile'=>$file_Basename);
    }
}

//Show all the failures if they exist
if(count($notProcessed) >= 1){

    echo '<strong>***** These items failed as they don\'t contain ID3v1, ID3v2 or Vorbis Comment meta container. Manually process directories. *****</strong><br><br>';

    foreach($notProcessed as $value){

        echo '<strong>File:</strong> '.$value['musicFile'].'<br><br>'.$printFix;
    }
}

echo '<br><br>------------------------- Root File Scan Finished! -------------------------'.$printFix;

}

Micha
  • 383
  • 3
  • 14
  • Consider adding an [mcve] - with focus on the _minimal_. As for "streaming", consider [websockets](https://stackoverflow.com/questions/12203443/is-native-php-support-for-web-sockets-available), but I'm not sure that's what is appropriate / going on in your case. – random_user_name Mar 07 '19 at 02:56
  • PHP doesn't stream output, it runs on the server and return the output at once. https://stackoverflow.com/questions/223983/live-video-streaming-with-php –  Mar 07 '19 at 02:56
  • maybe "stream" is not the correct choice of wording. I just need everything php is echoing sent back as it is happening – Micha Mar 07 '19 at 03:00
  • Do you want to catch the output that PHP echoes out individually everytime it run the loop? That's exactly what stream is. –  Mar 07 '19 at 03:10
  • @catcon Yes that is exactly what I need. As it iterates through the loop I need everything its spitting out – Micha Mar 07 '19 at 06:49
  • Well you would have to start with two things: Make your server-side script _flush_ parts of the output as soon as they are available (broader topic, research), and react earlier on the client side, than when the readyState has reached its “final stage”, 4. – 04FS Mar 07 '19 at 08:25
  • An alternative could be, that you fire more requests from the client side, that have the server-side script perform the necessary actions on a couple of files only each time, so that you get the feedback for those smaller “packages” quicker. – 04FS Mar 07 '19 at 08:29

0 Answers0