Funzioni php di base files

Funzioni php di base files

 

 

 

I riassunti , gli appunti i testi contenuti nel nostro sito sono messi a disposizione gratuitamente con finalità illustrative didattiche, scientifiche, a carattere sociale, civile e culturale a tutti i possibili interessati secondo il concetto del fair use e con l' obiettivo del rispetto della direttiva europea 2001/29/CE e dell' art. 70 della legge 633/1941 sul diritto d'autore

 

 

Le informazioni di medicina e salute contenute nel sito sono di natura generale ed a scopo puramente divulgativo e per questo motivo non possono sostituire in alcun caso il consiglio di un medico (ovvero un soggetto abilitato legalmente alla professione).

 

 

 

 

Funzioni php di base files

6. I files

Uno degli scopi principali della programmazione è la manipolazione di dati e strutture di dati. Queste strutture in alcuni casi sono temporanee, memorizzate in memoria centrale come variabili, array oppure oggetti, ma spesso si ha la necessità di disporre di strutture dati permanenti, memorizzate su disco, accessibili a qualunque script ne abbia la necessità e non solo allo script in corso di esecuzione. Queste strutture dati possono essere memorizzate nei files oppure nei database. In questo capitolo tratteremo dell’accesso alle informazioni contenute nei files.
L’ambiente PHP dispone di estensioni in grado di accedere al file-system per leggere, scrivere e modificare il contenuto dei files. Alcune di queste funzioni sono modellate sulla struttura delle corrispondenti funzioni della “standard library” del “C” mentre altre sono astrazioni di livello superiore.
Dal punto di vista della visione del filesystem distinguiamo due situazioni:

  • Accesso diretto al filesystem locale
  • Accesso tramite un servizio al filesystem (locale o remoto)

Nel primo caso viene specificato un percorso nel filesystem locale (assoluto o relativo) cioè nel disco dell’host in cui è in esecuzione lo script.
Esempio: /home/belxxxxxx/public_html/files/prova.txt è un percorso locale assoluto
files/prova.txt è un percorso locale relativo
Nel secondo caso viene specificato un URL (completo di protocollo, host e path) e quindi attraverso il servizio specificato si raggiunge un filesystem che può essere sia locale che remoto.
Esempio: http://labsis.scuole.bo.it/~belxxxxx/files/prova.txt  è un accesso tramite http
ftp://labsis.scuole.bo.it/pub/4b5/prova.txt  è un accesso tramite ftp
Naturalmente l’effettivo accesso alle informazioni (lettura, scrittura, cancellazione…) sono subordinate ai diritti posseduti dall’agente. Si deve tenere presente che l’agente non è lo sviluppatore che ha generato lo script ma il processo che esegue lo script. Per i dettagli vedere il successivo paragrafo sui diritti di accesso.

6.1 Regole per la costruzione di un percorso locale:

Le regole di percorso vanno scritte secondo lo stile “Unix”.
Lavorando in sviluppo sulla piattaforma Windows l’intepreter traduce le regole da unix a windows con una importante eccezione: in ambiente unix non esistono le unità (A:, C: …) perché i dispositivi fisici sono “montati” come cartelle di un unico file system che parte dalla radice (/) quindi è bene evitare riferimenti diretti alle unità che impedirebbero la portabilità WindowsàUnix.
Questa regola impone che sulla piattaforma Windows i percorsi siano relativi rispetto alla unità (/percorso e non C:/percorso) limitando le operazioni di file-system alla stessa unità su cui si trova lo script.
Nessun problema invece con l’opposta direzione delle barre (\ in win e / in unix). Conviene usare sempre lo stile unix perché l’intepreter che gira su windows ribalta automaticamente le barre.
Alcune regole di gestione dei percorsi:

  • nome.ext                   à il file si trova nella stessa cartella dello script (sconsigliato)
  • ./nomefile.ext            à come sopra ma più sicuro perché specifica esplicitamente

    l’indicazione cartella corrente (più portabile)

  • cart/nome.ext           à il file si trova in una sottocartella della cartella corrente
  • ./cart/nome.ext        à come sopra ma più portabile
  • ../nome.ext               à il file si trova nella cartella superiore allo script
  • ../cart/nome.ext       à il file si trova in una cartella parallela a quella dello script
  • ../c1/c2/nome.ext     à il file si trova in una cartella contenuta in una cartella parallela

   a quella dello script        

  • ../../nome.ext           à il file si trova due livelli sopra la cartella corrente
  • ../../cart/nome.ext    à il file si trova in una cartella contenuta due livelli sopra
  • /c1/c2/nome.ext         à percorso assoluto (va usato con cautela)

Poiché può capitare di dovere usare uno stesso percorso più volte cambiando il nome file può essere utile memorizzare il percorso in una variabile e poi concatenarlo con il nome file corrente:


$path=”../cart/”
$nomefile=”prova.txt”
$fullpath=$path.$nomefile;   

6.2 Inclusione

Un importante caso di utilizzo dei files è la inclusione di files nello script. Si realizza con le funzioni include() o require(). L’unica differenza tra le due funzioni è che la prima in caso di fallimento produce un warning non fatale che può anche essere nascosto mentre la seconda produce un errore fatale che interrompe l’interpretazione. Tutto sommato nella maggior parte dei casi conviene usare require anche se molti script ereditati da precedenti versioni di PHP contengono include.


<?php
 ...
 require(“./file.inc”);
 ...
?>   

Note:

  • Quando l’interpreter esegue l’istruzione require cerca il file nel percorso specificato, lo legge e lo inserisce al posto della istruzione di require.
  • L’inclusione interrompe l’interpretazione. Se il file incluso contiene a sua volta uno script (in linea o una funzione) è necessario ripetere le tag di script <?php ... ?>
  • La precedente caratteristica consente di includere direttamente tag html
  • L’interpretazione riprende automaticamente al termine del file di inclusione
  • L’inclusione in PHP è piuttosto diversa dalla inclusione di un header in “C”. In questo caso infatti l’header incluso viene processato dal compilatore e serve esclusivamente per motivi di analisi sintattica (prototipi, classi e tipi derivati) mentre nel caso del PHP viene utilizzato dall’interpreter e quindi normalmente contiene istruzioni che vengono immediatamente eseguite, corpi di funzione che vengono rese disponibili per una successiva esecuzione o tag html che vengono direttamente mandate in output
  • Una conseguenza importante del punto precedente è che non si deve abusare della inclusione inserendo funzioni inutili perché viene rallentata l’esecuzione.

Esaminiamo i tre casi principali con l’aiuto di esempi:
Esecuzione immediata di istruzioni:


<?php                             //script principale
 require(“./italiano.inc”);
 echo $s;
?>   

 

<?php                             //file italiano.inc
 $s=”Questa stringa è in italiano”;
?>

Note:

  • Lo script principale apre il file italiano.inc nella cartella corrente. L’interpreter si interrompe
  • Il file italiano.inc contiene una tag di script quindi viene interpretato. Notare che non è necessaria l’estensione .php perché non deve essere cercato dal web server.
  • L’esecuzione di italiano.inc porta alla generazione della stringa $s con il suo contenuto. Al termine del file l’interpretazione si interrompe.
  • Al ritorno al file principale riprende l’interpretazione con l’emissione del contenuto di $s
  • Questo esempio fa riferimento ad una possibile soluzione del problema della localizzazione (cioè configurazione di uno stesso programma in diverse lingue). Si può sviluppare lo script indipendentemente dalla lingua, sviluppare vari file di inclusione nazionali contenenti le stesse informazioni ma in lingue diverse e poi configurare lo script (anche dinamicamente) in modo che includa il file di lingua appropriato. Il file english.inc conterrebbe la stringa: “This string is in English”

Definizione del corpo di funzioni:


<?php                             //script principale
 require(“./funzioni.inc”);
 $c=somma(1,1);
 echo $c;
?>   

 

<?php                             //file funzioni.inc
 function somma($a, $b) {
  $ris=$a+$b;
  return $ris;
 }
?>

Note:

  • Lo script principale apre il file funzioni.inc nella cartella corrente. L’interpretazione si interrompe.
  • Il file funzioni.inc contiene una tag di script quindi viene interpretato. Notare che non è necessaria l’estensione .php perché non deve essere cercato dal web server.
  • L’esecuzione di funzioni.inc porta alla definizione della funzione somma() ma non alla sua esecuzione. Successive istruzioni dello stesso script possono usare la funzione somma. Notare che non è come l’inclusione di un header in “C”. In questo caso la funzione viene effettivamente inclusa, non solo il suo prototipo. Al termine del file l’interpretazione si interrompe.
  • Al ritorno al file principale riprende l’interpretazione con la invocazione della funzione appena definita,
  • Questo esempio fa riferimento alla costruzione di librerie di funzioni dell’utente che possono essere scritte una volta per tutte e riutilizzate in diversi script. Questa tecnica porta a numerosi vantaggi come la riduzione del tempo di sviluppo (una volta progettata una funzione la si usa in molti progetti), aumento della correntezza (se si corregge un errore, la correzione è automaticamente riportata in tutti gli script), migliore leggibilità degli script (le azione più complesse sono nascoste nelle funzioni).
  • In questo tipo di inclusioni è particolarmente importante evitare i side-effect per garantire la riusabilità dei files. Esistono alcune importanti eccezioni che verranno trattate in seguito (connessione ad una banca dati, procedura di autenticazione)

Inclusione diretta di tag html:


<?php                             //script principale
 require(“./instestazione.html”);
 ...
?>   

 

<!—file intestazione.html -->
<table><tr><td><h1>Instestazione della pagina</h1></td></tr></table>

Note:

  • Lo script principale apre il file intestazioni.inc nella cartella corrente. L’interpretazione si interrompe.
  • Il file intestazioni.inc contiene solo tag html quindi viene mandato così come è all’output standard (browser). L’estensione è .html solo per motivi di sviluppo ma potrebbe essere qualsiasi.
  • Al ritorno al file principale riprende l’interpretazione delle istruzioni che seguono.
  • Questo esempio fa riferimento alla costruzione di blocchi di codice html predisposti per un uso generale riusabili in molti script. Individuare parti comuni a tutte le pagine di uno stesso sito ed estrarle come file di inclusione html da il vantaggio che quando si aggiorna una parte comune tutte le pagine vengono di conseguenza aggiornate. Ad esempio se si cambia <h1> in <h2> le dimensioni dell’intestazione di tutte le pagine vengono cambiate senza dovere materialmente modificare tutte le pagine.
  • E’ possibile una soluzione intermedia in cui inserite nelle tag html sono presenti tag php. Questa soluzione sarà oggetto di un esercizio aggiuntivo.

6.3 Lettura di un file
Esistono molte tecniche di lettura dei files che differiscono per livello di astrazione. Possiamo dividere in due categorie:

  • Funzioni di tipo “C standard library”: è un insieme di funzioni che ricalca la gestione dei files in ambiente “C”. Consente la lettura sia di file di testo per righe e per caratteri che la lettura di files binari per record.
  • Funzioni che leggono l’intero file in una unica operazione: queste funzioni costituiscono astrazioni più potenti riservate in genere ai soli files di testo. L’intero file viene letto in una unica operazione e il risultato viene mandato a seconda dei casi ad una ad un array, ad una stringa, o all’output standard.

Funzioni di tipo “C standard library”
Come in “C” il file deve essere aperto in lettura con la funzione fopen():


$f=fopen(“miofile.txt”,”r”); //apre un  file in sola lettura

Note:

  • Il percorso può essere locale relativo o assoluto oppure remoto
  • Restituisce un intero che viene usato come puntatore al file
  • Se fallisce restituisce FALSE

Se il file è di testo può essere letto con le funzioni di lettura fgetc(), fgets() ed fscanf:


$char=fgetc($f);                      //legge un carattere
$buffer=fgets($f,4096);               //legge una riga (max 4096 bytes)
fscanf($f,”$s,$s\n”,$nome,$cognome);  //legge una riga formattata

Note:

  • Tutte le funzione restituiscono FALSE se falliscono
  • Dopo la lettura il puntatore al file è incrementato alla posizione successiva
  • fgetc restituisce una stringa contenente un solo carattere
  • fgets legge una riga fino a \n, EOF oppure max bytes; attenzione la sintassi è piuttosto diversa da quella del “C”
  • fscanf va usata  con cautela perché presuppone che la riga sia formattata.

Se invece il file è binario vanno usate le funzioni fread() ed fseek() ftell() e rewind():


$buffer=fread($f,80);                 //legge un record
$buffer=fseek($f,80,SEEK_CUR);        //sposta ad un altro record
$pos=ftell($f);                       //restituisce la posizione nel file
rewind($f);                           //riporta la posizione all’inizio

Note:

  • Solo fread restituisce FALSE superando il fine file
  • L’apertura deve essere fatta con l’opzione “rb”
  • L’uso della lettura binaria non è frequente perché esistono funzioni specializzate per la lettura di particolari files binari (GIF,JPG …)

Sebbene tutte queste funzioni, eccetto fseek, restituiscano FALSE se viene superato l’EOF (end of file) è raccomandabile usare sempre la funzione feof() per testare il superamento del fine file:


$ris=feof($f);                        //vero se superato l’EOF

Note:

  • Restituisce TRUE se è stato superato l’EOF, false se non è stato superato.
  • L’EOF viene superato se viene effettuata una lettura sull’ultimo byte del file portando il puntatore oltre la fine file. Quindi se il puntatore è sull’ultimo byte ma non è ancora stato letto l’EOF è falso.  Restituisce un intero che viene usato come puntatore al file

Al termine della lettura è sempre opportuno chiudere il file per liberare risorse. Il file viene comunque chiuso al termine dello script.


$fclose($f);                          //chiude il file

 Ecco un esempio completo:


$f=fopen ("miofile.txt","r");
while(!feof($f)) {
 $buffer=fgets($f,4096);
 echo $buffer;
}
fclose($f);

Funzioni che leggono l’intero file in una unica operazione

  • Lettura in un array file()
  • Lettura in una stringa file_get_contents()
  • Lettura ed emissione su standard output readfile()

Lettura in un array file()
La funzione file() apre il file, legge riga per riga fino al fine file e memorizza ogni riga in un array indicizzato. Il file viene automaticamente chiuso

$vettore=file("miofile.txt");
foreach($vettore as $elemento) {
 echo $elemento;
}

Note:

  • Il nomefile può essere locale o remoto
  • Ogni elemento del vettore è una stringa terminata da \n che può essere rimosso con un trim()
  • Questa funzione è utile quando il file di testo è organizzato su più righe.

Lettura in una stringa file_get_contents()
La funzione file_getcontents() apre il file, legge fino al fine file e memorizza l’intero file in una stringa. Il file viene automaticamente chiuso

$stringa=fileget_contents("miofile.txt");
echo $stringa;

Note:

  • Il nomefile può essere locale o remoto
  • In realtà può essere usata anche per leggere un file binario. Naturalmente in questo i caratteri archiviati nella stringa non hanno il significato di codici ASCII.
  • Esiste da php 4.3

Lettura ed emissione su standard output readfile()

La funzione readfile() apre il file, legge fino al fine file e lo manda sullo standard output memorizza l’intero file in una stringa. Il file viene automaticamente chiuso

readfile("miofile.txt");

Note:

  • Il nomefile può essere locale o remoto
  • Consente di mandare direttamente allo standard output un file già formattato con una unica operazione.

Interpretazione di un file

Esistono alcune funzioni che oltre a leggere un file effettuano alcune operazioni di interpretazione dei dati.

  • Lettura degli ini parse_ini_file(): legge un ini file di tipo windows
  • Lettura dei CSV fgetcvs(): legge un file di tipo Comma Separated Values

Lettura degli ini parse_ini_file()
Gli ini-file sono files di configurazione in formato testo particolarmente usati in ambiente windows. Gli ini-file sono divisi in più sezioni (identificatori racchiusi tra parentesi quadre) e in ogni sezione possono essere inserite più chiavi (identificatore), ad ogni chiave è associato un valore mediante un operatore =.
Qui di seguito è riportato l’ini-file usato dal programma easyphp per configurarsi all’avvio. E’ costituito da tre sezioni ([EasyPhp],[Mysql] e [System]). In ogni sezione sono presenti varie chiavi (AutoStartServers, AutoStartEasyPhp, ...) e ad ogni chiave è associata una stringa che rappresenta il valore di quella chiave (Y,N, ...). Oltre a queste regole non è previsto ne alcun ordine ne alcuna sintassi particolare per un ini-file il cui significato è noto solo al programma che lo utilizza per configurarsi.

[EasyPhp]
AutoStartServers=Y
AutoStartEasyPhp=N
AutoReloadConf=Y
ExpertMode=Y
CheckVersion=N
StartAsServices=N
ShowAlways=N
ExpandPos=1
[MySql]
MySqlArguments=--skip-name-resolve --language=french
Datadir=C:\Programmi\EasyPHP\mysql\data
Basedir=C:\Programmi\EasyPHP\mysql
[System]
Setupdir=C:\Programmi\EasyPHP
Windir=C:\WINDOWS
Systemdir=C:\WINDOWS\System32

La funzione parse_ini_file legge un file di tipo ini e lo memorizza in un array associativo in cui le chiavi dell’array sono le chiavi dell’ini file e i corrispondenti valori i valori associati. E’ anche possibile ottenere un array bidimensionale contente anche i nomi delle sezioni.

$ini_array = parse_ini_file("easyphp.ini");
foreach ($ini_array as $chiave => $valore) {
 echo”$chiave=$valore”;
}

Lettura dei CSV fgetcvs()
Il formato CSV è un formato di registrazione di dati tabulari in forma testuale. Questo formato è ad esempio uno dei possibili formati di salvataggio di una tabelle Excel e di molti gestori di database. Un file CSV è un file di testo formato da una serie di righe tutte formate dallo stesso numero di valori separati da un separatore che in genere è la  virgola ma che può anche essere cambiato.
Nell’esempio seguente viene mostrato un file Excel salvato in formato CSV.

1,2,3,4
5,6,7,8
6,8,10,12

La lettura dei files CSV si effettua aprendo il file in modalità standard library  e leggendo le righe con la funzione fgetcvs che legge tutti gli elementi di una riga e li memorizza in un array indicizzato.

$f = fopen ("test.csv","r");
while (!feof($f)) {
 $dati=fgetcsv($f,1000,",");
 for($i=0;$i<count($dati);$i++) {
  echo”$dati[$i] “;
 }
 echo”<br>”;
}
fclose ($f);

 


6.3 Scrittura di un file

La scrittura dei files segue regole analoghe a quelle della lettura. Anche i questo caso sono possibili sia scritture in stile “C” che per interi files seppure con un minore numero di alternative.

Funzioni di tipo “C standard library”
Come in “C” il file deve essere aperto in scrittura con la funzione fopen():


$f=fopen(“miofile.txt”,”w”); //apre/crea un  file in sola scrittura

Note:

  • Il percorso può essere locale relativo o assoluto oppure remoto
  • Il protocollo http: non consente scritture
  • Altri modi di apertura sono:
  • “r+” apre in lettura e scrittura puntatore all’inizio
  • “a” apre/crea in scrittura puntatore alla fine
  • “a+” apre/crea in lettura e scrittura puntatore alla fine
  • Restituisce un intero che viene usato come puntatore al file
  • Se fallisce restituisce FALSE

Data la natura di PHP non esiste una concreta distinzione tra scrittura di file di testo e binari di conseguenza fputs ed fwrite sono sinonimi:


$scritti=fputs($f,$buffer,4096);           //scrive una riga max 4096 bytes
fscritti=fwrite($f,$buffer,4096);          //legge una riga max 4096 bytes

Note:

  • Tutte le funzioni restituiscono il numero di bytes scritti o –1 se falliscono.
  • Dopo la scrittura  il puntatore al file è incrementato alla posizione successiva
  • Non esiste fprintf che può essere sostituita dalla combinanzione sprintf + fputs

Gli spostamenti nei files binari si fanno comunque con fseek() ftell() e rewind():


$buffer=fseek($f,80,SEEK_CUR);        //sposta ad un altro record
$pos=ftell($f);                       //restituisce la posizione nel file
rewind($f);                           //riporta la posizione all’inizio

Note:

  • L’apertura deve essere fatta con l’opzione “wb”
  • L’uso della scrittura binaria non è frequente perché esistono funzioni specializzate per la scrittura di particolari files binari (GIF,JPG …)

Al termine della scrittura è sempre opportuno chiudere il file per liberare risorse. Il file viene comunque chiuso al termine dello script.


$fclose($f);                          //chiude il file

Mantenendo invece il file aperto si può forzare una scrittura fisica (in genere i sistemi operativi mantengono i dati scritti con fputs/fwrite in  una memoria cache (memoria centrale) e salvano effettivamente in memoria solo alla chiusura o in caso di overflow


$fflush($f);                          //forza la scrittura del file

Ecco un esempio completo:


$v=array(“a”,”b”,”c”,”d”);
$f=fopen ("miofile.txt","w");
for ($i=0;$i<count($v);$i++) {
 $scritti=fputs($f,$v[$i].”\n”,4096);   //aggiunge il caporiga
}
fclose($f);

Funzioni che scrivono l’intero file in una unica operazione

Esiste solo la versione Scrittura di una stringa in un file: file_put_contents()
La funzione file_put_contents() apre il file, scrive il contenuto di una stringa nel file. Il file viene automaticamente chiuso

$stringa=”questa è una stringa\ndi due righe”
$ris=file_put_contents("miofile.txt",$stringa);

Note:

  • Restituisce FALSE se fallisce
  • Si può aggiungere come terzo parametro facoltativo FILE_APPEND per aggiungere dati invece che creare un nuovo file
  • Si può simulare la scrittura di un array in un file facendola precedere da un implode.
  • Può essere usata anche per files binari

Files temporanei

E’ spesso necessario creare files temporanei che devono essere cancellati subito dopo l’uso. Un problema comune in questi casi è la gestione della concorrenza. Se ad esempio due clienti interrogano contemporaneamente lo stesso web-server chiedendo la stessa pagina, il web server che è un programma concorrente avvia due processi che, in apparente contemporaneità ma in realtà dividendosi il tempo di CPU, avanzano facendo la stessa azione per due clienti diversi. Se l’azione prevede l’apertura di un file temporaneo e lo script lo genera con un nome fisso questa azione contemporanea si risolve in una corruzione del risultato o nel blocco dei processi. Per ovviare a questo problema si può usare la funzione di creazione di un file temporaneo che genera un nome univoco ottenendolo da una randomizzazione di sistema. In questo modo due processi di uno stesso script operano su file temporanei di nome diverso. Un file temporano viene automaticamente cancellato al momento della chiusura.

$tmp=tmpfile();                  
fwrite($tmp,”dato temporaneo”);
fclose($tmp);

Note:

  • Il programmatore non conosce né il nome del file né la sua posizione (cartella temp di default del sistema)ma solo il suo puntatore.
  • Se è necessario conoscerne il nome usare invece la funzione tmpnam() con la quale si può ottenere un nome temporaneo valido e fissare la cartella di destinazione; a questo punto però è necessario creare il file con la funzione di standard library fopen() e cancellarlo dopo la chiusura.

Accesso contemporaneo  ai files

Un problema analogo al precedente, sempre determinato dalla esecuzione concorrente di più istanze (copie) dello stesso script, è il caso di accesso contemporaneo ad un file. Se ad esempio le due copie dello stesso script tentano di incrementare il valore di un contatore archiviato in un file il risultato potrebbe essere la corruzione  del suo contenuto. Esiste una funzione di sincronizzazione chiamata flock(). Questa sincronizzazione è di tipo applicativo, cioè si basa sul fatto che tutti i processi prima di accedere al file invochino la funzione flock(). In caso contrario la sincronizzazione fallisce. La flock blocca il processo che la invoca quindi proteggendo una sezione di accesso al fine con una coppia di flock è possibile accedere al file in modo sicuro.
L’esempio seguente mostra l’incremento di un contatore:


$f=fopen(“counter.txt”,”r+”);                  
flock($f,LOCK_EX);
$counter=fgets($f,10);
$counter++;
rewind($f);
fputs($f,$counter);
flock($f,LOCK_UN);
fclose($f);

Note:

  • Il processo si sospende sulla prima flock fino a che non ha accesso esclusivo al file.
  • E’ indispensabile rilasciare il controllo con la seconda flock altrimenti tutti gli altri processi resteranno bloccati

6.6 Manipolazione dei files

Esistono molte funzioni di manipolazione dei files che si basano per la loro esecuzione sulle sottostanti funzioni di sistema operativo. Poiché l’ambiente è multipiattaforma queste funzioni, indipendentemente dal loro nome che talvolta richiama il nome di funzioni unix, lavorano anche sulla piattaforma windows.
Conviene usare queste funzioni per la manipolazione dei files piuttosto che costruire algoritmi basati sulle funzioni di std library.

Copiare un file: copy()
Copia un file in un altro file. Restituisce FALSE se fallisce.


if(!copy(“sorgente.txt”,”destinazione.txt”)) echo(“errore di copiatura”);

Cancellare un file: unlink()
Cancella un file esistente. Restituisce FALSE se fallisce.


if(!unlink(“file.txt”)) echo(“errore di cancellazione”);

Cambiare nome a un file: rename()
Rinomina un file esistente ad un nuovo nome non esistente. Restituisce FALSE se fallisce.


if(!rename(“vecchio.txt”,”nuovo.txt”)) echo(“errore di rinominazione”);

Controllare se un file esiste: file_exists()
Controlla se un file esiste nel percorso specificato nel file system locale. Restituisce TRUE se il file esiste.


if(file_exist(“file.txt”) echo(“il file esiste”);

Controllare la dimensione di un file: filesize()
Restituisce la dimensione in bytes di un file. Restituisce FALSE se fallisce


$size=filesize(“file.txt”);                 
echo(“il file contiene $size bytes”);

Cercare un file con le wildcard: glob()
Cerca nel percorso specificato l’esistenza di un file indicato anche  con le wildcard: *, ?. Restituisce un array contenente l’elenco dei files (o directory) trovati oppure FALSE se fallisce


$elenco=glob(“*.txt”);
foreach($elenco as $nomefile) {
 echo”$nomefile<br>”;
}

Restituisce la  directory corrente: getcwd()
Restituisce la directory corrente (quella a cui ci si può riferire con il percorso ./).


echo getcwd();

Cambiare directory corrente: chdir()
Cambia la directory corrente (quella a cui ci si può riferire con il percorso ./). Restituisce FALSE se fallisce.


if(!chdir(“cartella”)) echo(“errore di cambio cartella);

Creare una directory: mkdir()
Crea una directory (cartella) nel percorso specificato. E’ possibile specificare anche i diritti di accesso significativi solo in ambiente unix (vedi successivo paragrafo). Restituisce FALSE se fallisce.


if(!mkdir(“cartella”)) echo(“errore di creazione);

Cancellare una directory: rmdir()
Cancella una directory (cartella) nel percorso specificato. Restituisce FALSE se fallisce.


if(!rmdir(“cartella”)) echo(“errore di creazione);

Controllare se un percorso è un file: is_file()
Verifica se un percorso specificato corrisponde ad un file Restituisce TRUE se il percorso corrisponde ad un file, FALSE se non esiste o è una cartella.


if(is_file(“file.txt”)) echo(“E’ un file);

Controllare se un percorso è una directory: is_dir()
Verifica se un percorso specificato corrisponde ad una cartella. Restituisce TRUE se il percorso corrisponde ad una cartella, FALSE se non esiste o è un file.


if(is_dir(“cartella”)) echo(“eE’ una cartella);

Rinfrescare le informazioni sui files: clearstacache()
Tutte le informazioni estratte dalle funzioni precedenti non vengono ri-lette ad ogni richiesta ma fanno riferimento ad una immagine di stato che il sistema operativo archivia in una cache di memoria centrale. Se non si vuole correre il rischio di attingere ad informazioni che non sono più aggiornate  è opportuno fare ricaricare le informazioni dal disco.


Clearstatcache();

6.7 Ricerca nelle directory

Le funzioni precedenti formano una gamma completa di strumenti per accedere a files e directory. Tuttavia esiste uno strumento di astrazione superiore che semplifica l’accesso alle directory soprattutto nel caso in cui l’intero contenuto debba essere esaminato.
Si tratta di un oggetto appartenente ad una classe predefinita di nome ‘dir’. Questa classe esibisce le proprietà:

  • path: percorso della directory che è descritta dall’oggetto
  • handle: handle della directory (può essere usato anche con le altre funzioni di manip

e i metodi:

  • read(): legge un nome file dalla directory
  • rewind(): ritorna all’inizio della directory
  • close(): chiude l’oggetto

Il seguente esempio i files contenuti in una cartella


$d=dir(“./”);
while ($nomefile=$d->read()) {
 if (($nomefile!=”.”)&&($nomefile!=”..”)) {
   echo $nomefile."<br>\n";
 }
}
$d->close();

Note:

  • Il ciclo percorre la cartella corrente
  • Estrae iterativamente i nomi dei files
  • Esclude i files . e ..
  • Stampa tutti i nomi
  • Rilascia le risorse

 


Questo secondo esempio, più elaborato, percorre ricorsivamente il file system a partire da una cartella iniziale mostrando il contenuto delle cartelle ed aprendo i documenti. In pratica si comporta come l’explorer di windows.


<?php
if(!isset($p)) $p=".";                      //si parte dalla dir corrente
if ($p!=".") {                              //dir sup solo se non sono in cima
 $s = substr($p,0,strrpos($p, "/"));
?>
<a href="<?php echo"$PHP_SEL?p=$s" ?>">CARTELLA SUPERIORE</a><br>
<?php
}
?>
<?php
$d=dir($p);
while ($e=$d->read()) {                    //cerca le sub-dir    
 if (($e!=".")&&($e!="..")) {              //esclude . e ..
  if (is_dir("$p/$e")) {                   //è una dir rilancia se stessa
?>
<a href="<?php echo"$PHP_SEL?p=$p/$e" ?>"><?php echo $e ?></a><br>
<?php
  }
 }
}
?>
<?php
$d->rewind();                             //re-inizializza oggetto 
while ($e=$d->read()) {                   //cerca i files 
 if (($e!=".")&&($e!="..")) {             //escludi . e ..
  if (is_file("$p/$e")) {                 //è un file apri in un’altra pagina
?>
<a href="<?php echo"$p/$e" ?>" target="_blank"><?php echo $e ?></a><br>
<?php
  }
 }
}
$d->close();
?>

Note:

  • Alla prima invocazione parte dalla cartella corrente (./) che diventa una radice relativa.
  • Il collegamento alla cartella superiore è presente solo se non si è in radice relativa per evitare di uscire dal file system da presentare
  • Il collegamento alla cartella superiore viene costruito dalla cartella corrente tagliando l’ultima parte del percorso
  • L’oggetto directory viene generato a partire dal percorso passato come parametro di ingresso.
  • L’oggetto viene percorso due volte: una prima volta per estrarre le subdir e una seconda volta, dopo un rewind per estrarre i files. Il motivo di questa separazione è che i componenti dell’oggetto sono ordinati per nome ma con dir e file mescolati.
  • Se un componente è una dir viene generato un collegamento allo script stesso con il nome della dir passato come parametro. In questo modo la pagina si aggiorna presentando il contenuto della nuova dir.
  • Se un componente è un file viene generato un collegamento al file in una nuova finestra. In questo modo la pagina di dir resta inalterata e il file si apre in una nuova finestra in sovrapposizione.

 


6.8 Diritti di accesso

Il successo di tutte le operazioni sui files presentate in precedenza è subordinato alla disponibilità di adeguati diritti di accesso ai files e directories coinvolte.
In ambiente locale  di sviluppo (in genere un ambiente mono-utente o comunque un ambiente in cui lo sviluppatore è anche amministratore) non ci sono problemi ad accedere ad un qualunque punto del file-system.
Nell’ambiente operativo invece, che normalmente è un ambiente multiutente, deve essere posta una grande cura nel gestire i diritti di accesso in modo da consentire agli script di funzionare correttamente senza minare la sicurezza del sistema.
Facendo riferimento all’ambiente unix vengono ora richiamati alcuni concetti di base riguardo ai diritti di accesso che dovrebbero essere già noti dai corsi precedenti.
In ambiente unix l’accesso alle risorse è regolato da un sistema costituito da utenti (user) che sono raggruppati in gruppi (group).
Sono utenti l’amministratore (root), tutti gli utenti ‘normali’ (nel nostro caso studenti, professori, tecnici, progetti … con il loro username come belxxxx, peroni, biblioteca), e alcuni ‘agenti’ che sono processi in esecuzione che svolgono servizi (apache, mail, ...).
I gruppi sono raggruppamenti di utenti con caratteristiche comuni. Ad esempio esistono i gruppi ‘users’, ‘prof’,‘3b5’, ... ma esistono anche gruppi speciali come ‘root’ , ‘apache’ e ‘mail’ riservati a contenere utenti speciali. Ogni utente appartiene almeno ad un gruppo (gruppo principale) ma può contemporaneamente appartenere anche ad altri gruppi. L’appartenenza ad altri gruppi consente di condividere risorse con gli altri componenti del gruppo (ad esempio files o cartelle). La definizione degli utenti e il loro raggruppamento in gruppi è prerogativa dell’amministratore (root) che è l’unico che può aggiungere/togliere utenti, aggiungere/togliere/modificare gruppi.
Ciascuna risorsa presente nel file-system appartiene ad un particolare utente (owner) che in genere l’ha generata ma che potrebbe anche averla ottenuta dell’amministratore. Poiché l’owner appartiene ad almeno un gruppo la risorsa è anche associata (non posseduta) ai gruppi a cui l’owner appartiene e di conseguenza agli altri utenti di tali gruppi.
In conclusione per ogni risorsa sono definiti tre livelli di diritti relativi a user, group e other cioè relativi all’utente che possiede la risorsa, agli altri utenti dei gruppi a cui appartiene l’owner e agli utenti degli altri gruppi a cui l’owner non appartiene.
Per ciascun livello sono definiti tre tipi di diritto: lettura (read), scrittura (write) ed esecuzione (execute). Il primo diritto consente di leggere la risorsa (nel caso di un file significa aprirlo, nel caso di una directory significa potere renderla directory corrente), il secondo diritto consente creare, cancellare o modificare la risorsa, il terzo diritto consente eseguire la risorsa (nel caso del file significa che è un programma o uno script che può essere eseguito, nel caso di una directory significa che può essere attraversata per raggiungere una sottodirectory in essa contenuta.
Da queste considerazioni deriva la definizione di diritti di un file/directory in ambiente unix

user

Group

other

r

w

x

r

W

x

r

w

x

Che può essere letta con un comando ‘ls –la’. Ad esempio la situazione:

drwxr-xr-x       nomecartella
-rw-rw-r--       nomefile  

indica che nomecartella è una directory che può essere letta  e percorsa da tutti ma scritta solo dal proprietario, mentre nomefile è un file che può essere letto e scritto dal proprietario e dagli utenti del suo gruppo ma non può essere eseguito.
Un problema tipico che si incontra nello sviluppo di web attivo è che talvolta è necessario che uno script acceda a file e cartelle che appartengono ad uno specifico utente. Lo script quando è in esecuzione non si presenta come l’utente che lo ha sviluppato ma come l’agente che lo sta eseguente; quindi nel nostro caso un script php in esecuzione si presenta come una sequenza di azioni svolte dall’utente ‘apache’. Se questo utente non ha diritti di accesso all’area in cui vuole leggere o scrivere lo script fallisce.
In fase di sviluppo la tecnica di collaudo tipica è di consentire da parte dell’utente diritti completi a tutti sulle risorse in corso di collaudo:

chmod 777 nomerisorsa

Note: il comando di sistema chmod consente al proprietario di modificare i diritti delle sue risorse specificando in ottale lo stato dei nove diritti (777 ottale à 111-111-111 binario quindi tutti i diritti consentiti).
Ma una volta completato il collaudo funzionale il problema dei diritti deve essere affrontato per garantire sicurezza all’intero sistema.
Si può dividere il problema in due categorie: lettura e scrittura. Il caso della lettura è meno grave perché si può sempre consentire la lettura di risorse ad altri a meno che la risorse non contenga informazioni segrete (password o altre dati segreti) oppure non contenga informazioni da proteggere con i diritti di autore (codice sorgente di programmi … ). E’ quindi sufficiente separare le informazioni dei due tipi e proteggere quelle segrete mettendole in una cartella priva di diritti di attraversamento.

chmod 755 nomecartella    à cartelle pubbliche 111-101-101
chmod 644 nomefile        à files pubblici     110-100-100  
chmod 700 nomecartella    à cartelle private   111-000-000
chmod 600 nomefile        à files privati      110-000-000

Nel caso della scrittura la situazione è più complessa perché non si può mai consentire a tutti l’accesso in scrittura d’altra parte è indispensabile che l’agente ‘apache’ sia in grado di scrivere nelle cartelle dedicate alla scrittura da parte degli script che esegue.
Una possibile soluzione è la creazione di un gruppo speciale e l’assegnazione a questo gruppo sia dell’utente proprietario delle cartelle di scrittura che dell’agente apache. Se i diritti delle zone di scrittura sono impostati nel seguente modo:

chmod 770 nomecartella    à cartelle di gruppo 111-111-000
chmod 664 nomefile        à files di gruppo    110-110-000  

Se utente ed agente appartengono allo stesso gruppo lo script può scrivere nelle cartelle.
Mentre i diritti sui files e cartelle sono operazioni a cura dell’utente proprietario le modifiche dei gruppi sono a cura dell’amministratore.

In dettaglio la situazione di presenta così:
Supponiamo che l’amministratore di progetto (utentex) appartenga al gruppo users e che l’agente web (apache) appartenga al gruppo nobody.
Immaginiamo che l’amministratore di sistema generi un nuovo gruppo di nome progettox e di inserire in questo gruppo solo gli utenti utentex ed apache.
Nel file etc/group a cura dell’amministratore di sistema deve essere inserita la riga:

progettox:x:nnnnn:utentex,apache

Le cartelle ed i files generati direttamente dall’amministratore di progetto (utentex) non devono appartenere a utentex:users ma ad utentex:progettox.
Per ottenere questo risultato si possono seguire due strade:
Cambiare il gruppo dell’utente prima di generare files o cartelle con il comando di shell newgrp progettox e poi generare files e cartelle che nascono già come utentex:progettox

  • Generare normalmente files e cartelle che quindi nascono di proprietà di utentex:users e poi cambiare il gruppo dei files interessati con il comando di shell

chggrp progettox nomefile 

Lo script eseguito dall’agente si ritiene eseguito da apache:apache quindi lo script può cambiare ad apache:progettox. Questa azione dovrebbe essere possibile sia con funzioni built-in di php:


<?php
$grpinfo= posix_getgrnam (“progettox”);
$ris=posix_setpgid(posix_getpid(),$grpinfo[‘gid’]);
?>

sia invocando il comando con una exec (vedi paragrafo successivo):

<?php
 $ris=exec(“newgrp progettox”);
?>

Ora l’agente (apache) appartiene allo stesso gruppo dell’utente proprietario di files e cartelle in cui si vuole creare/modificare/cancellare. Se il proprietario ha concesso tali diritti al gruppo l’agente può accedere in creazione/modifica/cancellazione. Anche l’agente deve però mantere i diritti di gruppo sui file/cartelle su cui opera in modo che l’utente conservi la possibilità di agire manualmente. Non è noto a priori lo schema di default di generazione dei diritti di apache quindi lo script lo deve modificare temporaneamente prima di qualsiasi accesso con la funzione umask(). Se invocata da uno script la modifica è attiva solo per la durata dello script.
La funzione umask()  opera in logica negativa (0 à abilita, 1 à disabilita) quindi per regolare ii  diritti di scrittura di gruppo si devono generare le seguenti umask:

  • Cartelle pubbliche:        rwxrwxr--     umask(0003);
  • Cartelle private:           rwxrwx---     umask(0007);
  • Files pubblici:               rw-rw-r--      umask(0113);
  • Files privati                  rw-rw----      umask(0117);

Note:
Lo zero più significativo è indispensabile in php per generare un numero ottale altrimenti nel secondo e terzo caso sarebbe interpretato come decimale.

L’utente è bene che invochi manualmente (o con uno script) il corrispondente  comando umask xxxx prima di modificare files o cartelle perché l’impostazione di default (contenuta nel file .login) potrebbe essere diversa da quella necessaria in questa particolare manutenzione. Se ci fosse il diritto di scrittura  di gruppo tale diritto  verrebbe assegnato a files o cartelle generate dall’utente quando opera come membro del gruppo principale (users nell esempio) consentendo ad altri utenti dello stesso gruppo di modificare i propri files.

 


6.9 Esecuzione comandi

E’ possibile eseguire comandi, cioè programmi nella shell del sistema operativo che ospita l’ambiente di web attivo. Il motivo può essere l’utilizzo di programmi di sistema (in genere comandi di manutenzione, ma qualunque comando su cui l’agente abbia diritto di esecuzione può essere invocato) oppure programmi applicativi. Data la grande versatilità dell’ambiente PHP in realtà non esiste nulla che non si possa fare internamente con uno script. Il vantaggio di questa tecnica è che le prestazioni di tali programmi che in genere sono compilati sono superiori a quelle di PHP che è interpretato. Lo svantaggio, da non trascurare è che si perde la portabilità tra diversi sistemi operativi. Infatti i comandi sono sicuramente diversi tra linux e windows e anche le applicazioni sviluppate, anche se progettate in modo portabile (console application C++ con librerie standard) devono essere ricompilati.
Le principali funzioni sono:

Esecuzione di un programma esterno con  output system()
Esegue il comando specificato e manda i risultati verso l’output standard (attenzione se non redirezionati vanno direttamente al browser senza altre interpretazioni) In uscita fornisce una stringa contenente l’ultima riga di output.


<?php
 $ris=system(“mioprogramma par1 par2”,&$codice);
?>

Note:

  • La chiamata di sistema esegue un programma applicativo (console application che si aspetta due parametri passati sulla linea di comando.
  • L’output del programma va direttamente all’output standard quindi si presume che sia un output valido per il browser (In genere tag html ma potrebbero essere anche altri formati come quelli grafici se preceduti da un opportuno header http)
  • Il programma terminando restituisce un codice di terminazione che può essere letto nella variabile $codice
  • $ris contiene l’ultima riga di output del programma che in genere fornisce anch’essa informazioni sullo stato del programma.

Esecuzione di un programma esterno senza output exec()
Esegue il comando specificato senza mandare i risultati verso l’output. Opzionalmente è possibile specificare un array in cui vengono inserite tutte le righe di output In uscita fornisce una stringa contenente l’ultima riga di output.


<?php
 $ris=exec(“cd ..”);
 $ris=exec(“ls –la”,&$elenco);
?>

Note:

  • La prima invocazione sposta la directory corrente al livello superiore
  • La seconda invocazione deposita nell’array $elenco la lista dei files contenuti (un file per ogni elemento di array)

Esecuzione di un comando di shell
Non si tratta di una vera e propria funzione ma di una sintassi di PHP che viene interpretata come esecuzione di un comando di shell. Si assegna ad una variabile una stringa contenente il comando e delimitata da una coppia di caratteri backtick `comando`(attenzione non è la singola quota ma il carattere di codice 0x60 che si genera con la sequenza ALT+9+6). Il comando contenuto nella stringa viene eseguito dalla shell corrente e il risultato mandato nella variabile di destinazione.


<?php
 $elenco=`ls –la`;
?>

Note:

  • Equivale al caso precedente ma il risultato va in una stringa invece che in un array.

6.10 Contatore di visite

Un esempio di utilizzo dei files in lettura e scrittura è la realizzazione di un contatore di visite. Ogni volta che un sito  viene visitato il contatore deve essere incrementato, quindi normalmente il contatore viene visualizzato nella home page, ma non è detto che il conteggio sia effettuato solo dalla home page. Il valore di stato del conteggio deve essere archiviato in modo permanente sul server, quindi la soluzione migliore è un file (in questo caso non vanno bene ne cookies ne session che sono client-side).
Gli script devono avere accesso in scrittura al file che può essere di testo e contenere il numero di visite corrente. Ogni volta che una pagina abilitata al conteggio viene lanciata uno script invocato da essa apre il file in modo esclusivo (vedi paragrafo sulla concorrenza), legge il valore del contatore, lo incrementa e lo riscrive. Se la pagina ha anche il compito di mostrare il contatore, realizza una presentazione che può essere sia grafica che testuale.

Script di conteggio con visualizzazione testuale:

<?
$f=fopen(“counter.txt”,”r+”);                  
flock($f,LOCK_EX);
$counter=fgets($f,10);
$counter++;
echo”Visitatori: $counter”;
rewind($f);
fputs($f,$counter);
flock($f,LOCK_UN);
fclose($f);
?>

Note:

  • Una pagina che debba solo contare senza visualizzare non contiene l’istruzione di output
  • E’ opportuno prevedere vie di eccezione per l’assenza del file e per la mancanza di un dato numerico.
  • In un successivo capitolo saranno mostrate soluzioni grafiche. Il vantaggio di una soluzione grafica è che non deve per forza essere inserita in una pagina attiva ma può diventare una tag <img> di una pagina statica.

 

 

Fonte: http://www.itis.pr.it/~dsacco/itis/5B/php/LEZIONI/file-php.doc

Sito web da visitare: http://www.itis.pr.it/~dsacco/

Autore del testo: non indicato nel documento di origine

Il testo è di proprietà dei rispettivi autori che ringraziamo per l'opportunità che ci danno di far conoscere gratuitamente i loro testi per finalità illustrative e didattiche. Se siete gli autori del testo e siete interessati a richiedere la rimozione del testo o l'inserimento di altre informazioni inviateci un e-mail dopo le opportune verifiche soddisferemo la vostra richiesta nel più breve tempo possibile.

 

Funzioni php di base files

 

 

I riassunti , gli appunti i testi contenuti nel nostro sito sono messi a disposizione gratuitamente con finalità illustrative didattiche, scientifiche, a carattere sociale, civile e culturale a tutti i possibili interessati secondo il concetto del fair use e con l' obiettivo del rispetto della direttiva europea 2001/29/CE e dell' art. 70 della legge 633/1941 sul diritto d'autore

Le informazioni di medicina e salute contenute nel sito sono di natura generale ed a scopo puramente divulgativo e per questo motivo non possono sostituire in alcun caso il consiglio di un medico (ovvero un soggetto abilitato legalmente alla professione).

 

Funzioni php di base files

 

"Ciò che sappiamo è una goccia, ciò che ignoriamo un oceano!" Isaac Newton. Essendo impossibile tenere a mente l'enorme quantità di informazioni, l'importante è sapere dove ritrovare l'informazione quando questa serve. U. Eco

www.riassuntini.com dove ritrovare l'informazione quando questa serve

 

Argomenti

Termini d' uso, cookies e privacy

Contatti

Cerca nel sito

 

 

Funzioni php di base files