Clicca qui per scaricare la guida per la creazione di file in PHP

Transcript

Clicca qui per scaricare la guida per la creazione di file in PHP
I file in PHP
Un file è un archivio elettronico contenente informazioni (dati) memorizzate su memoria di massa. Il file ha la
caratteristica di consentire la lettura, la scrittura e la modifica dei dati in esso contenuti. Per lavorare con i file
in php è importante conoscere il concetto di puntatore a file. Esso è un numero intero che viene assegnato al
file al momento della sua apertura e ne consente l’individuazione in modo univoco. Al primo file aperto il motore
php assegna il numero 1 e così via. Dopo l’apertura, nel seguito del programma non si dovrà più usare il nome
(o la URL) ma si dovrà fare riferimento al solo puntatore.
Apertura di file
La funzione che PHP mette a disposizione per aprire un file si chiama fopen(). La funzione fopen() causa il
caricamento del descrittore in memoria RAM affinchè il file sia effettivamente disponibile a tutti i livelli.
$miofile=fopen(“/percorso/nomefile.txt”,”w”);
La funzione fopen() ha due parametri: <nome file> e <modalità di apertura> (esiste anche un terzo parametro
<use_include_path> opzionale), e restituisce un il puntatore al file aperto (nell’esempio precedente tale
puntatrore verrò assegnato alla variabile $miofile).
Il parametro <nome file> può essere semplicemente il nome del file (facendo quindi riferimento alla directory
corrente), oppure contenere un percorso tanto relativo quanto assoluto:
$miofile=fopen(“nomefile.txt”,”w”);
// solo nome
$miofile=fopen(“./percorso/nomefile.txt”,”w”);
//percorso relativo
$miofile=fopen(“’/miosito/percorso/nomefile.txt”,”w”); //percorso assoluto
Il parametro <modalità di apertura> indica il tipo di accesso richiesto per il flusso. Esso può essere:
Elenco dei possibili valori usati da fopen() per il parametro modalità di apertura
Descrizione
'r'
Apre in sola lettura; posiziona il puntatore all'inizio del file.
'r+' Apre in lettura e scrittura; posiziona il puntatore all'inizio del file.
'w' Apre il file in sola scrittura; posiziona il puntatore all'inizio del file e il contenuto precedente
viene perso. Se il file non esiste, tenta di crearlo.
'w+' Apre in lettura e scrittura; posiziona il puntatore all'inizio del file e il contenuto precedente
viene perso.Se il file non esiste, tenta di crearlo.
'a' Solo per aggiunta(modalità append). Apre in sola scrittura; posiziona il puntatore alla fine del
file. Se il file non esiste, tenta di crearlo.
'a+' Per lettura e aggiunta. Apre in lettura e scrittura; posiziona il puntatore alla fine del file. Se il file
non esiste, tenta di crearlo.
'x' Crea ed apre il file in sola scrittura; posiziona il puntatore all'inizio del file. Se il file esiste già
la chiamata a fopen() fallirà restituendo FALSE e verrà generato un errore di lievllo E_WARNING.
Se il file non esiste si tenterà di crearlo. Questo equivale a specificare i
flag O_EXCL|O_CREAT nella sottostante chiamata a open(2) . Questa opzione è supportata a
partire dalla versione 4.3.2 di PHP, e funziona solo con i file locali.
Elenco dei possibili valori usati da fopen() per il parametro modalità di apertura
Descrizione
'x+' Crea ed apre il file in lettura e scrittura; posiziona il puntatore all'inizio del file. Se il file esiste
già la chiamata a fopen() fallirà restituendo FALSE e verrà generato un errore di
lievllo E_WARNING. Se il file non esiste si tenterà di crearlo. Questo equivale a specificare i
flag O_EXCL|O_CREAT nella sottostante chiamata a open(2) . Questa opzione è supportata a
partire dalla versione 4.3.2 di PHP, e funziona solo con i file locali.
b
Per trattare il file come file binario. Se non esiste non viene crato.
Nota:
Differenti famiglie di file system hanno differenti tipi di terminatori di riga. Quando si scrive un file di testo e si
desidera inserire una interruzione di linea, occorre utilizzare il terminatore appropriato per il sistema operativo
utilizzato. I sistemi basati su Unix utilizzano \n come terminatore di riga, i sistemi basati su Windows
utilizzano \r\n mentre i sistemi Macintosh utilizzano \r.
Per verificare se l’apertura del file è andata a buon fine basta considerare il valore del puntatore: nel caso in
cui il sistema operativo non fosse riuscito ad aprire il file, cioè a caricarne il descrittore, il motore php assegna
il valore zero (false) alla variabile $miofile.
Esempio di controllo durante l’apertura di un file in php:
$miofile=fopen(“accessi.txt,”r”);
if (!miofile) die(“il file non è stato aperto”);
Dove die(“stringa”) è una funzione di utilità del php che stampa la stringa e fa terminare lo script.
Alternativamente, si può usare la funzione file_exists() per verificare se il file esiste.
Creazione di un file
Per creare un file bisogna utilizzare una delle modalità indicate con la tabella precedente. Possiamo dunque
creare un file nel modo seguente:
$nomefile=”accessi.txt”;
if (file_exists($nomefile))
{
$idfile=fopen($nomefile,’r+’);
if (!$idfile) die(“il file $nomefile non &egrave; stato aperto<BR>”);
$msg=”apertura file $nomefile<BR>”;
}
Else
{
$idfile=fopen($nomefile,’w+’);
if (!$idfile) die(“il file $nomefile non &egrave; stato aperto<BR>”);
$msg=”creazione file $nomefile<BR>”;
}
Echo $idfile;
echo $msg;
Chiusura di un file:fclose()
Al termine delle elaborazioni il file deve essere chiuso. Ciò è molto importante poiché un file aperto occupa
risorse e appesantisce l’elaborazione del server; è quindi necessario che il programmatore si ricordi di
prevedere la chiusura dei file aperti il più frequentemente possibile. Ricordiamoci sempre che stiamo
operando lato server e che gli utenti connessi possono essere numerosi, con conseguente moltiplicazione
delle risorse in gioco e dei possibili conflitti. La funzione di chiusura viene richiamata indicando come
parametro il puntatore relativo:
fclose($miofile);
Senza riprendere la teoria dei sistemi operativi sulla gestione delle risorse condivise, ci limitiamo ad alcune
considerazioni intuitive:



non bisogna avere sezioni interattive mantenendo aperto il file: è meglio riaprirlo e richiuderlo più
volte piuttosto che mantenerlo aperto per più pagine;
l’informazione è la ricchezza del sistema e, appena generata, deve subito essere salvata su disco;
le risorse condivise devono essere gestite in mutua esclusione.
Solo la chiusura del file ci garantisce che le informazioni vengono scritte in modo persistente sul disco e le
risorse vengono rilasciate per poter essere utilizzate da un altro utente o da un altro script:
Scrittura e lettura di un file
Scrittura di un file: fwrite()
La funzione di scrittura ha due parametri : <identificatore del file> e <stringa da scrivere>.
La funzione fwrite() restituisce il numero di byte che ha scritto oppure il valore -1 in caso di errore:
naturalmente il file deve essere stato preventivamente aperto in una modalità che permetta la scrittura.
Con il seguente codice:filescrittura.php
<?php
$nomefile="accessi.txt";
$idfile=fopen($nomefile,'w+');
if (!$idfile) die("il file $nomefile non &egrave; stato aperto<BR>");
$bytescritti=fwrite($idfile,"ali baba");
echo "$bytescritti <BR>";
$bytescritti=fwrite($idfile," e i 40 ladroni");
echo "$bytescritti <BR>";
?>
Otteniamo : 8
15
Se vogliamo rileggere da un file i dati appena scritti, conviene prima chiudere il file (altrimenti la posizione
corrente è il fondo del file) e quindi riaprirlo per leggerlo.
Lettura di un file:fread()
Una volta aperto un file in una delle modalità che ci permette la lettura ( per esempio “r”) e avendo quindi
a disposizione il puntatore del file utilizziamo la funzione fread().
Essa ha due parametri: <identificatore del file> e <numero di byte da leggere>.
Esempio:
<?php
$nomefile="accessi.txt";
$idfile=fopen($nomefile,'w+');
if (!$idfile) die("il file $nomefile non &egrave; stato aperto<BR>");
$bytescritti=fwrite($idfile,"ali baba");
echo "$bytescritti <BR>";
$bytescritti=fwrite($idfile," e i 40 ladroni");
echo "$bytescritti <BR>";
fclose($idfile);
$idfile=fopen($nomefile,"r+");
$datiletti=fread($idfile,23);
echo "$datiletti <BR>";
?>
Otteniamo : 8
15
Ali baba e i 40 ladroni
Possiamo ora affrontare un primo esempio completo che potrà venirci utile in seguito: scriviamo uno script
per registrare il contatore di accessi. Filecontaaccessi.php
<HTML>
<HEAD>
<TITLE>SEMPLICE CONTATORE ACCESSI</TITLE>
</HEAD>
<BODY>
<?php
$nomefile="contatore.txt";
//controllo l'esistenza del file
if (file_exists($nomefile))
{
$idfile=fopen($nomefile,"r+");
if (!$idfile) die("il file $nomefile non &egrave; stato aperto <BR>");
$conta_accessi=(int) fread($idfile,10);
}
else
{
$idfile=fopen($nomefile,"w+");
if (!$idfile) die("il file $nomefile non &egrave; stato aperto <BR>");
$conta_accessi=0;
}
fclose($idfile);
//incremento del contatore accessi
$conta_accessi++;
$idfile=fopen($nomefile,"w+");
if (!$idfile) die("il file $nomefile non &egrave; stato aperto <BR>");
fwrite($idfile,$conta_accessi);
fclose($idfile);
echo($conta_accessi);
?>
</BODY>
</HTML>
Condivisione di un file
Prima di proseguire nella trattazione della gestione dei file, è opportune fare un’osservazione: in generale un
file presente su un server ( per esempio quello che contiene il contatore di accessi), proprio per la sua
funzione, cioè di essere incrementato a ogni accesso, verrà utilizzato da ogni utente, o meglio , da ogni
processo associato a ogni utente che si collega al nostro sito. Ci troviamo in una tipica situazione di
concorrenza , tanto descritta e studiata nel progetto dei sistemi operativi. Il nostro file è in questo caso la
risorsa condivisa e va quindi definita una modalità di sincronizzazione per l’accesso alla sezione critica: il
meccanismo più semplice è quello della mutua esclusione , ossia fare in modo che un solo processo alla volta
acceda alla risorsa condivisa. Php mette a disposizione dell’utente il meccanismo di sincronizzazione basato
sui semafori secondo primitive di lock e unlock . Ricordiamo le due regole fondamentali per la gestione di
una regione critica in mutua esclusione:


quando un processo accede in scrittura a una sezione critica, la risorsa deve essere allocata in modo
esclusivo a tale processo (locked) ossia bloccata;
se due (o più ) processi devono accedere in lettura a una sezione critica la risorsa può essere condivisa
tra tali processi (shared) : condivisa.
La funzione php che ci permette di implementare tale meccanismo è :
flock(int fp, int modo)
dove: fp è il puntatore al file;
modo è un valore intero (come riportato in tabella).
La funzione ritorna a un valore booleano che vale true se ha avuto successo, false in caso d’errore.
Valore
1
2
3
4
Costante predefinita
LOCK_SH
LOCK_EX
LOCK_UN
LOCK_NB
Modalità
Condivisa- shared
Esclusiva- locked
Unlock
Disabilita il semaforo
Descrizione
Per operazioni di lettura
Per operazioni di scrittura
Rilascia la risorsa
Realizza un lock non bloccante
La funzione flock() ha bisogno del puntatore del file e quindi deve essere usata in combinazione con
fopen(): contaaccessiLOCK_EX.php
<?php
$nomefile="contatore.txt";
//operazione di lettura
//controllo l'esistenza del file
if (file_exists($nomefile))
{
$fp=fopen($nomefile,"r");
if (!$fp) die("il file $nomefile non &egrave; stato aperto <BR>");
flock($fp, LOCK_SH); //blocca il file condiviso
$conta_accessi=(int) fread($fp,10); //operazione di lettura
echo "$conta_accessi";
flock($fp,LOCK_UN); // sblocca il file
fclose($fp);
}
?>
Diversamente nel file successivo vediamo il blocco di un file esclusivo in scrittura:
scriviaccessiLOCK_SHeLOCKEX.php
<?php
$nomefile="contatore.txt";
//operazione di LETTURA
//controllo l'esistenza del file
if (file_exists($nomefile))
{
$fp=fopen($nomefile,"r");
if (!$fp) die("il file $nomefile non &egrave; stato aperto <BR>");
flock($fp, LOCK_SH); //blocca il file CONDIVISO
$conta_accessi=(int) fread($fp,10); //operazione di lettura
echo "$conta_accessi";
flock($fp,LOCK_UN); // sblocca il file
fclose($fp);
// OPERAZIONE DI SCRITTURA
$conta_accessi++;
$fp=fopen($nomefile,"r+");
if (!$fp) die("il file $nomefile non &egrave; stato aperto <BR>");
flock($fp,LOCK_EX); //blocca il file ESCLUSIVO
fwrite($fp,$conta_accessi);
flock($fp,LOCK_UN); // sblocca il file
fclose($fp);
echo($conta_accessi);
}
Accesso sequenziale di un file
Lettura sequenziale di un file: fgetc() e feof()
Abbiamo visto come leggere da un file gruppi di caratteri; descriviamo ora nei dettagli la più semplice
modalità di accesso al file: la lettura sequenziale, cioè lo scorrimento del file carattere per carattere dalla
prima posizione all’ultima. Prima di tutto è indispensabile essere in grado di riconoscere quando siamo
arrivato all’ultima posizione.
Per controllare il raggiungimento della fine del file, il linguaggio php offre la funzione feof(<identificatore del
file>) . Questa funzione accetta come parametro il puntatore del file e restituisce un valore booleano che
vale true se la posizione corrente è la fine del file, false altrimenti.
Un’altra funzione che ci permette di controllare il raggiungimento della fine del file è fgetc(<identificatore
file>) :essa ci restituisce il carattere presente alla posizione corrente sul file, oppure il valore booleano false
quando si è raggiunta la fine del file ( si noti che la condizione di fine è proprio inverso di quella della funzione
feof(). Con fgetc() si può simultaneamente leggere il file e controllarne la condizione di terminazione, facendo
attenzione solo ai casi in cui il carattere letto ( per esempio uno zero) equivale al valore booleano false.
Nell’ipotesi di aver approntato un file dati.txt contenente il testo “ali baba e i 40 ladroni”, otteniamo la
stampa “alibabaei40”, in quanto incontra lo zero e la funzione fgetc() interpreta come fine file tale valore .
Esempio di file : sequenza.php
<?php
$nomefile="dati.txt";
//controllo l'esistenza del file
if (file_exists($nomefile))
{
$idfile=fopen($nomefile,"r");
if (!$idfile) die("il file $nomefile non &egrave; stato aperto <BR>");
$msg="contenuto del file $nomefile <BR>";
echo $msg;
do
{
$un_carattere=fgetc($idfile);
echo "$un_carattere ";
} while ($un_carattere);
fclose($idfile);
}
else
{
$msg="il file $nomefile non esiste <BR>";
echo $msg;
}
?>
Modifichiamo l’esercizio, utilizzando la funzione feof() e fread() al posto di fgetc(). E verifichiamo che a
questo punto stampa la stringa completa “alibabaei40ladroni”. Esempio : sequenza2.php
<?php
$nomefile="dati.txt";
//controllo l'esistenza del file
if (file_exists($nomefile))
{
$idfile=fopen($nomefile,"r");
if (!$idfile) die("il file $nomefile non &egrave; stato aperto <BR>");
$msg="contenuto del file $nomefile <BR>";
echo $msg;
while (!feof($idfile))
{
$un_carattere=fread($idfile,1);
echo "$un_carattere ";
}
fclose($idfile);
}
else
{
$msg="il file $nomefile non esiste <BR>";
echo $msg;
}
?>
Altre due funzioni utili per l’accesso sequenziale sono fgets() e fputs(). Esse servono per leggere e scrivere
rispettivamente una stringa di N caratteri in un file.
Posizionamento diretto all’interno di un file.
La seconda modalità di accesso ai dati dei file è l’accesso casuale, che non significa “accesso a caso” ma
“accesso in una qualunque posizione del file “ (è detto anche accesso diretto).
La funzione che permette di posizionarsi in un punto qualsiasi del file è : fseek().
La funzione fseek() accetta due parametri: <identificatore del file> e <offset>
Il secondo parametro offset rappresenta la nuova posizione corrente , espressa in numero di byte dall’inizio
del file. Per esempio con il file diretto1.php si ottiene il seguente risultato
ali baba e
baba e i 4
<?php
$nomefile="dati.txt";
//controllo l'esistenza del file
if (file_exists($nomefile))
{
$idfile=fopen($nomefile,"r");
if (!$idfile) die("il file $nomefile non &egrave; stato aperto <BR>");
$datiletti=fread($idfile,10);
echo "$datiletti <BR>";
$datiletti=fseek($idfile,4);
$datiletti=fread($idfile,10);
echo "$datiletti <BR>";
fclose($idfile);
}
else
{
$msg="il file $nomefile non esiste <BR>";
echo $msg;
}
?>