Lezione Precedente Elenco Lezioni Lezione Successiva

Laboratorio di Sistemi Informativi

Introduzione a PHP

La prima pagina PHP

La lezione scorsa abbiamo visto come inserire un pagina HTML nel nostro spazio riservato per le pagine web. Consideriamo adesso una pagina in PHP:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Prova PHP</title>
</head>
<body>
<?php
echo "Ciao sono Gianluca";
?>
</body>
</html>

Come vedete, una pagina PHP è essenzialmente un pagina HTML, nella quale è possibile inserire il tag speciale

<?php ..... ?>

All'interno di questo tag si può includere il vero e proprio codice in PHP. Nel nostro caso, abbiamo inserito un piccolissimo programma che semplicemente utilizza il comando echo. Il comando echo è l'analogo della System.out.print di Java: stampa la stringa (o qualunque altro dato) gli venga passato come argomento. In questo caso stampa la stringa "Ciao sono Gianluca".

Ma cosa vuol dire "stampare" all'interno di una pagina HTML/PHP? Quando al server web viene richiesta una pagina PHP, lui carica la pagina eliminando tutto cio è che compreso tra <?php e ?>. Questa parte eliminata viene eseguita dall'interprete PHP e tutto quello che viene stampato durante l'esecuzione del codice viene reinserito al suo posto all'interno della pagina. Il tutto è (dovrebbe essere) chiarificato dal seguente schema:

Elaborazione codice PHP

Se la memorizziamo col nome prova.php e vi accediamo all'indirizzo http://<nomeserver>/~<nomeutente>/prova.php otteniamo lo stesso risultato della pagina HTML vista nella lezione precedente.  Se andiamo a vedere il sorgente HTML dal browser notiamo che tutto il codice PHP è sparito ed è stato rimpiazzato dal suo output!!

Il browser (Firefox, Internet Explorer, Opera, etc..) non è mai a diretto contatto con il codice PHP. Quest'ultimo viene interpretato dal server Web che trasferisce al browser solo il risultato dell'esecuzione. In questo il PHP differisce fondamentalmente da Javascript che, al contrario, viene interpretato direttamente dal browser e non viene assolutamente toccato dal server web!

Una conseguenza della nota di cui sopra è che, mentre è possibile visualizzare una pagina locale anche senza avere un server web installato, questo non è possibile per le pagine in PHP. Ad esempio, cliccando sul menù File → Open File di Firefox si può visualizzare una pagina HTML locale. Se si specifica la pagina prova.html (cosa equivalente a mettere l'indirizzo file:///home/<nomeutente>/public_html/prova.html) si ha esattamente lo stesso risultato di quando si accede alla pagina tramite il server web. Ma se si carica direttamente la pagina PHP (ovvero si fornisce l'indirizzo file:///home/<nomeutente>/public_html/prova.php) il codice PHP verrà considerato un commento e non verrà nè eseguito nè visualizzato, col risultato di avere una pagina vuota. Questo perché, quando si usa il protocollo file come URL, il browser va a cercarsi il file da visualizzare direttamente dal disco locale, senza passare dal server web.

In aula informatizzata, la URL per l'accesso locale è file:///home/LABECONOMIA/<nomeutente>/public_html/prova.php.

Una pagina PHP deve assolutamente essere salvata con l'estensione php. Se per caso la si salva con estensione html, il codice PHP non verrà eseguito ma arriverà intatto al browser che, come già detto, lo considererà alla stregua di un commento.

La seconda pagina PHP

Il grande vantaggio di poter usare un linguaggio come PHP all'interno di una pagina HTML è che la pagina può essere resa dinamica! Mentre prova.php genera sempre lo stesso risultato ogni volta che viene visualizzata, è possibile modificarla leggermente per ottenere una pagina che è sempre "nuova".

Consideriamo il seguente codice:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Prova PHP 2</title>
</head>
<body>
<?php
echo "Sono le ore: ",time();
?>
</body>
</html>

Oltre al comando echo adesso abbiamo utilizzato la funzione time() che restituisce il numero di secondi trascorsi dal 1 gennaio 1970.  Ogni volta che viene ricaricata la pagina, viene visualizzato un numero differente!

Il linguaggio PHP

Una documentazione completa del linguaggio PHP si può trovare all'indirizzo http://www.php.net/docs.php in varie lingue (tra cui l'italiano, anche se è solo parzialmente tradotto). È comunque consigliabile usare la versione in inglese, perché è quella sviluppata per prima, per cui si è più sicuri che sia aggiornata.

Una introduzione al linguaggio PHP si trova invece nel libro di testo consigliato. Fondamentalmente, PHP è molto simile ai linguaggi C/C++ e Java. Gli assegnamenti, le espressioni, gli operatori aritmetico/logici e i comandi if, for, while, do ... while, break, continue e switch si usano esattamente allo stesso modo. Le differenze principali sono invece le seguenti:

Commenti

I commenti si possono specificare in questi tre stili:

// Questo è un commento di una linea

# Altra forma per un commento di una linea

/*  Questo è per
    commenti che si estendono
    su più linee */

È possibile quindi scrivere commenti che si prolungano fino alla fine della linea usando la doppia barra o il cancelletto #. Si può invece racchiudere un commento lungo tra /* e */.

Variabili 

Tutte le variabili vanno indicate con un $ iniziale seguito dal nome della variabile. Ad esempio $i, $ks7x, $variabile sono tutti esempi di variabili. Le variabili possono essere usate senza essere dichiarate. Inoltre, le variabili non hanno un tipo ben definito, e possono essere usate con tipi diversi in istruzioni diverse. Ad esempio

$x=1;
$x="prova";

è una sequenza di instruzioni perfettamente valida.

Tipi di dato

PHP ha vari tipi di base, tra cui i più comuni sono: bool, float, integer e string e null.
Stringhe (racchiuse tra virgolette)
I valori di tipo stringa richiedono un po' di attenzione, in particolare quelli racchiusi tra virgolette. Infatti, il PHP fa tutta una serie di sostituzioni all'interno di questo tipo di stringhe. Ad esempio, alcune sequenze di caratteri vengono rimpiazzate con altre:
Così, la stringa "questa \"stringa\"\nchissà \x7eche vuol dire" rappresenta in realtà il valore

questa "stringa"
chissà ~che vuol dire

La caratteristica però più interessante delle stringhe in PHP è che i nomi di variabili vengono rimpiazzati con il loro valore.  Ad esempio:

$cm=127;
$inch=$cm/2.54;
echo "$cm centimetri sono $inch pollici";

stampa su video

127 centimetri sono 50 pollici

Quando il nome della variabile potrebbe essere ambiguo, si può includere il nome tra parentesi graffe. Ad esempio:

$memory=256;
$message="My computer has $memoryMegaBytes of RAM"

non funziona, perchè non esiste nessua variabile che si chiama $memoryMegaBytes. Allora, o si mette uno spazio tra memory e MegaBytes (che però viene poi inserito nella stringa), oppure usare gli apici in questo modo

$message="My computer has ${memory}MegaBytes of RAM"

o in questo

$message="My computer has {$memory}MegaBytes of RAM"
Stringhe (racchiuse tra apici)
Nelle stringhe delimitate da apici tutte queste sostituzioni non avvengono. Le uniche possibili sono due:
che sono necessarie per poter inserire degli apici dentro una stringa delimitata da apici.
Il tipo NULL

Il valore/tipo NULL viene utilizzato spesso per indicare situazioni di errore, in maniera simile a come di usa il valore null in Java. Una particolarità di PHP è che se si usa una variabile senza averle mai assegnato alcun valore, essa conterrà proprio NULL. In realtà l'accesso in lettura ad una variabile mai assegnata molto probabilmente genererà anche una segnalazione di errore, ma questo lo vedremo dopo.

Notare che se provo a visualizzare con echo il valore NULL, ottengo solo una stringa vuota. Devo utilizzare la funzione var_dump (che vedremo più in dettaglio tra poco) invece di echo:

<?php
 $x = NULL;
 echo $x;        // visualizza una stringa vuota
 echo "<br>"; 
 var_dump ($x);  // visualizza NULL
?>

Un problema simile si verifica con i booleani. Il comando echo visualizza false come stringa vuota e true come 1. Anche in questo caso si può usare var_dump per avere un output più chiaro.

Conversioni di tipo
Il PHP esegue tutta una serie di conversioni automatiche di tipo. Trattare in dettaglio queste conversioni sarebbe lungo e noioso, per cui si rimanda al manuale di PHP, dove queste informazioni possono essere consultate quando servono. Facciamo solo un esempio:
$foo = "0"; // $foo è una stringa (ASCII 48)
$foo += 2; // $foo è ora un intero (2)
$foo = $foo + 1.3; // $foo è ora un float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo è intero (15)

Notare in particolare le conversioni tra stringhe e interi, che raramente vengono eseguite automaticamente in linguaggi di programmazione tradizionali tipo C e Java.

Un'altra conseguenza di queste conversioni di tipo è che alcuni confronti, che in apparenza dovrebbero restituire il valore false, in realtà restituiscono true. Ad esempio:

if (0 == null) echo "a";

stampa la stringa a, perchè il valore null viene automaticamente convertito nell'intero 0. Onde evitare questi problemi, quando i tipi di dato in un confronto potrebbero non essere uguali, si può usare per l'uguaglianza l'operatore === (con 3 simboli uguali). v1 === v2 è true se v1 e v2 hanno stesso tipo e stesso valore. Allora:

if (0 === null) echo "a";

non visualizza nulla.

Funzioni

Il PHP mette ha disposizione una ENORME collezione di funzioni, adatte ai compiti più svariati. Una funzione è qualcosa di molto simile ad un metodo statico del linguaggio Java, ovvero è un blocco di codice a cui si possono passare dei parametri, effettua una qualche elaborazione, restituisce un risultato. La differenza fondamentale tra le funzioni in PHP e i metodi statici in Java è che quest'ultimi "vivono" all'interno di una classe, mentre i primi "vivono" al di fuori.

Supponiamo, ad esempio, di voler calcolare la radice quadrata di un numero. In Java esiste il metodo statico sqrt della classe Math, per cui l'espressione x=Math.sqrt(y) mette in x la radice quadrata del valore presente nella variabile y. Il PHP dispone della funzione sqrt che è analoga al metodo sqrt di Java, ma si usa senza specifica nessuna classe. L'espressione di prima diventa $x=sqrt($y).

Vediamo adesso alcune delle funzioni che ci risulteranno più utili.

Operatori e funzioni su stringhe
PHP ha una libreria ENORME di funzioni su stringhe. Basta andare nel manuale di riferimento e consultare la sezione sulle funzioni stringa per avere un elenco di tutte le funzioni di manipolazione di stringhe. Qui citiamo solo le due che, per il momento, ci interessano maggiormente:

Nota! Per indicare che strlen prende in input un valore di tipo stringa e resituisce un intero scriveremo

int strlen(string $str)

Il nome $str è inventato, non ha quindi nessuna importanza. Di solito scegliamo un nome che in qualche modo ricordi il significato di quel determinato argomento. Ad esempio, una funzione che prende in input due interi e restituisce il primo diviso il secondo, restituendo il risultato in virgola mobile, si potrebbe riassumere con

float division(int $dividendo, int $divisore)

Ricordatevi che si tratta solo di un modo per commentare la maniera corretta con cui va usata la funzione. I tipi non vanno scritti nè al momento della chiamata (ovvero si scrive $x=strlen("pippo"), e non $x=int strlen(string "pippo") ) e neanche al momento della definizione della funzione (vedi comando function più sotto).


Funzioni di riconiscimento di tipo
Concludiamo con alcune funzioni di carattere generale sui tipi. Il fatto che in PHP le variabili non vengano dichiarate può portare talvolta a non sapere se una certa variabile è stata mai settata oppure no, o a non sapere qual è il tipo di una variabile in un determinato punto. Ci sono pertanto una serie di funzioni che consentono di scoprire questi fatti:
Funzioni definite dall'utente
Il PHP consente di definire delle funzioni, esattame come il Java consente di definire nuove classi e, al loro interno, nuovi metodi statici. Ad esempio:
function foo ($arg_1, $arg_2, ..., $arg_n)
{
echo "Example function.\n";
...
return $retval;
}
La funzione foo sopra definita accetta n argomenti. Questi argomenti possono essere acceduti da dentro la funzione con i nomi $arg_1, ... $arg_n. Alla fine, il risultato restituito dalla funzione è il parametro del comando return ($retval in questo caso). Il passaggio dei parametri è per valore: eventuali modifiche ai parametri $arg_1, ... $arg_n non si riflettono delle variabili corrispondenti nella chiamata di funzione.

Come ulteriore esempio, si consideri il seguente programma che usa una funzione ricorsiva per il calcolo del fattoriale (si ricordi che il fattoriale di n è il prodotto dei numeri da 1 a n)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Esempio di funzione</title>
</head>
<body>
<?php

function factorial($n)
{
   if ($n==0)
     return 1;
   else
     return $n * factorial($n-1);
}

$x=5;
echo "Il fattoriale di $x e` ",factorial($x);
?>

</body>
</html>
L'output di questo programma è:

Il fattoriale di 5 e` 120

Array

Gli array in PHP sono molto diversi dagli analoghi in Java o C++. Piuttosto che di veri e propri vettori, si tratta più che altro di "dizionari", ovvero di strutture dati che consentono di collegare a una chiave un determinato valore. Le chiavi possono essere o interi o stringhe, mentre i valori possono essere di un tipo qualunqe. Per comodità di esposizione distingueremo tra array numerici ed associativi, a seconda che le chiavi siano interi o stringhe.
Array numerici
Un esempio di uso di un vettore numerico è il seguente

$a=array("uno","due",3.5);
echo $a[1];

che produce la stringa "due" in output (gli indici infatti iniziano da 0).  array("uno","due",3.5) indica un array di 3 elementi che sono, in ordine, le stringhe uno, due e il numero 3.5. Notare che gli elementi di un array non devono essere necessariamente tutti dello stesso tipo. Si può far in modo che un array parta dall'indice uno piuttosto che da zero. Con

$numbers=array(1=> "uno", "due", "tre", "quattro");

si crea un array tale che $numbers[1]="uno", $numbers[2]="due", etc.. L'array si può anche riempire in maniera sparsa. Ad esempio

$primi=array(2=>"due", "tre", 5=>"cinque", 7=>"sette");

crea un array con i numeri primi da 2 a 7.  Una volta creato un array, è possibile assegnare dei valori ai suoi elementi con la solita notazione. Il seguente comando aggiunge il valore 11 all'array dei numeri primi.

$primi[11]="undici";

Notare che è possible assegnare un valore ad un elemento dell'array anche precedentemente non definito. In altre parole, non esiste un dimensione fissata per gli array come in Java. Per finire, è possibile anche assegnare un valore a un elemento dell'array non-specificato con un comando del tipo

$primi[]="dodici non è primo";

Quando non viene fornito un indice, PHP automaticamente usa l'indice più grande presente nell'array più uno. Nel caso precedente, l'assegnamento equivale a $primi[12]="dodici non è primo";
Array associativi
Gli array associativi sono delle strutture indicizzate da stringhe. Ad esempio

$a=array("pos 1" => 3.4, "z" => "stringa");
$a["xx"]="stinga2";
echo $a["pos 1"];

crea un array associativo $a di due elementi, il primo (3.4) corrisponde alla chiave "pos 1", il secondo ("stringa") alla chiave "z". Successivamente si aggiunge un nuovo elemento "stringa2" in corrispondenza della chiave "xx". Successivamente viene prodotto come output il valore 3.4.

Si possono anche creare array "misti" in cui alcune chiavi sono delle stringhe ed altre dei numeri. Ad esempio:

$nn=array(1 => "uno", 2=>"due", "uno"=>1, "due"=>2);
Array multidimensionali
Non esistono degli array multidimensionali in senso proprio, ma si possono creare facilmente array di array. Ad esempio

$planet=array(array("Mercurio",0.39,0.38),array("Venere",0.72,0.95),array("Terra",1.0,1.0));
echo $planet[1][2]

visualizza il numero 0.95.
Stringhe ed array
Come abbiamo detto, il PHP sostituisce, dentro le stringhe delimitate da virgolette, il valore di una variabile al posto del nome. La stessa cosa vale se con gli elementi di un array piuttosto che i nomi di variabili. Ad esempio

$a=array("a", "b", "c");
echo "La posizione 1 dell'array a è $a[1]";

visualizza La posizione 1 dell'array a è b.

Un po' di attenzione va posta però quando si vuole accedere ad un array associativo dentro una stringa. Ad esempio:

$b=array("uno"=>1, "due"=>2);
echo "La posizione uno vale $b['uno']";

non funziona. Nonostante per accedere normalmente alla posizione "uno" dell'array $b si usa $b['uno'] o $b["uno"], quando questo avviene dentro una stringa, si usa semplicemente $b[uno] come in

$b=array("uno"=>1, "due"=>2);
echo "La posizione uno vale $b[uno]";

oppure la notazione con le parentesi graffe

$b=array("uno"=>1, "due"=>2);
echo "La posizione uno vale {$b['uno']}";

Onde evitare possibili problemi, consiglio di adoperare sempre la notazione con le graffe quando si vuole utilizzare una variabile array dentro una stringa.

Ovviamente, è sempre possibile usare l'operazione di concatenazione tra stringhe e scrivere:

$b=array("uno"=>1, "due"=>2);
echo "La posizione uno vale ".$b['uno'];
Funzioni predefinite sugli array
Come per le stringhe, anche per gli array sono disponibili molteplici funzioni predefinite. Citiamo solo quelle fondamentali:
Il costrutto foreach
Spesso è necessario eseguire una qualche operazione su tutti gli ementi di un array. Supponiamo ad esempio di voler stampare il contenuto dell'array $a. Volendo copianre in PHP lo stile usato per i programmi Java, potremmo scrivere:
for ($i=0; $i < count($a); $i++) 
  echo $a[$i],"<br>";
Il problema è che la scansione fatta in questo modo funziona solo se $a ha solo indici numerici e, per di più, consecutivi da 0 a count($a)-1. Come fare allora nel caso generale? Ci viene in aiuto un costrutto special di PHP, pensato apposta per questo scopo: il comando foreach. La sintassi è la seguente:
foreach (<arr> as <var>)
  <istruzione>
che esegue l'istruzione <istruzione> tante volte quanti sono gli elementi nell'array <arr>, ogni volta assegnando alla variabile <var> il valore di uno di questi elementi. Ad esempio
$a=array("pos 1" => 3.4, 3 => "stringa");
foreach ($a as $elemento)
echo $elemento, "<P>";
stampa gli elementi dell'array $a (ovvero 3.4 e stringa) uno dopo l'altro, su linee diverse. Una variante di foreach consente di accedere non soltanto al valore degli elementi presenti in un array ma anche alle rispettivi chiavi. Ad esempio:
$a=array("pos 1" => 3.4, 3 => "stringa");
foreach ($a as $chiave => $elemento)
echo $chiave, ":", $elemento, "<P>";
stampa le righe pos1:3.4 e 3:stringa.

Esempio riassuntivo

Quello che segue è un esempio di programma PHP che riassume alcuni dei punti mostrati fin'ora.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Prova PHP completo</title>
</head>
<body>
Questa &egrave; una pagina di prova di PHP...<br>
Iniziamo con un p&ograve; di HTML puro<br>
<?php
echo "E ora entriamo in PHP<br>";
$x=4.5;
echo "Adesso la variabile x assume un valore float: ",$x,"<br>";
?>
Torniamo un istante in HTML<br>
<?php
echo "E quando torniamo in PHP, x vale ancora: ",$x,"<br>";
$x="stringa di prova";
echo "Adesso invece x &egrave; una stringa: ",$x,"<br>";
$a=array("uno","due",3.5);
echo "La posizione n. 1 (quindi la seconda) dell'array a vale: ",$a[1],"<br>";
$a=array("pos1" => 3.4, 3 => "stringa");
echo "L'elemento di indice 'pos1' dell'array a vale: $a[pos1]<br>";
echo "Ed ecco infine tutti gli elementi dell'array a: <br>";
foreach ($a as $key => $elemento)
  echo "<b>",$key,"</b>:",$elemento, "<br>";
echo $a,"<br>";
print_r($a);
echo "<br>";
var_dump($a);
echo "<br> Valore nullo:";
var_dump($nuovo);
if (0 == null) echo "<br>Primo test:successo"; else echo "<br>Primo test:insuccesso";
if (0 === null) echo "<br>Primo test:successo"; else echo "<br>Primo test:insuccesso";
?>
</body>
</html>


Notare che i tag <?php ... ?> possono apparire più volte all'interno della stessa pagina, e il valore delle variabili si conserva da una occorrenza all'altra. Provare questa pagina web e controllare se l'output corrisponde con il seguente:

Questa è una pagina di prova di PHP...
Iniziamo con un pò di HTML puro
E ora entriamo in PHP
Adesso la variabile x assume un valore float: 4.5
Torniamo un istante in HTML
E quando torniamo in PHP, x vale ancora: 4.5
Adesso invece x è una stringa: stringa di prova
La posizione n. 1 (quindi la seconda) dell'array a vale: due
L'elemento di indice 'pos1' dell'array a vale: 3.4
Ed ecco infine tutti gli elementi dell'array a:
pos1:3.4
3:stringa
Array
Array ( [pos1] => 3.4 [3] => stringa )
array(2) { ["pos1"]=> float(3.4) [3]=> string(7) "stringa" }
Valore nullo:NULL
Primo test:successo
Primo test:insuccesso

Come ulteriore esempio della possibilità di aprire e chiudere varie volte i tag PHP, consideriamo il caso che, a seconda del valore della variabile $x, debba essere generato un diverso blocco di codice HTML. Si può scrivere il tutto come segue:
<?php
if ($x==0) 
  echo ' ....... blocco 1 ....... ';
else
  echo ' ....... blocco 2 ....... ';
?>
Tuttavia, se i due blocchi di HTML sono molto lunghi, può diventare scomodo lasciarli dentro il comando echo che, tra l'altro, obbliga a trattare gli apici e le barre retroverse in maniera speciale. Si può allora optare per questa soluzione:
<?php
if ($x==0) {
?gt;
 ....... blocco 1 ....... 
<?php } else { ?>
 ....... blocco 2 ....... 
<php } ?> 
In questo modo, però, i due blocchi non saranno interessati alle sostituzioni dei codice di controllo e delle variabili che avvengono normalmente nelle stringhe PHP. Notare l'uso obbligatorio delle graffe per racchiudere i due blocchi di codice HTML.

Messaggi di errore

Quando si verifica un errore nel codice PHP, l'interprete del linguaggio genera un messaggio di errore. Esistono vari tipi di messaggi, che corrispondono a comportamenti diversi dell'interprete PHP. È bene familiarizzare un po' con essi.

Parse error

Sono errori che si verificano prima ancora che il codice PHP venga avviato. Sono di solito errori di sintassi come un comando scritto in maniera errata o un punto e virgola dimenticato. Ad esempio:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>Prova warning</title>
</head>
<body>
Ancora Prima<br>
<?php
echo "Prima<br>";
echo "Errore<br>"
echo "Dopo<br>";
?>
</body>
</html>

genera il messaggio:

Parse error: parse error, expecting `','' or `';'' in /home/amato/public_html/errparse.php on line 11

I messaggi "Ancora Prima", "Prima" e "Dopo" non vengono visualizzati. La pagina web non viene inviata al browser, neanche parzialmente.

Error

Si tratta di errori fatali, che terminano l'esecuzione del programma. Tutto quello che è stato mandato in output fino a quel momento raggiunge il browser. Ad esempio:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Esempio di errore fatale</title>
</head>
<body>
<?php
echo "Prima<br>";
while (true);
echo "Dopo<br>";
?>
</body>
</html>

genera il seguente output:

Prima

Fatal error: Maximum execution time of 30 seconds exceeded in /home/amato/public_html/errorerror.php on line 9

Notare che c'è un tempo massimo di esecuzione dei programmi PHP!!! Questo perchè, siccome questi vengono di solito eseguiti su richiesta di un utente in Internet, non è buona norma fare aspettare il malcapitato per un tempo eccessivo.

Warning

Sono  messaggi non fatali, nel senso che l'esecuzione continua regolarmente anche dopo che l'errore si è verificato. Ad esempio:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Prova warning</title>
</head>
<body>
<?php
echo "Prima<br>";
$x=3/0;
echo "Dopo<br>";
?>
</body>
</html>

genera un risultato simile a questo:

Prima

Warning: Division by zero in /home/amato/public_html/errwarning.php on line 9
Dopo


Dunque il comando echo viene eseguito anche se il comando $x=3/0 ha generato un errore.

Notice

I messaggi di tipo Notice sono generati in varie occasioni, corrispondenti ad usi poco "puliti" del linguaggio: uso di variabili non inizializzate, uso di array associativi in cui la chiave viene specificata senza apici e senza virgolette (ad esempio con $a[chiave] invece di $a['chiave']), etc.. Spesso i messaggi di tipo Notice sono dovuti ad errori nel programma, anche se tavolta qualcuno di questi comportamenti può essere voluto.

Ad esempio:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Prova notice</title>
</head>
<body>
<?php
echo "Prima<br>";
echo $x;
echo "Dopo<br>";
?>
</body>
</html>

genera il risultato

Prima

Notice: Undefined variable: x in /home/amato/public_html/errnotice.php on line 10
Dopo

Errori nascosti

Talvolta i messaggi di errore venono generati ma non appaiono nell'output del browser. Questo perchè vengono inseriti in punti del codice HTML che non contengono dati da visualizzare. Ad esempio, supponiamo di avere il seguente codice:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Prova errore nascosto</title>
</head>
<body>
<?php
$x=1;
echo "Prima<br>";
echo "<font size='+",$x/0,"'>prova</font><br>";
echo "Fatto<br>";
?>
</body>
</html>


Il codice giusto sarebbe con $x al posto di $x/0 in modo da visualizzare prova con un font più grosso. Nonostance ci sia la divisione per 0, all'apparenza non viene visualizzato nessun messaggio di errore. Se però andiamo a spulciare il codice HTML che arriva al browser, scopriamo che il messaggio d'errore c'è ma si trova inserito, tra apici, come valore dell'attributo size del tag font. Ovvero, nel codice HTML abbiamo:
Prima<br><font size='+<br />
<b>Warning</b>: Division by zero in <b>/home/amato/public_html/errnotice.php</b> on line <b>11</b><br />
'
>prova</font><br>Fatto<br></body>
Ne segue che il messaggio, essendo considerato come valore di un attributo non viene visualizzato. Per questo, quando uno script PHP non si comporta come dovrebbe, è sempre meglio controllare il codice sorgente della pagina che arriva al browser alla ricerca di messaggi di errori "scomparsi".

Come visualizzare i messaggi di errore

In alcune distribuzioni di Linux, per motivi di sicurezza, gli errori non vengono inviati al browser, ma vengono registrati (in gergo si dice "loggati") in un apposito file quale ad esempio /var/log/httpd/error.log per Fedora e /var/log/apache2/error.log per Ubuntu. La Ubuntu per default visualizza i messaggi di errore, mentre Fedora e derivati non lo fanno. Durante lo sviluppo del software questa cosa è molto scomoda, in quanto costringe per ogni problema a consultare il file di log. A questo si aggiunge il fatto che spesso tale file è leggibile solo all'utente root.

Per fortuna, è possibile modificare la configurazione di default in maniera non troppo complessa. Prima di tutto occorre abilitare una funzionalità di Apache che consente di modificare la configurazione del server web tramite un file dal nome .htaccess. Basta inserire nella directory public_html un file dal nome ".htaccess" (attenzione al punto iniziale) contenente la seguente linea:

php_value display_errors On

(oppure anche php_value display_errors 1). Il file .htaccess contiene dei comandi speciali che alterano la configurazione del server web Apache e del PHP.  Nella riga di cui sopra, php_value è il comando (indica che vogliamo modificare un parametro di configurazione di PHP), display_errors è il parametro da modificare e 1 è il valore da assegnarle. Oltre a display_errors ci sono tantissimi altri parametri di cui è possibile modificare il valore, e che sono documentati nel manuale di PHP.

Una volta imparato come attivare la visualizzazione dei messaggi di errore, c'è anche da notare che in molte distribuzioni di Linux (ad esempio la Ubuntu) i messaggi di tipo Notice sono disattivati per default. Per attivare tutti i possibili messaggi di errore, si può inserire nel file .htaccess anche la riga:

php_value error_reporting -1

Il significato del numero -1 è spiegato nel manuale PHP, dove vengono anche discussi gli altri valori possibili per  error_reporting.

In questo modo siete sicuri che i messaggi di errore siano abilitati e visualizzati correttamente. Questa è, tra l'altro, la configurazione che sarà utilizzata per correggere gli esercizi per casa e il progetto finale, per cui è bene che essi funzionino in questa modalità.

ATTENZIONE: configurazione di Linux

La funzionalità che consente di utilizzare il file .htaccess, per motivi di sicurezza, è normalmente disabilitata. Inoltre, nelle versioni di Ubuntu dalla 10.04 in poi, tutto l'interprete PHP è disabilitato nella directory public_html: se provare a caricare una pagina PHP, invece di eseguirla, il server web vi fa scaricare il codice sorgente. Per risolvere questo problema, sulle versioni di Ubuntu da 8.04 in poi, scaricare il file userdir-options e dare i seguenti comandi dalla shell (come utente root):

cp userdir-options /etc/apache2/sites-available/
a2ensite userdir-options
/etc/init.d/apache2 reload

Il comando cp copia il file che avete scaricato nella directory dove Apache tiene i suoi file di configurazione (nel comando di cui sopra, assumo che il file userdir-options si trovi nella directory corrente, altrimenti occorre sostituire userdir-options con il suo percorso assoluto o relativo). Il comando a2ensite attiva il file di configurazione che avete copia e /etc/init.d/apache2 dice al server web di ricarica le configurazioni.

Esercizi e Soluzioni

Esercizio 1

Creare un file .htaccess all'interno dell directory public_html che abiliti la visualizzazione dei messaggi di errore sul browser e la generazione di tutti i tipi di errori. Nel caso di una installazione casalinga di Apache, se il server web dovesse smette di funzionare, controllare che la funzionalità di modifica dei parametri tramite il file .htaccess sia abilitata (vedi discussione nella sezione Come visualizzare i messaggi di errore?).

Esercizio 2

Scrivere una pagina PHP che determini un numero n a caso tra 1 e 10 e calcoli la somma dei numeri da 1 ad n. Si può usare a tale scopo la funzione rand(), documentata accuratamente nel sito web di PHP.

Lezione Precedente Elenco Lezioni Lezione Successiva

Valid HTML 4.01 Transitional Valid CSS!