Scaricare il file sul server dall'URL

Beh, questo sembra abbastanza semplice, e lo è. Tutto quello che dovete fare per scaricare un file sul vostro server è:

file_put_contents("Tmpfile.zip", file_get_contents("http://someurl/file.zip"));

Solo che c'è un problema. Cosa succede se hai un file grande, come 100mb. Allora, si esaurirà la memoria e non si potrà scaricare il file.

Quello che voglio è un modo per scrivere il file sul disco mentre lo sto scaricando. In questo modo, posso scaricare file più grandi, senza incorrere in problemi di memoria.

Soluzione

Da PHP 5.1.0, file_put_contents()` supporta la scrittura pezzo per pezzo passando uno stream-handle come parametro $data:

file_put_contents("Tmpfile.zip", fopen("http://someurl/file.zip", 'r'));

Dal manuale:

Se data [che è il secondo argomento] è una risorsa di flusso, il buffer rimanente di quel flusso sarà copiato nel file specificato. Questo è simile all'uso di

(Grazie Hakre).

Commentari (8)
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);
    }
}
Commentari (16)

Prova a usare 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);

Non sono sicuro, ma credo che con l'opzione CURLOPT_FILE scriva mentre estrae i dati, cioè non bufferizzati.

Commentari (5)