Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I download multiple parts of a file in parallel with PHP's curl library?
    primarykey
    data
    text
    <p>I decided to start a project about download acceleration with curl in PHP, using curl_multi functions.</p> <p>Here is my code:</p> <pre><code>set_time_limit(0); error_reporting(E_ALL); $fileurl = "http://hq-scenes.com/tv.exe"; $filename = basename($fileurl); $size = getFileSize($fileurl); $splits = range(0, $size, round($size/5)); $megaconnect = curl_multi_init(); $partnames = array(); for ($i = 0; $i &lt; sizeof($splits); $i++) { $ch[$i] = curl_init(); curl_setopt($ch[$i], CURLOPT_URL, $fileurl); curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 0); curl_setopt($ch[$i], CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch[$i], CURLOPT_VERBOSE, 1); curl_setopt($ch[$i], CURLOPT_BINARYTRANSFER, 1); curl_setopt($ch[$i], CURLOPT_FRESH_CONNECT, 0); curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT, 10); $partnames[$i] = $filename . $i; $bh[$i] = fopen(getcwd(). '/' . $partnames[$i], 'w+'); curl_setopt($ch[$i], CURLOPT_FILE, $bh[$i]); $x = ($i == 0 ? 0 : $splits[$i]+1); $y = ($i == sizeof($splits)-1 ? $size : $splits[$i+1]); $range = $x.'-'.$y; curl_setopt($ch[$i], CURLOPT_RANGE, $range); curl_setopt($ch[$i], CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.29 Safari/535.1"); curl_multi_add_handle($megaconnect, $ch[$i]); } $active = null; do { $mrc = curl_multi_exec($megaconnect, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active &amp;&amp; $mrc == CURLM_OK) { if (curl_multi_select($megaconnect) != -1) { do { $mrc = curl_multi_exec($megaconnect, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } $final = fopen($filename, "w+"); for ($i = 0; $i &lt; sizeof($splits); $i++) { $contents = fread($bh[$i], filesize($partnames[$i])); fclose($bh[$i]); fwrite($final, $contents); } fclose($final); function getFileSize($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $h = fopen('header', "w+"); curl_setopt($ch, CURLOPT_WRITEHEADER, $h); $data = curl_exec($ch); curl_close($ch); if (preg_match('/Content-Length: (\d+)/', $data, $matches)) { return $contentLength = (int)$matches[1]; } else return false; } </code></pre> <p>Everything goes OK, except one thing:</p> <p>The last part file doesn't reach the end of the file. the actual file size is : 3279848 bytes</p> <p>ranges are:</p> <pre><code>0-655970 655971-1311940 1311941-1967910 1967911-2623880 2623881-3279848 </code></pre> <p>part files with size</p> <pre><code>tv.exe0 655360 tv.exe1 655360 tv.exe2 655360 tv.exe3 655360 tv.exe4 655360 </code></pre> <p>That makes the final file 3276800 bytes length, but it must be 3279848 bytes. And of course the executable didn't work :(</p> <p>Notice that the part files have the same size. Even the last one, which should have some more bytes. So the problem is in the download range or something, not in the merge process.</p> <p>What did I do wrong?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload