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 è stato aperto<BR>”); $msg=”apertura file $nomefile<BR>”; } Else { $idfile=fopen($nomefile,’w+’); if (!$idfile) die(“il file $nomefile non è 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 è 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 è 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 è stato aperto <BR>"); $conta_accessi=(int) fread($idfile,10); } else { $idfile=fopen($nomefile,"w+"); if (!$idfile) die("il file $nomefile non è 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 è 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 è 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 è 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 è 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 è 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 è 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 è 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; } ?>