@@ -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 ();