How do I stop a remote file from downloading a file if it exceeds 5mb? If I stop it while transferring, will the file be held somewhere in some other temp dir or memory? How would I know? Here is my current code:
$url = 'http://www.spacetelescope.org/static/archives/images/large/heic0601a.jpg';
$file = '../temp/test.jpg';
file_put_contents($file, file_get_contents($url));
There are a number of ways in which you could do this, but because you are currently using file_get_contents()
, here is what I would do:
fopen()
fread()
- this allows you to track the current size and throw and error when you pass the threshold.Something like this:
$url = 'http://www.spacetelescope.org/static/archives/images/large/heic0601a.jpg';
$file = '../temp/test.jpg';
$limit = 5 * 1024 * 1024; // 5MB
if (!$rfp = fopen($url, 'r')) {
// error, could not open remote file
}
if (!$lfp = fopen($file, 'w')) {
// error, could not open local file
}
// Check the content-length for exceeding the limit
foreach ($http_response_header as $header) {
if (preg_match('/^\s*content-length\s*:\s*(\d+)\s*$/', $header, $matches)) {
if ($matches[1] > $limit) {
// error, file too large
}
}
}
$downloaded = 0;
while (!feof($rfp) && $downloaded < $limit) {
$chunk = fread($rfp, 8192);
fwrite($lfp, $chunk);
$downloaded += strlen($chunk);
}
if ($downloaded > $limit) {
// error, file too large
unlink($file); // delete local data
} else {
// success
}
NB: it is tempting to inspect the Content-Length:
header before you receive any of the file to check whether the file is too large - you can still do this if you like, but do not trust the value! The header is essentially an arbitrary value, and while it would be a protocol violation to use a content length that does not match the size of the file, it could be used to fool the system into downloading a file that breaks the rules. You'd need count the bytes even if you do check this value.
You could also do this using curl via the data callback, but I would regard this as a less satisfactory solution, mostly because of fact that curl requires a string function name and not the standard generic callable
type, which means you would either need to use a global variable or a static
variable in order to keep track of the downloaded content length, neither of which are acceptable (IMHO) for this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With