views:

129

answers:

2

Hello all,

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12.4M  100 12.4M    0     0  4489k      0  0:00:02  0:00:02 --:--:-- 4653k

The above is a CURL output from the command line when download the file. I have captured this using PHP like so, but I am having trouble working out how to use pre_match to extract the percentage done.

$handle = popen('curl -o '.VIDEOPATH.$fileName.'.flv '.$url, 'rb');

while(!feof($handle))
{
    $progress = fread($handle, 8192);
    //I don't even know what I was attempting here
    $pattern = '/(?<Total>[0-9]{1,3}\.[0-9]{1,2})% of (?<Total>.+) at/';
    //divide received by total somehow, then times 100
    if(preg_match_all($pattern, $progress, $matches)){
    fwrite($fh, $matches[0][0]."\r\n");
    }

}

How can I do this? Please note, I have no idea what I am doing with the above preg_match_all!

Thanks

Update

Thanks to the help of ylebre. I have this so far.

$handle = popen('curl -o '.VIDEOPATH.$fileName.'.flv '.$url.' 2>&1', 'rb');//make sure its saved to videos

while(!feof($handle))
{

    $line = fgets($handle, 4096); // Get a line from the input handle
    echo '<br>Line'.$line.'<br>';
    $line = preg_replace("/s+/", " ", $line); // replace the double spaces with one
    $fields = explode(" ", $line); // split the input on spaces into fields array
    echo '<br>Fields: '.$fields[0];
    fwrite($fh, $fields[0]); // write a part of the fields array to the output file

}

I get this output to the browser:


Line % Total % Received % Xferd Average Speed Time Time Time Current

Fields: Line Dload Upload Total Spent Left Speed

Fields: Line 0 1340k 0 4014 0 0 27342 0 0:00:50 --:--:-- 0:00:50 27342 41 1340k 41 552k 0 0 849k 0 0:00:01 --:--:-- 0:00:01 1088k 100 1340k 100 1340k 0 0 1445k 0 --:--:-- --:--:-- --:--:-- 1711k

Fields: Line


How do I extract the percentage part only? Maybe CURL can do this by itself - hmm will ask a question on this.

+1  A: 

The progress that is showing up is probably updating the information in the same spot, so it will help if you know what you are parsing exactly.

The next step I recommend is taking one line of input, and trying to get the regexp to work on that.

You could also just split the string at the spaces if I'm reading the output correctly. If you start out by replacing all the double spaces into one. After that you can use explode() to get an array with the values, which you can print_r to take a peek what is inside.

This would be something like:

$line = fgets($handle, 4096); // Get a line from the input handle
$line = preg_replace("/s+/", " ", $line); // replace the double spaces with one
$fields = explode(" ", $line); // split the input on spaces into fields array
fwrite($fh, $fields[0]); // write a part of the fields array to the output file

As long as the ordering in the fields remains the same, your resulting array should give you a consistent result.

Hope this helps!

ylebre
Ah! This looks like something I can understand. :) Thank you for the explanation. I had a go and I managed to receive the ouput above (updated question) - it seems to get both lines but not the percentage part. Anyway, I can edit this further? Thanks.
Abs
If the array is populated as I'm hoping, you should be able to access the percentage field in $fields[1].
ylebre
A: 

If you have access to PHP 5.3, you can use the CURL_PROGRESSFUNCTION option, which results in a much more elegant solution (no parsing output). Here's an example of how to use it:

function callback($download_size, $downloaded, $upload_size, $uploaded)
{
  $percent=$downloaded/$download_size;
  // Do something with $percent
}

$ch = curl_init('http://www.example.com');

// Turn off the default progress function
curl_setopt($ch, CURLOPT_NOPROGRESS, false);

// Set up the callback
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'callback');

// You'll want to tweak the buffer size.  Too small could affect performance.  Too large and you don't get many progress callbacks.
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);

$data = curl_exec($ch);
scompt.com