Skip to content

Instantly share code, notes, and snippets.

@irazasyed
Last active May 3, 2024 09:57
Show Gist options
  • Save irazasyed/7533127 to your computer and use it in GitHub Desktop.
Save irazasyed/7533127 to your computer and use it in GitHub Desktop.
PHP: File downloader function - Downloading files in chunks.
<?php
/**
* Download helper to download files in chunks and save it.
*
* @author Syed I.R <syed@lukonet.com>
* @link https://github.com/irazasyed
*
* @param string $srcName Source Path/URL to the file you want to download
* @param string $dstName Destination Path to save your file
* @param integer $chunkSize (Optional) How many bytes to download per chunk (In MB). Defaults to 1 MB.
* @param boolean $returnbytes (Optional) Return number of bytes saved. Default: true
*
* @return integer Returns number of bytes delivered.
*/
function downloadFile($srcName, $dstName, $chunkSize = 1, $returnbytes = true) {
$chunksize = $chunkSize*(1024*1024); // How many bytes per chunk
$data = '';
$bytesCount = 0;
$handle = fopen($srcName, 'rb');
$fp = fopen($dstName, 'w');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$data = fread($handle, $chunksize);
fwrite($fp, $data, strlen($data));
if ($returnbytes) {
$bytesCount += strlen($data);
}
}
$status = fclose($handle);
fclose($fp);
if ($returnbytes && $status) {
return $bytesCount; // Return number of bytes delivered like readfile() does.
}
return $status;
}
/** ------------------------------------------
* Function Usage
* ------------------------------------------
*/
$bytes = downloadFile('http://wordpress.org/latest.zip', 'latest.zip');
@mspeener
Copy link

mspeener commented Mar 9, 2018

Works great! No more memory errors.

@laocoi
Copy link

laocoi commented Nov 21, 2020

Working like a charm! Thanks!

@sumeetweb
Copy link

Working smooth still in 2021. I want to add something to it.
If your HTTP Request requires additional headers, pass it to fopen via context.

Example:

function downloadFileChunked($srcUrl, $dstName, $chunkSize = 1, $returnbytes = true) {
$http = array(
'request_fulluri' => 1,
'ignore_errors' => true,
'method' => 'GET'
);
$http['header'] = $headers;
$headers[] = 'User-Agent: Your-Custom-User-Agent';
$headers[] = 'Authorization: Bearer FooBarFooBar';

$context = stream_context_create(array( 'http' => $http ));

$chunksize = $chunkSize*(1024*1024); // How many bytes per chunk
$data = '';
$bytesCount = 0;
$handle = fopen($srcUrl, 'rb', false, $context);
$fp = fopen($dstName, 'w');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$data = fread($handle, $chunksize);
fwrite($fp, $data, strlen($data));
if ($returnbytes) {
$bytesCount += strlen($data);
}
}
$status = fclose($handle);
fclose($fp);
if ($returnbytes && $status) {
return $bytesCount; // Return number of bytes delivered like readfile() does.
}
return $status;
}

@jazz7381
Copy link

how to use this script if the file is protected by basic auth?

@sumeetweb
Copy link

how to use this script if the file is protected by basic auth?

Use the header : Authorization: Basic

If the "Basic" authentication scheme is used, the credentials are constructed by first combining the username and the password with a colon (aladdin:opensesame), then by encoding the resulting string in base64 (YWxhZGRpbjpvcGVuc2VzYW1l).

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment