fire.gif

LE FUNZIONI DI PHP3
Per completare l'esame delle funzioni di base di php3, presentiamo in questo articolo i comandi per controllare il flusso dello script e le istruzioni per il trattamento di stringhe e file
I costrutti if, else ed elseif rappresentano gli elementi fondamentali per la costruzione delle espressioni condizionali. Usandoli nel programma potremo forzare l'esecuzione di una o più righe di codice in base al risultato booleano di una certa espressione. In realtà php3, come il Perl, non possiede un tipo di variabile booleano dedicato esclusivamente alla verifica delle condizioni. Infatti qualsiasi espressione che restituisca il numero zero, le stringhe vuote o "0" oppure un array senza elementi è considerata falsa. Tutte le altre espressioni, invece, sono vere. Fatta questa premessa passiamo alla presentazione delle funzioni di controllo.
linea.gif
IF, ELSE, ELSEIF e SWITCH
Oltre all'uso classico che si può fare di questi costrutti, esemplificato come segue,

$a = 1; $b = 2;
if ($a > $b) { 
    print " a è maggiore di b"; 
} else { 
    print "a non è maggiore di b"; 
}
$a = 2; $b = 1;
if ($a > $b) {
    print " a è maggiore di b";
} elseif ($a == $b) {
    print "a è uguale a b";
} else {
    print "a è minore di b";
}

li possiamo usare adottando anche una sintassi un po' particolare, utile per innestare blocchi di puro codice html, come nell' esempio seguente

<?php
  $a = 2; $b = 1;
  if ($a > $b):
?>
a è maggiore di b
<?php elseif ($a == $b): ?> {
a è uguale a b
<?php  else: ?>
a è minore di b
<?php endif; ?>

Vi sarete accorti che è stato utilizzato uno statment insolito come if(): istruzioni; endif; Ricordiamo per completezza di esposizione che il codice preceduto da else viene eseguito se la condizione verifica dall'if è falsa, mentre la porzione di script preceduta da elseif viene eseguita se le due condizioni valutate dall'if, prima, e dallo stesso endif, dopo, sono rispettivamente false e vere. Infine vediamo come l'analisi di più espressioni condizionali di uguaglianza possa essere fatta con il costrutto switch()

$i = 1;
switch ($i) {
  case 0:
        print "i è uguale a 0";
  case 1:
        print "i è uguale a 1";
  case 2:
        print "i è uguale a 2";
}

Nell' esempio, anche se la variabile $i vale 1, php eseguirà le ultime due istruzioni print. Per evitare quindi risultati imprevisti occorre usare la clausola break eventualmente accompagnata dall'opzione default (default viene eseguita se nessuno dei "case" precedenti riscontra l'espressione di switch).

$i = 1;
switch ($i) {
  case 0:
        print "i è uguale a 0";
        break;
  case 1:
        print "i è uguale a 1";
        break;
  case 2:
        print "i è uguale a 2";
        break;
  default:
         print "i non è uguale a 0, 1 o 2";
}

Lo script precedente dimostra che se $i vale 1, verrà stampata soltanto la frase "i è uguale a 1", mentre se $i vale 3 verrà eseguita solo l'ultima istruzione. Da ricordare che nell' espressione valutata da switch si possono usare solo valori scalari
linea.gif
FOR, WHILE e DO WHILE
La sintassi del ciclo for

for(expr1; expr2; expr3) { istruzioni; }

è identica a quella di altri linguaggi di programmazione, primo fra tutti il C. L'espressione expr1 viene eseguita sempre soltanto una volta all'inizio del ciclo e serve per inizializzarne il contatore. La seconda condizione expr2, invece, viene valutata all'inizio di ogni iterazione. Se la verifica ritorna vero il loop continuerà con una nuova esecuzione del blocco di istruzioni, altrimenti verrà interrotto. Possiamo creare anche loop infiniti omettendo la scrittura dell'espressione centrale expr2 poiché in tal caso sarà sempre vera. Questi esempi produrranno tutti lo stesso risultato: la stampa dei numeri da 1 a 10.


for ($i = 1; $i <= 10; $i++) {
  print $i;
}

for ($i = 1;;$i++) {
  if ($i > 10) {
    break;
  }
  print $i;
}

$i = 1;
for (;;) {
  if ($i > 10) {
    break;
  }
  print $i;
  $i++;
}

Se volessimo riscrivere gli esempi precedenti, adottando il ciclo while, dovremmo usare una delle due scritture

while(expr) { istruzioni;}
while(expr): istruzioni; endwhile;

ovvero


$i = 1;
while ($i <= 10) {
  print $i++;
}

$i = 1;
while ($i <= 10):
  print $i;
  $i++;
endwhile;

L'aspetto particolare di while è da ricercare nella valutazione l'espressione condizionale. Se questa viene valutata subito falsa non verrà eseguita alcuna istruzione, al contrario del ciclo do-while. Infatti in do while, la condizione viene verificata alla fine di ogni iterazione, e quindi anche se fosse subito falsa il gruppo di istruzioni verrebbe eseguito almeno una volta come nell'esempio seguente

$i = 0;
do {
    print $i;
} while ($i > 0);

Anche in while e do while si può usare lo statment break per interrompere il loop, ignorando il valore dell'espressione.
linea.gif
STRINGHE E FILE
In php3 esistono numerose funzioni per il trattamento delle stringhe. Riassumiamo le più usate in questa tabella ricordando prima la nomenclatura adottata nel manuale di php per presentarle

tipo_restituito nome_funzione(tipo parametro, ...);

Attenzione ai parametri racchiusi fra parentesi quadre: sono opzionali. Ecco l'elenco:

string crypt(string str, string [salt]);
Cripta una stringa usando l'algoritmo DES standard. Alla funzione viene passata la stringa da criptare più un secondo argomento (opzionale) costituito da due caratteri scelti a caso. Se il parametro slat non viene usato sarà php ad impostarlo per conto nostro.

echo crypt("segreta", "pw"); // stampa la password "segreta" criptata
array explode(string separator, string str);
Restituisce un array di stringhe composto dagli elementi della stringa str separati dal/i carattere/i separatore/i

$a = explode(" ", "a b c d e");
/* $a ha 5 elementi
$a[0]="a"
$a[1]="b" */
string implode(array pieces, string glue);
E' il contrario di explode(). Quindi restituisce una stringa costituita dagli elementi dell'array uniti da una stringa scelta a piacere

echo implode("$a", " "); // stampa "a b c d e"
array split(string pattern, string string, int [limit]);
Simile a explode()

$a = "a:b:c:d:e";
$b = split( ":", $a, 3);
/* $b ha 3 elementi
$b[0]="a"
$b[1]="b"
$b[2]="c" */
int strcmp(string str1, string str2);
Compara lessicograficamente due stringhe. Ritorna: un valore minore di zero se str1 è minore di str2 zero se str1 e str2 sono uguali un valore maggiore di zero se str1 è maggiore di str2

int strlen(string str);
Restituisce il numero di caratteri di una stringa

echo strlen("abc"); // stampa 3
string strstr(string haystack, string needle);
Trova la prima occorrenza di una stringa in un'altra

<?php
  if(strstr($HTTP_USER_AGENT, "Mozilla")) {
    echo "Stai usando Netscape";
  }
  if(strstr($HTTP_USER_AGENT, "MSIE")) {
    echo "Stai usando Internet Explorer";
  }
?>
string strtolower(string str);
Converte in minuscolo tutti i caratteri di una stringa

echo strtolower("abc"); // stampa ABC
string strtoupper(string str);
Converte in maiuscolo tutti i caratteri di una stringa

echo strtoupper("ABC"); // stampa abc
string substr(string str, int start, int [length]);
Ritorna una porzione di stringa

echo substr("abcdef", 1); // stampa bcdef
echo substr("abcdef", 3, 2); // stampa de
echo substr("abcdef", -1); // stampa f
echo substr("abcdef", -3, 2); // stampa cb
string trim(string str);
Restituisce la stessa stringa passata alla funzione ma depurata di tutti i caratteri blank (spazi, tab, ritorni a capo)

echo trim("a b	c\n"); // stampa abc

Passiamo al prossimo argomento. Per accedere ai files presenti nel disco del nostro server Linux si usa la funzione

int fopen(string filename, string mode);

che ritorna un puntatore al file da aprire. L'opzione "mode" può avere i seguenti valori e serve per specificare la modalità di accesso

'r'Apre il file in lettura
'r+'Apre il file in lettura e scrittura
'w'Apre il file in scrittura. Se il file esiste viene troncato altrimenti viene creato
'w+'Apre il file in lettura e scrittura. Se il file esiste viene troncato altrimenti viene creato
'a'Apre il file in scrittura e sposta il puntatore interno alla fine del file. Se il file non esiste viene creato
'a+'Apre il file in lettura e scrittura e sposta il puntatore interno alla fine del file. Se il file non esiste viene creato

Da notare che con la funzione fopen possiamo aprire anche risorse ipertestuali usando come nome del file l'URL completo della risorsa. Se da un lato la lettura del contenuto di un file, a partire dalla posizione del puntatore interno, può essere ottenuta con questi comandi

string fgetc(int fp);Legge un carattere da una riga del file
string fgets(int fp, int length);Legge una riga del file
string fgetss(int fp, int length);Legge una riga del file eliminando eventuali tag html
array file(string filename);Legge il file e ne restituisce l'intero contenuto in un array. Gli elementi dell'array sono le righe del file comprensive di ritorno a capo
int readfile(string filename);Legge il file e ne scrive il contenuto sullo standard output

la scrittura, dall'altro, è permessa dalla seguente funzione

int fputs(int fp, string str, int [length]);

Il parametro "fp" delle funzioni non è altro che il puntatore al file restituito da fopen(). Ricordiamo inoltre che dopo una sessione di lavoro con un file aperto conviene usare la funzione fclose() per chiuderlo e rendere così disponibile il puntatore per altre operazioni. Vediamo alcuni esempi


<?php
  $fp = fopen("/etc/passwd", "r");
  while(! feof($fp)) {
    echo fgetc($fp);
  }
  fclose($fp);
  // stampa il contenuto del file /etc/passwd
?>

<?php
  readfile("http://localhost/");
  // visualizza l'home page del server web
?>

<?php
  $fp = fopen("ftp://user:password@localhost/home/user/prova.txt", "w");
  $i = 1;
  while($i <= 10) {
    fputs($fp, $i++);
  }
  fclose($fp);
  /* scrive via ftp il file prova.txt
  ovviamente al posto di user e password
  scriveremo il nome e la password di un
  account ftp del server */
?>

Si noti nel primo esempio l'uso della funzione feof() con cui si verifica il raggiungimento della fine del file. In tal caso feof() restituirà il valore booleano vero. Vediamo infine come si possa usare un'altra funzione, anch'essa appartenente a numeroso gruppo dei comandi di accesso al filesystem di Linux, per eseguire i comandi del sistema operativo. La funzione oggetto della nostra attenzione è

int popen(string command, string mode);

la quale apre una pipe al processo del comando di sistema.


<? php
  $pipe = popen("/bin/ps", "r");
  while(! feof($pipe)) {
    echo fgets($pipe, 5);
  }
  pclose($pipe);
  // stampa i processi attivi 
?>

Forse però il metodo più immediato per lanciare comandi Linux consiste nell'uso di queste funzioni

string exec(string command, string [array], int [return_var]);
string system(string command, int [return_var]);

La prima, exec(), se usata senza i parametri opzionali, restituisce solo l'ultima riga dell'output del comando di sistema. Se invece si usa il secondo parametro allora si può inviare tutto l'output del comando in un array per poi leggerne il contenuto. Possiamo altresì catturare in una variabile lo stato di esecuzione del comando e verificarne così l'esatta esecuzione. Quest'ultima proprietà vale sostanzialmente anche per la funzione system() con la differenza che essa stampa direttamente il risultato del comando anziché restituirlo. Concludiamo con un beve appunto. Se i comandi di accesso ai files dovessero generare degli errori insoliti, oltrea a controllare la completa correttezza del codice dello script php3, dovremmo verificare che tali files possano essere letti o scritti dal processo in cui è eseguito il server web. In altre parole, dovremmo assicurarci che i permessi del file consentano il tipo di accesso desiderato all'utente proprietario del processo del demone httpd (in generale lo user "nobody") o al limite che il file sia di sua proprietà.

fire.gif

Data creazione HTML: Gennaio 2000
Autore: Francesco Munaretto
E-mail: NoSpam@thank.you
exclaim.gif