Bueno, esto parece bastante sencillo, y lo es. Todo lo que tienes que hacer para descargar un archivo en tu servidor es:
file_put_contents("Tmpfile.zip", file_get_contents("http://someurl/file.zip"));
Sólo hay un problema. ¿Qué pasa si usted tiene un archivo grande, como 100mb. Entonces, se quedará sin memoria, y no podrá descargar el archivo.
Lo que quiero es una forma de escribir el archivo en el disco mientras lo estoy descargando. De esta manera, puedo descargar archivos más grandes, sin tener problemas de memoria.
Desde PHP 5.1.0, file_put_contents()
soporta la escritura pieza a pieza pasando un stream-handle como parámetro $data
:
file_put_contents("Tmpfile.zip", fopen("http://someurl/file.zip", 'r'));
Del manual:
Si data [que es el segundo argumento] es un recurso de flujo, el búfer restante de ese flujo se copiará en el archivo especificado. Esto es similar al uso de
(Gracias Hakre.)
private function downloadFile($url, $path)
{
$newfname = $path;
$file = fopen ($url, 'rb');
if ($file) {
$newf = fopen ($newfname, 'wb');
if ($newf) {
while(!feof($file)) {
fwrite($newf, fread($file, 1024 * 8), 1024 * 8);
}
}
}
if ($file) {
fclose($file);
}
if ($newf) {
fclose($newf);
}
}
Pruebe a utilizar cURL
set_time_limit(0); // unlimited max execution time
$options = array(
CURLOPT_FILE => '/path/to/download/the/file/to.zip',
CURLOPT_TIMEOUT => 28800, // set this to 8 hours so we dont timeout on big files
CURLOPT_URL => 'http://remoteserver.com/path/to/big/file.zip',
);
$ch = curl_init();
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
No estoy seguro, pero creo que con la opción CURLOPT_FILE
se escribe a medida que se extraen los datos, es decir, no en el buffer.