Un'esigenza di molte applicazioni web è quella di esportare, o importare, i dati dal nostro database. Accade spesso, per esempio, che in fase iniziale si disponga di un database già popolato e dal quale caricare i dati, o di dover esportare dati per condividerli con altri programmi.
La scelta di usare il formato CSV (Comma Separated Value) è quella che garantisce la maggiore compatibilità: creeremo infatti un file di testo dove stabiliremo il separatore dei campi, in genere la virgola o il punto e virgola, e stamperemo una riga di testo per ciascun record da esportare.
Trattandosi di un file di testo praticamente qualsiasi linguaggio di programmazione o applicazione sarà in grado di leggere i dati e gestirli. Per citare due casi particolarmente popolari possiamo segnalare che il CSV potrebbe essere un buon modo per passare i dati a un database importandoli tramite phpMyAdmin, o per visualizzare le informazioni esportate all'interno di Excel.
Per ottenere il nostro scopo dovremo connetterci al database e lanciare una query SELECT
. Il secondo passaggio sarà costituito dal ciclo sui dati estratti dove costruiremo una stringa facendo attenzione che l'output venga stampato in un file di testo, la formattazione non potrà quindi essere in formato HTML. Per capirsi, alla fine della riga il ritorno a capo non sarà eseguito tramite il classico tag br
, ma con \n
ovvero new line
.
Infine dovremo predisporre le istruzioni per la stampa della stringa e il download del file, o il suo salvataggio sul server.
Connessione al database e estrazione dei dati
Procediamo quindi con la connessione al database e l'estrazione dei dati:
$host = 'localhost';
$mydatabase = 'corso';
$user = 'root';
$pass = 'root';
try {
$db = new PDO('mysql:host='.$host.';dbname='.$mydatabase, $user, $pass);
} catch (PDOException $e) {
echo "Errore: " . $e->getMessage();
die();
}
Il secondo step sarà costituito da una SELECT sulla tabella utenti
più volte usata in questa guida:
$sql = 'SELECT id, nome, cognome, email FROM utenti ORDER BY id ';
$stmt = $db->prepare($sql);
$stmt->execute();
Prepariamo quindi una variabile stringa in cui inserire i dati estratti:
$output = '';
A questo punto dobbiamo definire il delimitatore di campo, in genere il doppio apice ("
), che serve a racchiudere i valori del campo estratto, e il separatore di campo: useremo il punto e virgola (;
), altre opzioni sono la virgola (,
) o la tabulazione (\t
).
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$output.='"'.$row['id'].'";';
$output.='"'.$row['nome'].'";';
$output.='"'.$row['cognome'].'";';
$output.='"'.$row['email'].'";';
$output.="\n";
}
Il codice prodotto presenta uno svantaggio: creerà un'ultima riga vuota, potrebbe quindi essere opportuno rimuovere $output.="\n";
e inserire come prima istruzione del ciclo un controllo di questo tipo:
if($output!= ''){$output.="\n";}
In pratica stiamo dicendo che aggiungeremo il ritorno a capo prima della riga a partire dalla seconda.
Salvataggio o download del file
Costruita la stringa del contenuto possiamo passare alla gestione dell'output. Il primo caso sarà quello di salvare il contenuto in un file:
$file = 'miofile.csv';
$f = fopen($file,'w');
fwrite($f,$output);
fclose($f);
Per questo scopo impostiamo il nome del file, apriamolo in modalità scrittura (write), scriviamo la stringa creata e chiudiamo il file.
L'altra opzione è quella di procedere all'invio del file stesso:
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename="miofile.csv");
echo $output;
exit;
}
header()
permette di settare le intestazioni del file. Con il Content-type
specifichiamo che tipo di file inviare, mentre con Content-Disposition
forziamo il browser a mostrare la finestra che richiede il salvataggio del file con il nome suggerito. Una volta salvato possiamo aprire il nostro file con un qualsiasi editor di testo.
Infine si potrebbe decidere di inviare un file CSV e, invece di aprirlo con un editor di testo, usare Excel o OpenOffice per la visualizzazione del contenuto; eventualmente dovremo settare correttamente i parametri relativi al separatore e al delimitatore, la variazione da apportare al nostro codice sarà in questo caso:
$file = "sheet.xls";
header("Content-Type: application/vnd.ms-excel");