Nel forum più volte vengono rivolte domande che implicano una manipolazione di dati che risiedono su file.
Questa breve pillola non è certamente esaustiva ed omnicomprensiva ma cerca di dare un indirizzo generale a molte di queste domande.
Da tenere presente che un db su file non sarà mai lontanamente paragonabile ad un db vero e proprio con un proprio linguaggio che lo rende maggiormente efficiente.
In questi casi, la prima cosa da tenere presente è la struttura che daremo ai nostri dati sul file: questa deve essere standard per ogni record che inseriremo in modo da poter trattare in modo uniforme tutti i records.
Cerchiamo di immaginare il nostro db su file strutturato in questo modo
Ogni record su una riga
campo1 delimitatore campo2 delimitatore campo3 caratteredifinerecord
Come si può capire si devono tenere presenti:
a) il delimitatore
b) il carattere di fine record
c) il numero di campi
Questa struttura ricorda i files con dati in formato csv (comma separated value).
Se apriamo un foglio di calcolo, immettiamo i dati nelle colonne A B e C in modo omogeneo (su ogni colonna c'è un tipo di dato) e salviamo questo foglio in formato csv, aprendo il file creato con un prg di lettura di file di testo (ex.Notepad) noteremo che sarà così formato:
campo1;campo2;campo3
dato1;dato2;dato3
dato4;dato5;dato6
dove il ; rappresenta il nostro delimitatore di campo e \n (che in questo caso non è visibile) il carattere di fine record.
Vediamo, dunque, come immettere e trattare i dati in quest'ottica
Le funzioni php che utilizzeremo sono
file fopen fputs fclose list explode trim count time date strtoupper
Potete vederne l'utilizzo su www.php.net immettendole come ricerca
Supponiamo che vogliamo gestire una rubrica di indirizzi email utilizzando come separatore di campi il carattere | (naturalmente questo carattere non dovrà essere presente nei vari record ma deve essere utilizzato solo come delimitatore) e come carattere di fine record \n
Struttura della rubrica
data di iscrizione|nome|email\n
Nome del file di rubrica: rubrica.txt
SCRIVERE UN RECORD
Per prima cosa vediamo come scrivere un record.
Tenendo presente la struttura della rubrica, la cosa diventa molto semplice:
codice:
// i dati nome ed email provengono presumibilmente da un form con campi input text nome ed email
// togliamo eventuali spazi bianchi e fine riga all'inizio ed alla fine di ogni dato
$nome = trim($nome);
$email = trim($email);
// apriamo il file di rubrica
$fp = fopen("rubrica.txt", "a");
// scriviamo il nostro record
fputs($fp, time()."|$nome|$email\n");
// chiudiamo il file
fclose($fp)
VISUALIZZARE I RECORDS
Per poter leggere i dati invece tratteremo i dati in array sfruttando la funzione file("nomefile")
Dunque:
codice:
// immettiamo tutti i dati del file in un array
$records = file("rubrica.txt");
// contiamo gli elementi dell'array totale
$numero = count($records);
// scorriamo l'array
for($x = 0; $x < $numero; ++$x)
{
// togliamo il carattere \n
$records[$x] = trim($records[$x]);
// immettiamo i dati del singolo record in un array
$dati = explode("|", $records[$x]);
// assegniamo a delle variabili i valori dell'array
list($timestamp, $nome, $email) = $dati;
// stampiamo i risultati a video
echo "Data: ".date("d/m/Y", $timestamp)." Nome: $nome Email: $email
";
}
Per brevità, il codice precedente poteva essere ridotto a meno righe accorpando i vari passaggi
codice:
$records = file("rubrica.txt");
for($x = 0; $x < count($records); ++$x)
{
list($timestamp, $nome, $email) = explode("|", trim($records[$x]));
echo "Data: ".date("d/m/Y", $timestamp)." Nome: $nome Email: $email
";
}
Per scorrere i record dall'ultimo al primo
codice:
...
for($x=count($records); $x > 0; --$x)
...
RICERCARE UN RECORD
Bisogna innanzitutto decidere in base a quale campo effettuare la ricerca
Quella di seguito esposta è una ricerca unsensitive (non tiene conto di maiuscole e minuscole) e con esatta corrispondenza
Supponiamo di voler fare un ricerca in base al campo nome
codice:
// elaboriamo la stringa da ricercare togliendo eventuali spazi bianchi all'inizio e alla fine e convertendo tutte le lettere in maiuscolo
$searching = trim(strtoupper("valoredaricercare"));
// impostiamo una variabile di controllo
$found = false;
$records = file("rubrica.txt");
// ciclo per scorrere i records
for($x = 0; $x < count($records); ++$x)
{
list($timestamp, $nome, $email) = explode("|", trim($records[$x]));
// se c'è corrispondenza, interrompe il ciclo
if( strtoupper($nome) == $searching ) {
$found = true;
break;
}
}
// stampiamo il risultato
if($found) {
echo "Data: ".date("d/m/Y", $timestamp)." Nome: $nome Email: $email";
}
else {
echo "Non sono state trovate corrispondenze";
}
Naturalmente questa ricerca soffre di molte limitazioni, prima di tutte il fatto che si blocca al primo record trovato.
MODIFICARE UN RECORD
Data la ricerca di cui sopra potremo pensare di modificare tale record.
Infatti basterebbe aggiungere al posto della stampa del record trovato un form
codice:
echo "<form name=\"modifica\" action=\"modifica.php\" method=\"post\">";
echo "Nome : <input type=\"text\" name=\"mod_nome\" value=\"$nome\">
";
echo "Email : <input type=\"text\" name=\"mod_email\" value=\"$email\">
";
echo "<input type=\"hidden\" name=\"searching\" value=\"$searching\">";
echo "<input type=\"submit\" name=\"modifica\" value=\"modifica\">";
echo "</form>";
e nel file modifica.php
codice:
$records = file("rubrica.txt");
// apriamo il file rubrica.txt per rigenerarlo
$fp = fopen("rubrica.txt", "w");
// ciclo per scorrere i records
for($x = 0; $x < count($records); ++$x)
{
list($timestamp, $nome, $email) = explode("|", trim($records[$x]));
// se c'è corrispondenza stampa i nuovi valori, altrimenti stampa i vecchi
if( strtoupper($nome) == $searching ) {
fputs($fp, time()."|$mod_nome|$mod_email\n");
}
else {
fputs($fp, $record[$x]);
}
}
// chiudiamo il file
fclose($fp);
L'esempio citato ha il limite di modificare tutti i nomi corrispondenti alla ricerca!!!
Faccio notare che le cose suesposte sono esemplificative, molto limitate e di concetto più che di pratica (probabilmente con più di qualche errore anche di codice).
Per sviluppare questo tipo di codice bisogna stare molto attenti alle piccole cose.
Gli esempi qui postati non possono essere utilizzati sic et sempliciter ma bisogna considerarli come pure esemplificazioni da poter sviluppare
Spero che questo mio contributo possa stimolarne di nuovi in questo senso.