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).
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:
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:
l’indicazione cartella corrente (più portabile)
a quella dello script
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:
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 |
Note:
Definizione del corpo di funzioni:
<?php //script principale require(“./funzioni.inc”); $c=somma(1,1); echo $c; ?> |
|
<?php //file funzioni.inc |
Note:
Inclusione diretta di tag html:
<?php //script principale require(“./instestazione.html”); ... ?> |
|
<!—file intestazione.html --> |
Note:
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”
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:
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:
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:
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:
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()
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"); |
Note:
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"); |
Note:
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:
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()
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] |
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"); |
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 |
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"); |
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:
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:
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:
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” |
Note:
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(); |
Note:
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:
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à:
e i metodi:
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:
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:
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 |
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 |
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 |
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
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 |
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:
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:
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:
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:
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:
<? |
Note:
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.
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).
"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