Skip to content

Instantly share code, notes, and snippets.

@TheCoderRaman
Forked from ARACOOOL/downloader.php
Created October 5, 2023 10:38
Show Gist options
  • Save TheCoderRaman/5d8f9097958b0da64efacfe1ced386c4 to your computer and use it in GitHub Desktop.
Save TheCoderRaman/5d8f9097958b0da64efacfe1ced386c4 to your computer and use it in GitHub Desktop.

Revisions

  1. @ARACOOOL ARACOOOL revised this gist Aug 16, 2017. No changes.
  2. @ARACOOOL ARACOOOL created this gist Aug 9, 2017.
    128 changes: 128 additions & 0 deletions downloader.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,128 @@
    #!/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();