15 commenti tutorial, php

I database testuali sono dei semplici documenti di testo (.txt) in cui vengono salvati dei dati per poi essere letti tramite script php.

 

In particolare php offre una gamma di funzioni atte alla scrittura e lettura dei file in cui potranno essere salvati dei dati e letti all'occorrenza.

 

 

LIMITI DEI DATABASE TESTUALI

Occorre fin da subito chiarire un punto: i database testuali sono utilizzabili solo nel caso in cui la mole di dati in esso contenuta è relativamente piccola e soggetti a sporadiche modifiche.

 

Infatti essi avranno una gestibilità decisamente molto più complessa e limitata rispetto a quella ottenibile con un database MySql dato che non sarà possibile formulare le query.

Inoltre, risulta quasi del tutto impossibile istaurare relazioni fra i dati.

 

 

IL FUNZIONAMENTO

Al fine di gestire i dati contenuti in un file .txt occorrerà:

  • "scrivere" il file con una idonea formattazione;
  • eseguire operazioni su di esso ricorrendo ad alcune funzioni; fra le tante, ve ne sono alcune che assumono particolare rilievo: fopen(), fread(), fwrite(), fclose(), file() ed explode().

 

Chiariamo i due concetti esaminandoli separatamente.

 

 

LA FORMATTAZIONE DI UN DATABASE TESTUALE

Un file .txt si articola in più righi: ognuno di essi potrà rappresentare un set di dati.

 

Ad esempio poniamo di voler costruire un database in cui salvare i dati riguardanti dei prodotti su un file di testo: ogni rigo potrà rappresentare un prodotto.

Tuttavia, per ogni prodotto inserito occorrerà salvare più di una informazione: poniamo, ad esempio, di voler salvare il nome, la taglia e il prezzo.

Affinche più dati siano scritti su un unico rigo occorrerà strutturare una formattazione adeguata. Vediamone un esempio:

 

capo|taglia|prezzo

 

Pertanto il file di testo che possiamo chiamare prodotti.txt avrà una struttura di questo genere:

camicia|S|150
felpa|XXL|220
t-shirt|M|250

 

In pratica i tre dati (nome, taglia e prezzo) che desideriamo salvare su un unica riga del file .txt saranno separati gli uni dagli altri da un carattere separatore (poco comune) a nostra scelta, nell'esempio "|".

 

Quindi, un database testuale è un file .txt in cui ciascun rigo contiene uno o più dati e all'interno del rigo i singoli dati sono separati da una carattere separatore.

Ciò sarà rilevante sia in fase di lettura, sia in fase di scrittura del file.

 

 

LA LETTURA

In fase di "lettura" è possibile far ricorso a diverse funzioni che tuttavia presentano ognuna delle specifiche particolarità.

Quella che in caso di database testuali risulta essere maggiormente utile è file().

 

La funzione file() accetta come unico parametro il percorso al file che si desidera leggere ed esegue una lettura del file rigo per rigo restituendo un array in cui ciascun elemento è costituito da un rigo.

Ovviamente, avendo ottenuto un array, questo potrà essere letto con un classico ciclo foreach.

 

Scorrendo il nostro array otterremo un singolo rigo per ogni ciclo; per isolare i singoli dati presenti all'interno di tale rigo si farà ricorso alla funzione explode().

 

La funzione explode() riceve due parametri obbligatori: il primo è il carattere separatore; il secondo è una stringa da trasformare in un array.

 

Vediamo cosa avremo:

<?php
$my_database_txt = 'prodotti.txt';
$array_righi = file($my_database_txt);
foreach($array_righi as $key => $capi){
	list($capo, $taglia, $prezzo) = explode("|", $capi);
	echo '
		<p>
		Capo: ' .$capo. '<br />
		Taglia: ' .$taglia. '<br />
		Prezzo: ' .$prezzo. '<br />
		<a href="action.php?delete=' .$key. '">Elimina</a> - <a href="form_update.php?row=' .$key. '">Modifica</a>
		</p>
		<hr />';
	}
?>

 

Si ponga attenzione ai link per eseguire l'eliminazione e la modifica di un prodotto il cui funzionamento sarà di seguito illustrato.

 

 

LA SCRITTURA

Per poter scrivere su un file di testo occorre anzitutto assicurarsi che questo abbia i permessi di scrittura: a questo scopo può essere utile la funzione is_writable(). Essa prende come parametro il percorso al file e restituisce un valore boleano, TRUE se il file può essere scritto.

 

La scrittura del file avverrà con le funzioni fopen(), fwrite() e fclose().

 

La funzione fopen() serve per apire il collegamento con la risorsa (il file da scrivere). Essa prevede due parametri obbligatori: il percorso al file e una stringa che ci indicherà modalità con la quale si vorrà operare sul file (si rimanda al manuale per maggiori dettagli).

La funzione fwrite() esegue la scrittura sul file e prevede due parametri: la risorsa e la stringa da scrivere.

Infine, la funzione fclose() esegue la chiusura del file e prevede come unico parametro la risorsa.

 

Avremo una pagina con un banale form:

<form action="action.php" method="post">
<label for="capo">Capo</label>
	<input type="text" id="capo" name="capo" />
<label for="taglia">Taglia</label>
	<input type="text" id="taglia" name="taglia" />
<label for="prezzo">Prezzo</label>
	<input type="text" id="prezzo" name="prezzo" />
	
	<input type="submit" name="scrivi" value="scrivi" />
</form>

 

 

E poi avremo una pagina (action.php) che eseguirà la scrittura sul un file prodotti.txt:

<?php
$my_database_txt = 'prodotti.txt';
if(isset($_POST['scrivi']))
	{
	if(!is_writable($my_database_txt)){
		exit("il file non ha i permessi di scrittura!");
		}
	// riceviamo i dati e li filtriamo
	$bad_char = array("|", "rn", "r", "n");
	$capo = str_replace($bad_char, "", $_POST['capo']);
	$taglia = str_replace($bad_char, "", $_POST['taglia']);
	$prezzo = str_replace($bad_char, "", $_POST['prezzo']);
	// apriamo il file
	$open = fopen($my_database_txt, "a+");
	// scriviamo i dati separati dal carattere separatore
	fwrite($open, $capo."|".$taglia."|".$prezzo."rn"); 
	// chiudiamo il file   
	fclose($open);
	
	// ritorniamo nella pagina di visualizzazione
	header("location: lettura.php");
	exit;
	}
?>

 

 

ELIMINARE UN RIGO DAL FILE .TXT

Eliminare un rigo sta a significare, nel caso del nostro database basato su file di testo, eliminare un prodotto. Abbiamo precedentemente visto che ciascun prodotto avrà un link per l'eliminazione scritto attaverso un ciclo foreach di questo tipo (si veda il codice per eseguire la lettura):

 

<a href="action.php?delete=' .$key. '">Elimina</a>

 

La variabile $key all'interno del ciclo individua la chiave dell'array ottenuto con la funzione file() e, quindi, ci consente di individuare il rigo specifico che vogliamo eliminare. Nel file action.php pertanto avremo:

 

if(isset($_GET['delete']))
	{
	// creiamo l'array con tutti i righi
	$array_righi = file($my_database_txt);
	// eliminiamo dall'array il rigo la chiave inviata via get
	unset($array_righi[$_GET['delete']]);
	// apriamo il file resettando il contenuto
	$open = fopen($my_database_txt, "w");
	foreach($array_righi as $key => $value){
		// ri-scriviamo tutti i righi (rimanenti)
		fwrite($open, $value);
		}
	fclose($open);
	// ritorniamo nella pagina di visualizzazione
	header("location: lettura.php");
	exit;
	}

 

Occorre notare che conla funzione unset() eliminiamo l'elemento dall'array; inoltre la funzione fopen, a differenza di quando fatto in precedenza, avrà come secondo parametro w e quindi questo verrà cancellato di tutto il suo contenuto e riscritto di nuovo ma senza il rigo eliminato.

Il codice proposto necessiterebbe di ulteriori e più rigidi controlli (quantomento con array_key_exists) ma ho voluto ridurre al minimo lo script.

 

 

LA MODIFICA DI UN RIGO DI UN FILE .TXT

La modifica del singolo rigo segue una logica per molti aspetti simile a quella vista per l'eliminazione. Tuttavia in questo caso avremo uno step ulteriore: dovremo precompilare un form con i dati correnti del rigo che desideriamo modificare e poi, al submit di tale form, eseguire la modifica.

 

Anzitutto esaminiamo il link che rimanda alla pagina di modifica che, ricordo, viene prodotto all'interno del ciclo foreach (si veda il codice per eseguire la lettura):

<a href="form_update.php?row=' .$key. '">Modifica</a>

 

 

Come detto in precedenza per l'eliminazione, $key ci permetterà di individuare il rigo che desideriamo modificare. In questo caso dovremo estrarre i dati contenuti in tale rigo e compilare i value del form:

<?php
$my_database_txt = 'prodotti.txt';
if(!isset($_GET['row'])){
	header("location: lettura.php");
	exit;
	}
$array_righi = file($my_database_txt);
if(!isset($array_righi[$_GET['row']])){
	exit('errore nella chiave');
	}
list($capo, $taglia, $prezzo) = explode("|", $array_righi[$_GET['row']]);
?>
<html>
<head>
</head>
<body>
<h2><a href="lettura.php">Torna alla lista degli articoli</a></h2>
<form action="action.php" method="post">
<label for="capo">Capo</label>
	<input type="text" id="capo" name="capo" value="<?php echo htmlentities($capo, ENT_QUOTES); ?>" />
<label for="taglia">Taglia</label>
	<input type="text" id="taglia" name="taglia" value="<?php echo htmlentities($taglia, ENT_QUOTES); ?>" />
<label for="prezzo">Prezzo</label>
	<input type="text" id="prezzo" name="prezzo" value="<?php echo htmlentities($prezzo, ENT_QUOTES); ?>" />
	<input type="hidden" name="row_update" value="<?php echo $_GET['row']; ?>" />
	<input type="submit" name="modifica" value="modifica" />
</form>
</body>
</html>

 

Si noti il campo name="row_update" di tipo hidden che avrà come value la chiave inviata via get. All'invio del form andremo a recuperare i dati inviati: i nuovi valori che dovrà assumere il rigo e il rigo da modificare (presente nel campo hidden). Pertanto avremo:

 

$my_database_txt = 'prodotti.txt';
if(isset($_POST['modifica']) AND isset($_POST['row_update']))
	{
	// creiamo l'array con tutti i righi
	$array_righi = file($my_database_txt);
	// riceviamo i dati e li filtriamo
	$bad_char = array("|", "rn", "r", "n");
	$capo = str_replace($bad_char, "", $_POST['capo']);
	$taglia = str_replace($bad_char, "", $_POST['taglia']);
	$prezzo = str_replace($bad_char, "", $_POST['prezzo']);
	// ri-scriviamo il rigo (che sostituirà il precedente)
	$array_righi[$_POST['row_update']] = $capo."|".$taglia."|".$prezzo."rn";
	// apriamo il file resettando il contenuto
	$open = fopen($my_database_txt, "w");
	foreach($array_righi as $key => $value){
		// ri-scriviamo tutti i righi
		fwrite($open, $value);
		}
	fclose($open);
	// ritorniamo nella pagina di visualizzazione
	header("location: lettura.php");
	exit;	
	}

 

Come possiamo notare lo script segue una logica analoga a quella vista per l'eliminazione con l'unica differenza che anzichè eliminare l'elemento dall'array $array_righi con unset lo andremo a valorizzare con i nuovi valori (opportunamente filtrati) provenienti dal form, semparando i valori con il carattere semparatore | e aggiungendo a fine stringa il ritorno a capo.

 

Di seguito il link al download dei file in cui è presente lo script completo.

download

Olimpio Romanella

Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.

Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.

15 Commenti presenti

avatar Relpa

Relpa

19 November 2015 ore 12:01

....ho capito.

avatar Relpa

Relpa

15 November 2015 ore 11:31

nessuna risposta?

avatar Relpa

Relpa

11 November 2015 ore 17:24

@Relpa: Aggiungo che si tratta di un carrello destinato a pochi prodotti e ormai impostato su files testuali. L'uso di Mysql non so configurarlo e dovrei, penso, cambiare molto se non tutto il lavoro fatto fino qui.
Superato questo ostacolo dovrei essere in dirittura di arrivo...
Grazie comunque

avatar Relpa

Relpa

11 November 2015 ore 16:39

@Olimpio Romanella:
Allego una riga del database che prevede:
Id|Cod.Prod|Nome|Descrizione|Prezzo|Immagine|Opzione1|Opzione2|Opzione3|Opzione4|Opzione5|Opzione6
e una riga memorizzata in db/articoli.php
0|001|Giacca|Giacca Armani...| 150,00 |<img src='db/images/1' width='30'>|opz1|opz2|opz3|opz4|opz5|opz6|<img src='db/images/1' width='200'>
1|243e|12|6tyu56t| 123|<img src='db/images/2' width='30'>|4er|w4er|w4er|e4r|tfwed5|rftgv|<img src='db/images/2' width='200'>
La prima immagine '30' si vede nel pannello di amministrazione e la seconda '200' nell'index.php
ecc...

avatar Olimpio Romanella

Olimpio Romanella

11 November 2015 ore 16:18

@Relpa: come e' strutturato il tuo database?

in ogni caso per questo genere di usi e' opportuno usare un database MySql

avatar Relpa

Relpa

11 November 2015 ore 16:14

<?php
include('setting1.php');
$array_righi = file($my_database_php);
foreach($array_righi as $key => $idriga){
list($idriga, $art, $nome, $desc, $prezzo, /*$file,*/ $opz1, $opz2, $opz3, $opz4, $opz4, $opz5, $opz6, $file) = explode("|", $idriga);
echo '<p style="margin:0 auto; float:left; padding-right:25px; text-align:center;"><a href="carrello.php?id=' .$idriga. '"> ' .$file.'</a></p>';
}
?>
Con questo script inserisco in index.php, tramite un pannello di amministrazione, una serie di immagini prese da un database testuale. Una volta presenti nella index, cliccando su ciascuna immagine, passo alla pagina carrello.php
(es. carrello.php?id=2). A questo punto come posso richiamare in carrello.php il singolo prodotto associato all'immagine proveniente da index.php e relativi dati memorizzati nel database testuale? Richiamare , quindi, in una sola pagina carrello.php, tutti i prodotti alternativamente per poi passarli infine alla pagina di riepilogo acquisti?
Grazie dell'attenzione.

avatar Giuseppe Micali

Giuseppe Micali

13 January 2014 ore 19:07

E' un ottimo script, però non riesco a far partire la numerazione da 1 e non da zero

avatar Francesco

Francesco

17 September 2013 ore 20:59

Buongiorno a tutti, ho riscontrato un problema nella modifica e nella cancellazione delle righe con i rispettivi form. Sono l'unico che ha avuto problemi di questo tipo?
Help!
Grazie!

avatar Emilio Lussu

Emilio Lussu

05 September 2013 ore 12:15

Molto spesso, l'essere dei "crani" nell'informatica, non significa avere anche le capacità di saper fare didattica. Molti di costoro, non sanno spiegare, non sanno farsi capire. Questo é il sito migliore che ho trovato. Complimenti per l'estrema chiarezza di come sono spiegati gli script, e anche per l'ordine di come sono redatti. Grande maestria nella didattica!

avatar mcroy

mcroy

18 February 2013 ore 18:23

ma il tasto download mi scarica tutt'altra cosa: un form di iscrizione.
dove posso trovare i file dello script in oggetto?
grazie.

avatar oly1982

oly1982

08 February 2013 ore 15:21

@Marco: è la normale sintassi del ciclo foreach che si utilizza per scorrere gli array.

avatar Marco

Marco

06 February 2013 ore 23:04

ciao! davvero ottimo lavoro...

mi puoi spiegare per quanto riguarda lo script di lettura, che significa questa porzione di codice:

foreach($array_righi as $key => $capi)

precisamente "$key => $capi"

avatar D.O.

D.O.

20 November 2012 ore 19:37

Complimenti per la maestria con la quale è stata redatta questa utilissima guida. Questo è uno dei migliori blog che ho incrociato sul web. Davvero complimenti, continua così!!!

avatar Mario

Mario

31 October 2012 ore 14:45

Ciao,
grazie per l'utilissima guida, volevo soltanto sapere se è possibile effettuare un minimo di filtraggio per la visualizzazione dei dati, per esempio, se si tratta di prodotti se possiamo far visualizzare soltanto quelli che appartengono ad una certa "categoria" ponendo il caso che nel database di testo fosse un campo disponibile.
Grazie

avatar Penelope

Penelope

11 August 2011 ore 03:19

Grazie ^_^ questo tua guida mi è stata utilissima per realizzare un guestbook, ovviamente ti inserirò nei credits^^ Per il momento il sito è ofline (totale restauro)ma spero ti faccia piace vedere il lavoro x il momento link
Un abbraccio e ancora grazie