2015-05-28 21 views
7
private function convert_to_csv($input_array, $output_file_name, $delimiter) { 

    $temp_memory = fopen('php://memory','w'); 

    foreach ($input_array as $line) { 

     fputcsv($temp_memory, $line, $delimiter); 

    } 

    fseek($temp_memory, 0); 

    header('Content-Type: application/csv'); 
    header('Content-Disposition: attachement; filename="' . $output_file_name . '";'); 

    fpassthru($temp_memory); 

}    

Io uso la funzione di cui sopra per prendere una matrice di dati, convertirli in CSV e inviarli al browser. Due domande:Crea CSV in memoria, e-mail e rimuovi dalla memoria

  1. Il file viene rimosso dalla memoria dopo essere stato scaricato tramite HTTP?
  2. Come si riscriverà questa stessa funzione in modo che il file possa essere utilizzato (ad esempio, da utilizzare come allegato di posta elettronica inviato con PHPMailer) e quindi rimosso immediatamente dalla memoria?

EDIT: Codice di lavoro - Ma scrive in un file, non la memoria

public function emailCSVTest() { 

    $test_array = array(array('Stuff','Yep'),array('More Stuff','Yep yep')); 

    $temp_file = '/tmp/temptest.csv'; 

    $this->convertToCSV($test_array, $temp_file); 

    $this->sendUserEmail('Test Subject','Test Message','[email protected]',$temp_file); 

    unlink($temp_file); 

} 

private function convertToCSV($input_array, $output_file) { 

    $temp_file = fopen($output_file,'w'); 

    foreach ($input_array as $line) { 

     fputcsv($temp_file, $line, ','); 

    } 

    fclose($temp_file); 

} 

ancora senza risposta: non la funzione originale rimuovere il file dalla memoria, o no?

+1

vorrei solo memorizzare il file nel file system ('/ tmp' per esempio), inviare la posta (con allegato) e in seguito chiama 'unlink()' sul nome del file. –

+0

Quindi modifica la prima riga in $ temp_file = fopen ('/ tmp/abc.csv', 'w'), crea il file, quindi sostituisci fseek >> fpassthru con return $ temp_file, seguito nella funzione padre con unlink ($ temp_file)? – FurryWombat

+0

qualcosa del genere, sì. Non dimenticare di 'fclose()' prima il file. (prima di 'unlink()') –

risposta

7

farei temp fopen involucro uso di PHP insieme con soglia di memoria come questo:

// we use a threshold of 1 MB (1024 * 1024), it's just an example 
$fd = fopen('php://temp/maxmemory:1048576', 'w'); 
if($fd === FALSE) { 
    die('Failed to open temporary file'); 
} 

$headers = array('id', 'name', 'age', 'species'); 
$records = array(
    array('1', 'gise', '4', 'cat'), 
    array('2', 'hek2mgl', '36', 'human') 
); 

fputcsv($fd, $headers); 
foreach($records as $record) { 
    fputcsv($fd, $record); 
} 

rewind($fd); 
$csv = stream_get_contents($fd); 
fclose($fd); // releases the memory (or tempfile) 

La memoria soglia è 1 MB. Se il file CSV diventa più grande, PHP creerebbe un file temporaneo, altrimenti tutto avverrà in memoria. Il vantaggio è che i file grandi CSV non esauriranno la memoria.

Informazioni sulla seconda domanda, fclose() rilascia la memoria.

Una volta ho scritto un articolo del blog riguardo a questo, potreste trovare interessante: http://www.metashock.de/2014/02/create-csv-file-in-memory-php/

+0

cosa succede quando un altro processo (utente) esegue lo stesso script e anche il file temporaneo deve essere creato: ciascun file temporaneo avrà un nome file univoco? In modo che non vengano sovrascritti? – Andrew

+0

certo, questo è sicuro. – hek2mgl

+0

E se ho bisogno di 'percorso_file', per essere usato in un'altra funzione (qualcosa come CurlFile()), allora il percorso dovrebbe essere intero 'php: // temp/maxmemory: 1048576'? – Andrew