PHP Extension
PHP Extension
HTTP Download in Parallel with Simultaneous Range Requests
See more HTTP Examples
Demonstrates how to download a large file with parallel simultaneous requests, where each request downloads a segment (range) of the remote file.Chilkat PHP Extension Downloads
<?php
include("chilkat.php");
$success = false;
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
$http = new CkHttp();
// First get the size of the file to be downloaded.
$url = 'https://www.chilkatsoft.com/hamlet.xml';
$resp = new CkHttpResponse();
$success = $http->HttpNoBody('HEAD',$url,$resp);
if ($success == false) {
print $http->lastErrorText() . "\n";
exit;
}
$remoteFileSize = $resp->get_ContentLength();
print 'Downloading ' . $remoteFileSize . ' bytes...' . "\n";
// Let's download in 4 chunks.
// (the last chunk will be whatever remains after the 1st 3 equal sized chunks)
$chunkSize = $remoteFileSize / 4;
// The Range header is used to download a range from a resource
// Range: bytes=<range-start>-<range-end>
// or
// Range: bytes=<range-start>-
// We're writing code this way for clarity..
$http1 = new CkHttp();
$http2 = new CkHttp();
$http3 = new CkHttp();
$http4 = new CkHttp();
$sbRange = new CkStringBuilder();
$sbRange->SetString('bytes=<range-start>-<range-end>');
$numReplaced = $sbRange->ReplaceI('<range-start>',0);
$numReplaced = $sbRange->ReplaceI('<range-end>',$chunkSize - 1);
print $sbRange->getAsString() . "\n";
$http1->SetRequestHeader('Range',$sbRange->getAsString());
$sbRange->SetString('bytes=<range-start>-<range-end>');
$numReplaced = $sbRange->ReplaceI('<range-start>',$chunkSize);
$numReplaced = $sbRange->ReplaceI('<range-end>',2 * $chunkSize - 1);
print $sbRange->getAsString() . "\n";
$http2->SetRequestHeader('Range',$sbRange->getAsString());
$sbRange->SetString('bytes=<range-start>-<range-end>');
$numReplaced = $sbRange->ReplaceI('<range-start>',2 * $chunkSize);
$numReplaced = $sbRange->ReplaceI('<range-end>',3 * $chunkSize - 1);
print $sbRange->getAsString() . "\n";
$http3->SetRequestHeader('Range',$sbRange->getAsString());
$sbRange->SetString('bytes=<range-start>-');
$numReplaced = $sbRange->ReplaceI('<range-start>',3 * $chunkSize);
print $sbRange->getAsString() . "\n";
$http4->SetRequestHeader('Range',$sbRange->getAsString());
// Start each range download
// task1 is a CkTask
$task1 = $http1->DownloadAsync($url,'qa_output/chunk1.dat');
$task1->Run();
// task2 is a CkTask
$task2 = $http2->DownloadAsync($url,'qa_output/chunk2.dat');
$task2->Run();
// task3 is a CkTask
$task3 = $http3->DownloadAsync($url,'qa_output/chunk3.dat');
$task3->Run();
// task4 is a CkTask
$task4 = $http4->DownloadAsync($url,'qa_output/chunk4.dat');
$task4->Run();
// Wait for the downloads to complete.
$numLive = 4;
while ($numLive > 0) {
$numLive = 0;
if ($task1->get_Live() == true) {
$numLive = $numLive + 1;
}
if ($task2->get_Live() == true) {
$numLive = $numLive + 1;
}
if ($task3->get_Live() == true) {
$numLive = $numLive + 1;
}
if ($task4->get_Live() == true) {
$numLive = $numLive + 1;
}
if ($numLive > 0) {
// SleepMs is a convenience method to cause the caller to sleep for N millisec.
// It does not cause the given task to sleep..
$task1->SleepMs(10);
}
}
// All should be downloaded now..
// Examine the result of each Download.
$numErrors = 0;
if ($task1->GetResultBool() == false) {
print $task1->resultErrorText() . "\n";
$numErrors = $numErrors + 1;
}
if ($task2->GetResultBool() == false) {
print $task2->resultErrorText() . "\n";
$numErrors = $numErrors + 1;
}
if ($task3->GetResultBool() == false) {
print $task3->resultErrorText() . "\n";
$numErrors = $numErrors + 1;
}
if ($task4->GetResultBool() == false) {
print $task4->resultErrorText() . "\n";
$numErrors = $numErrors + 1;
}
if ($numErrors > 0) {
exit;
}
// All downloads were successful.
// Compose the file from the parts.
$fac = new CkFileAccess();
$success = $fac->ReassembleFile('qa_output','chunk','dat','qa_output/hamlet.xml');
if ($success == false) {
print $fac->lastErrorText() . "\n";
}
else {
print 'Success.' . "\n";
}
// Let's download in the regular way, and then compare files..
$success = $http->Download($url,'qa_output/hamletRegular.xml');
// Compare files.
$bSame = $fac->FileContentsEqual('qa_output/hamlet.xml','qa_output/hamletRegular.xml');
print 'bSame = ' . $bSame . "\n";
?>