-
-
Save TheCoderRaman/5d8f9097958b0da64efacfe1ced386c4 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(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment