Last active
February 8, 2024 16:53
-
-
Save ARACOOOL/0d9e5300b6d5b981dfad809af699d485 to your computer and use it in GitHub Desktop.
Download remote file with progress bar (PHP, curl)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php | |
<?php | |
/** | |
* Usage: | |
* php downloader.php http://path.to/remote/file.ext /local/file/path | |
* | |
* Output: | |
* [############################################################################################### ] 96% | |
*/ | |
/** | |
* Class Downloader | |
*/ | |
class Downloader | |
{ | |
/** | |
* @var string | |
*/ | |
private $url; | |
/** | |
* @var string | |
*/ | |
private $destination; | |
/** | |
* Downloader constructor. | |
* @param string $url | |
* @param string $destination | |
*/ | |
public function __construct(string $url, string $destination) | |
{ | |
$this->url = $this->prepareUrl($url); | |
$this->destination = $this->prepareDestination($destination); | |
} | |
/** | |
* @param string $url | |
* @return string | |
*/ | |
private function prepareUrl(string $url): string | |
{ | |
if (!filter_var($url, FILTER_VALIDATE_URL)) { | |
$this->stderr('Invalid URL'); | |
die; | |
} | |
return $url; | |
} | |
/** | |
* @param string $output | |
*/ | |
private function stderr(string $output): void | |
{ | |
fwrite(STDERR, $output); | |
} | |
/** | |
* @param string $destination | |
* @return string | |
*/ | |
private function prepareDestination(string $destination): string | |
{ | |
$fileName = basename($destination); | |
$dirName = realpath(dirname($destination)); | |
if (!$dirName) { | |
$this->stderr('Check the destination path of file'); | |
die; | |
} | |
return $dirName . DIRECTORY_SEPARATOR . $fileName; | |
} | |
/** | |
* | |
*/ | |
public function download(): void | |
{ | |
$ch = curl_init(); | |
$fp = fopen($this->destination, 'wb'); | |
curl_setopt_array($ch, [ | |
CURLOPT_URL => $this->url, | |
CURLOPT_HEADER => false, | |
CURLOPT_FOLLOWLOCATION => true, | |
CURLOPT_FILE => $fp, | |
CURLOPT_PROGRESSFUNCTION => [$this, 'progress'], | |
CURLOPT_NOPROGRESS => false, | |
CURLOPT_SSL_VERIFYPEER => false, | |
CURLOPT_FAILONERROR => true | |
]); | |
curl_exec($ch); | |
if (curl_errno($ch)) { | |
$this->stderr('Error: ' . curl_error($ch)); | |
die; | |
} | |
curl_close($ch); | |
fclose($fp); | |
} | |
/** | |
* @param $resource | |
* @param int $download_size | |
* @param int $downloaded | |
* @param int $upload_size | |
* @param int $uploaded | |
*/ | |
private function progress($resource, $download_size = 0, $downloaded = 0, $upload_size = 0, $uploaded = 0): void | |
{ | |
$percent = $download_size > 0 && $downloaded > 0 ? ceil($downloaded * 100 / $download_size) : 0; | |
$this->stdout('[' . str_pad('', $percent, '#') . str_pad('', 100 - $percent) . "] $percent%\r"); | |
} | |
/** | |
* @param string $output | |
*/ | |
private function stdout(string $output): void | |
{ | |
fwrite(STDOUT, $output); | |
} | |
} | |
$dw = new Downloader($argv[1], $argv[2]); | |
$dw->download(); |
how to calculate current speeds?
The app does not do it, but you can calculate it separately:
$downloadSize = 15360; // kb
$downloadTime = 2000; // milliseconds
$estimatedDwnSpeed = $downloadSize / $downloadTime = 7.6; // mbps
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how to calculate current speeds?