tags:

views:

303

answers:

2

Okay, im not very good at describing these things, so bear with me..

Im trying to find a way of showing a status/progress bar kind of thing to show the percentage (or whatever) of how much of a text file has been read/parsed by php. I know roughly what I need to do (be it by counting the lines, or filesize and that of the actual text file) but I cant for the life of me work out how to actually implement it. I'm using PHP/AJAX and all I really want is for a single div to be updated every so often (5 seconds or something) to show the status until all is done, then show the output. Easy huh, though how the hell I'm supposed to do it, I dont know. I have found some really useful posts on here with regards to it but nothing that I can quite get to work with what I have.

If anyone can give me some rough tips/ideas I would be stupidly grateful (this is really doing my head in)! Thanks in advance!

+1  A: 

How about...

We have to assume that there is some way to determine the total job (100%) and the point that the php script is at (the % done status), so if it's reading/parsing a text file, you could have the parsing function start by writing the total line count to a db or text file. Then it can also write which line number it's on to that same file every 5 seconds. The js ajax function calls to that text file to get the total and the point it is on. When the php text parser is done, it destroys the status file to prevent it from taking up server space, file name conflicts, etc.


Example:

First, the (jquery) ajax function POSTs to the server:

 $.post("parser.php", { file: "somefile.txt"} );
 //I admit, I'm not sure if this is how a file would be posted with ajax

Next, the php pulls the file and starts the parser function:

    $tmpName  = $_FILES['userfile']['tmp_name'];
    $fileName  = $_FILES['userfile']['name'];

    //Turn the file into an array, so that you can use the array count for status:
    $content = file($tmpName);

    // Get the array count as the total, as it equals the line count:
    $total = count($content);

    //Write the filesize to a unique "total" txt file:
    $total_file = fopen($fileName."-total.txt", 'x');
    fwrite($total_file, $total);
    fclose($total_file);

    //Pass the Array to the parser function:
    parser($content, $fileName);

    //Kill the file when the function is done:
    unlink($fileName);

    function parser ($file_array, $filename) {
           //creates the status file and then closes it, to ensure that it
           //exists for the loop but gets overwritten each time

           $status_file = fopen($filename."-status.txt", 'x');
           fclose($status_file);

           foreach($file_array as $position => $data) {
                  //Do your parsing here //
                   .............
                  //reopen status file and wipe out what is in it already:
                  $status_file = fopen($filename."-status.txt", 'w');
                  fwrite($status_file, $position);
                  fclose($status_file);
             }

       }

So since the status and total file share the hopefully unique name of the uploaded file, the ajax function knows where to look. It can do this:

 total = $.get("somefile-total.txt");

 current = $.get("somefile-status.txt");

 status = current/total;
Anthony
Hey, thanks for the help. I had not thought about doing it that way, and it makes sense, although would writing to a seperate text file not be a bit of a security issue? Shall have a play about with it and see how we go. Thanks
rich
I was trying to imagine some way to have the script that was parsing be able to respond to an ajax request WHILE it was parsing, or have another script check the status, but I'm pretty sure both of those are pretty unlikely. The other option would be to open a "long polling" server push type situation, where the connection between ajax and the script remains open and ever loop in the above example returns the position to the ajax function instead of to the text file.
Anthony
Yeah, its a bit of a nightmare really this... I may stick with just the traditional graphic... hmmThanks for all your help though, its hugely appreciated! May look into the long polling stuff, I did look at it as it seemed relevant.
rich
@Anthony, your general approach is correct and a good starting point, but it could be tweaked some. I have a feeling the first line to send the actual file isn't going to work. Also, If you write the current progress and ttoal bytes to *one* file you avoid the wto separate ajax requests. so just: `status = $.get("somefile-status.txt");` and then split up status on `/`
Josh
@Josh, i was pretty unsure about the file upload bit, for sure. As far as writing it to two files, I was thinking it would simplify things since the total would be the same every time, so the php doesn't have to output it each time and the ajax would only have to request it once (which I didn't in my code, as I was being sloppy).
Anthony
A: 

There are some really good libraries available from JQuery that do just what you're asking. Unless this is purely for learning purposes, I'd take a look at those and avoid rebuilding the wheel.

http://plugins.jquery.com/search/node/upload

iddqd
Ah, I lknow... I have used jquery in the past with good results. But for this I really didn't want to use it, also this isn't for an upload.. Thanks though, I may have to go down that route.
rich