2011-01-25 14 views
14

Ho uno script PHP che occasionalmente ha bisogno di scrivere file di grandi dimensioni su disco. Utilizzando file_put_contents(), se il file è abbastanza grande (in questo caso circa 2 MB), lo script PHP esaurisce la memoria (errore fatale PHP: dimensione di memoria consentita di ######## byte esauriti). So che potrei solo aumentare il limite di memoria, ma non mi sembra una soluzione completa - ci deve essere un modo migliore, giusto?Qual è il modo migliore per scrivere un file di grandi dimensioni su disco in PHP?

Qual è il modo migliore per scrivere un file di grandi dimensioni su disco in PHP?

+1

Qual è la fonte dei dati? Inoltre, la maggior parte delle configurazioni di PHP dovrebbe essere in grado di gestire 2MB senza problemi. Il limite di memoria potrebbe essere inferiore. – webbiedave

+1

Da dove viene il file? Se esiste già su disco, quindi 'copia()' sarebbe più appropriato. – mario

+0

In questo caso, sto recuperando il file da un server remoto usando curl. Quindi, l'ho in una variabile. –

risposta

15

Avrete bisogno di un file temporaneo in cui si mette i bit del file di origine, più che cosa è da aggiungere:

$sp = fopen('source', 'r'); 
$op = fopen('tempfile', 'w'); 

while (!feof($sp)) { 
    $buffer = fread($sp, 512); // use a buffer of 512 bytes 
    fwrite($op, $buffer); 
} 

// append new data 
fwrite($op, $new_data);  

// close handles 
fclose($op); 
fclose($sp); 

// make temporary file the new source 
rename('tempfile', 'source'); 

in questo modo, l'intero contenuto della source non vengono letti nella memoria. Quando si utilizza cURL, si potrebbe omettere l'impostazione CURLOPT_RETURNTRANSFER e invece, aggiungere un buffer di uscita che scrive in un file temporaneo:

function write_temp($buffer) { 
    global $handle; 
    fwrite($handle, $buffer); 
    return ''; // return EMPTY string, so nothing's internally buffered 
} 

$handle = fopen('tempfile', 'w'); 
ob_start('write_temp'); 

$curl_handle = curl_init('http://example.com/'); 
curl_setopt($curl_handle, CURLOPT_BUFFERSIZE, 512); 
curl_exec($curl_handle); 

ob_end_clean(); 
fclose($handle); 

Sembra come se mi manca sempre l'ovvio. Come sottolineato da Marc, c'è lo CURLOPT_FILE per scrivere direttamente la risposta sul disco.

+0

Ha senso, ma in questo caso ho recuperato il file da un altro server usando curl, quindi è già in memoria. –

+0

@Joe Ho aggiornato la risposta. Un altro suggerimento che ti sta arrivando. –

+0

per la prima soluzione che potresti aver usato ['stream_copy_to_stream'] (http://php.net/stream_copy_to_stream) ;-) – arnaud576875

1

scrittura riga per riga (o pacchetto per pacchetto, in caso di file binari) utilizzando le funzioni come fwrite()

0

Prova this answer:

$file = fopen("file.json", "w"); 

    $pieces = str_split($content, 1024 * 4); 
    foreach ($pieces as $piece) { 
     fwrite($file, $piece, strlen($piece)); 
    } 

    fclose($file); 
Problemi correlati