di Antonella Sorbini 3 agosto 2019
Capita di dover estrarre grosse quantità di file di testo da un database già bello pieno, soprattutto se si decide di cambiare la struttura del database come spiegato nella mia pagina Siti in php con database piccoli e piu' file di testo
Se ci si trova a maneggiare database con un migliaio di record è impensabile mettersi a fare una cosa del genere a mano, siamo matti? ci si rinuncia in partenza. Ovviamente sfruttiamo il codice PHP per farci fare da lui il lavoro di estrazione dei file in automatico e metterli in una o più cartelle.
Ci mettiamo dunque al lavoro.
Partiamo dal presupposto di avere una tabella di DB classica con dentro qualunque cosa.
idArticolo | titoloArticolo | testoArticolo | altro |
contatore | testo | testo | ... |
.... | .... | .... | ... |
Ora ci prepariamo una pagina php nuova in cui ci inseriamo il codice che ci serve per fare il processo in automatico così mi ritrovo la cartella bella pronta tutta riempita con i file di testo. Per farlo sfruttiamo le funzioni sulla gestione dei file che php mette a disposizione e che sono molto comode. La documentazione ufficiale su tutte le funzioni per la gestione dei file si trova qui (Filesystem Functions), un mio articolo precedente in cui parlo della scrittura di un file con il codice php si trova qui (Scrivere file di testo con script PHP a oggetti ), ora però dobbiamo adattare il tutto alle nostre esigenze.
Ecco il codice della nostra paginetta php, il suo funzionamento è spiegato con i commenti lungo il codice, con queste premesse:
1-la tabella che ci interessa si chiama 'Tabella',
2- il suo contatore è 'idArticolo',
3-i testi che voglio estrarre sono nel campo 'titoloArticolo'
4-va costruita e messa sul server a mano una cartella vuota con il nome che ci serve in questo caso è 'titoloArticolo' (la scelta è ovviamente personale ma in queto modo il nome è autoesplicativo)
5- per evitare macelli si processa un solo campo alla volta, quindi i file vengono costruiti in una cartella alla volta, e per tutte le cartelle necessarie basta cambiare i codici della pagina e rimandarla in esecuzione sul server.
<?php
//classe che si occupa della scrittura dei file
class ScriviFile {
public function scriviTesto($percorsoNomeFile, $testo) {
$file = fopen($percorsoNomeFile, 'a+');//la funzone open prende vari parametri per decidere il tipo di permessi che si hanno sul file, in questo caso è a+, così crea il file anche se non esiste ancora e pone il pontatore alla fine del testo scritto
fwrite($file, $testo);
fclose($file);
}
};
//Connessione al database
//blocco dei parametri di connessione, ci vanno messi i dati forniti da chi ci gestisce il database
// nome di host
$host = "****";
// username dell'utente in connessione
$user = "*******";
// password dell'utente
$password = "******";
// nome del database
$db = "*******";
//stringa di connessione al DBMS
// istanza dell'oggetto della classe MySQLi
$mysqli = new mysqli($host, $user, $password, $db);
// verifica su eventuali errori di connessione
if ($mysqli->connect_errno) {
echo "Connessione fallita: ". $mysqli->connect_error . ".";
exit();
}
//ricavo i dati dalla tabella che mi interessa
$result = $mysqli->query("SELECT * FROM tabella ");//inserire qui il nome della tabella da cui prendere i dati
if($result->num_rows > 0) {
while($row = $result->fetch_array(MYSQLI_ASSOC)) //inserisco i dati estratti in un array
{
print_r ($row); //serve solo per la stampa di prova, non è obbligatorio ma utile, mi serve per vedere scritto l'array che ho ricavato e ridurre le quote di errore che puntualmente si verificano, magari solo per distrazione
echo '<br/>';//serve solo per vedere più facilmente i dati dell'array stampato
$idArticolo = $row['idArticolo']; //memorizzo il valore del campo idArticolo nella variabile con lo stesso nome, per evitare errori
$titoloArticolo = $row['titoloArticolo'];//idem come sopra
//cominciamo a lavorare seriamente alla scrittura dei file:
//l'oggetto objScriviFile che viene istanziato, prende due parametri in ingresso, uno è il percorso con il nome da dare al file, l'altro è la stringa che costituisce il testo da inserire nel file quindi ora ce li personalizziamo:
$nomeFile='titoloArticolo/titoloArticolo'.$idArticolo.'.txt';//qui devo costruire il percorso completo e dare il nome al file: quello che mi aspetto di ottenere è una cartella che si chiama titoloArticolo con dentro tanti file titoloArticolo1.txt, titoloArticolo2.txt ...ecc
$stringa=$titoloArticolo; //qui è il testo ricavato dalla tabella
//ora si costruisce l'oggetto che fa il lavoro di scrittura
$objScriviFile = new ScriviFile;
$objScriviFile->scriviTesto($nomeFile, $stringa);//tutto quanto è scritto qui si lascia inalterato perchè ho già personalizzato sopra
}
}
else {
echo 'nessun record presente'; }
// chiusura della connessione
$mysqli->close();
?>
Tutta questa paginona si sarebbe potuta sintetizzare inserendo la connessione la database come inclusione di file esterno come anche la classe ScriviFile posta all'inizio, ma per evitare piccoli errori di comprensione che poi andrebbero a pregiudicarne il funzionamento, ho preferito scriverla nel modo più esteso possibile.
Una volta scritta questa pagina php, la si scarica sul server in cui è residente il nostro bel sito e la si richiama dal browser mandandola così in esecuzione. Se tutto fila liscio, sulla pagina appariranno i dati dell'array senza alcuna indicazione di errore e andando a controllare la cartella che prima era vuota, adesso deve essere piena di file.
Se invece vengono indicati anche degli errori, significa che abbiamo avuto qualche distrazione nell'inserimento dei nomi di variabile: controllare SEMPRE l'utilizzo di maiuscole e minuscole, e anche se non si è capito un tubo di tutto quanto ho scritto qui, l'unica cosa che bisogna tener presente per estrarre i testi dal database in modo corretto sostituire in modo corretto i nomi che ho usato nell'esempio:
tabella --> mettere il nome della tabella da cui interessa estrarre i dati (riga 37 di questo codice)
IdArticolo --> mettere il nome del campo nel tabase che contiene il contatore della tabella (riga 44 e 52 di questo codice)
titoloArticolo --> mettere il nome del file che voglio ottenere e che concide con il nome della cartella vuota che conterrà tutti i file (riga 46, 52, 53 di questo codice)
Se finalmente tutto è andato in porto, ripetere la stessa operazione per tutte le cartelle che ci interessano, fatto questo finalmente possiamo pure buttare al secchio tutti i campi non più utili del nostro database.
Ora si deve fare attenzione su un punto: usando il parametro a+, si scrive il file e il puntatore si mette ALLA FINE del file, lo script fa il suo lavoro e siamo tutti contenti. Poi però c'è la variabile umana: capita che si mandi in esecuzione la pagina un'altra volta, magari solo perchè quel bastardo dell'autocompletamento degli indirizzi nel browser te la fa partire senza che uno non lo voglia effettivamente, e allora che succede? Il file in apertura viene già trovato pieno e si scrive di nuovo il testo partendo dalla coda del file, quindi se uno non ci pensa, si ritrova il testo estratto nel file duplicato tante volte quante è andato in esecuzione lo script. Per non complicarsi la vita basta eliminare il file php dal server dopo il suo utilizzo. Tutto qui.