OBIETTIVI DELLA LEZIONE
In questa lezione affrontiamo le strutture base del PHP:
Questo è il testo dello script per cui abbiamo preparato il form dell'esercizio 1 della lezione 16.
<html> <head> <title>Prova FORM. La tua matricola è <?php print " " . $_REQUEST['matricola'] . "."; ?> </title> </head> <body> Ben arrivato <?php print "<b>" . $_REQUEST["nome"] . " " . $_REQUEST['cognome'] . "</b>"; ?> ti stavo aspettando. <br /> Il tuo numero di matricola è nel titolo. </body> </html>
Secondo quanto visto nella scorsa lezione, il processo di creazione dinamica di una pagina HTML può essere schematizzato nei seguenti passi fondamentali:
(1) | Invio dei dati dal client al server | form HTML + richiesta HTTP (GET/POST) | Scorsa lezione |
(2) | Sul server una CGI riceve i dati | Server + Programma PHP | Oggi |
(3) | La CGI interroga il DB MySQL | query MySQL | Prossimamente |
(4) | Con i risultati ottenuti crea la pagina da rimandare all'utente | Programma PHP + Server | Oggi |
Oggi ci occuperemo dei punti (2) e (4), vedremo cioè come scrivere programmi PHP.
<html> <head> <title>Il mio primo file PHP</title> </head> <body> Questo è scritto in modalità HTML <?php print "<br />\n"; print "... e questo in modalità PHP\n"; ?> </body> </html>produce:
<html> <head> <title>Il mio primo file PHP</title> </head> <body> Questo è scritto in modalità HTML <br /> ... e questo in modalità PHP </body> </html>
<?php $nome="Giovanni"; $eta=52; $celibe=FALSE; ?>
<?php $nome="Giovanni"; // è una stringa $nome=52 // adesso è un intero ?>
Tra le variabili che il PHP ammette dalla versione 4 in poi, oggi
consideriamo:
quattro tipi di variabili scalari:
<?php $pi = 3.1415; $a = 1.0e-6; $b = 5.32E10; ?>
<?php $a="Questa è una stringa\n"; ?>Se la stringa è contenuta tra apici DOPPI il contenuto di ogni variabile viene convertito in stringa e sostituito al nome della variabile corrispondente!
<?php $a="lezione"; $b=15; $c="Questa è la $a numero $b\n"; print $c; ?>produce nel file HTML:
Questa è la lezione numero 15E' possibile utilizzare caratteri speciali (sequenze di escape) simili a quelli usati in Java:
\n | a capo (LF) |
\t | tabulazione orizzonatale (HT) |
\\ | backslash |
\$ | dollaro |
\" | virgolette doppie |
<?php $a='Questa è una stringa'; ?>Se la stringa è contenuta tra apici SINGOLI non viene effettuata nessuna sostituzione e gli unici caratteri speciali utilizzabili sono:
\\ | backslash |
\" | virgolette singole |
<?php $nome="Gino"; $s = <<<FINE Mi chiamo $nome.\n Sto provando a costruire stringhe in PHP.\n FINE; print $s; ?>produce nel file HTML:
Mi chiamo Gino. Sto provando a costruire stringhe in PHP.ATTENZIONE: la riga che contiene l'etichetta finale non deve contenere altro che l'etichetta e un punto e virgola. NON mettere spazi ne indentare l'etichetta!
<?php $nome="Gino"; $s = $nome{2}; print $s; // stampa la lettera n ?>
un tipo di variabile composta:
<?php $a[0]=1; $a[1]=2; $a[2]=3; $a[3]=4; print_r($a); ?>
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )ma è una struttura dati molto più versatile.
<?php $a[0]=1; $a[1]=2; $a[2]="pino"; $a[3]="abete"; print_r($a); ?>
Array ( [0] => 1 [1] => 2 [2] => pino [3] => abete )Gli indici possono essere numeri interi o stringhe:
<?php $a[0]=1; $a["quantità"]=2; $a["albero"]="pino"; $a[3]="abete"; print_r($a); ?>
Array ( [0] => 1 [quantità] => 2 [albero] => pino [3] => abete )La sintassi più generale per definire un array è:
array( [chiave1 =>] valore1, [chiave2 =>] valore2, [chiave3 =>] valore3, ... )l'ultimo esempio e infatti equivalente a:
<?php $a=array(0=>1, "quantità"=>2, "albero"=>"pino", 3=>"abete"); print_r($a); ?>mentre il primo è equivalente a:
<?php $a=array(1, 2, 3, 4); print_r($a); ?>Se la chiave non è specificata, viene automaticamente assegnata una chiave numerica crescente. Il modulo PHP verifica quale sia la chiave numerica più alta contenuta in quell'array e
<?php $a[2]=1; $a[]=2; print_r($a); $b[-5]=3; $b[]=4; print_r($b); ?>
Array ( [2] => 1 [3] => 2 ) Array ( [-5] => 3 [0] => 4 )Non pensiamo all'array PHP come ad una array C: Assomiglia più ad un array di oggetti Java e non occupa necessariamente una zona di memoria contigua!
<?php $a["ditta"] = "pincopallino"; $b = "la ditta {$a["ditta"]} ha pagato la fornitura."; // NON funzionerebbe: $b = "la ditta $a["ditta"] ha pagato la fornitura."; ?>
e un tipo di variabile speciale
<?php $a=NULL; ?>
<?php $a=3.78; unset($a); ?>
<?php
$a = "prova";
$b = "nuova";
$c = $a . $b;
unset($b);
var_dump(isset($b));
# stampa: bool(false)
$c = $a . $b;
# stampa: Notice: Undefined variable: b in provanull.php on line ...
print $c;
$b=null;
var_dump(isset($b));
# stampa bool(false)
$c = $a . $b;
# non stampa nessun notice!
print $c;
?>
(bool) o (boolean) | cast a valore logico |
(int) o (integer) | cast a numero intero |
(float) o (double) o (real) | cast a numero in virgola mobile |
(string) | cast a stringa |
(array) | cast ad array |
<?php $a=3.84; $b=(int)$a; print $b; // $a viene convertito in intero con il cast e implicitamente a stringa. // Il risultato è la stringa "3" ?>
DA tipo | A tipo | regola conversione implicita |
---|---|---|
integer o float | boolean | FALSE se il numero è zero (0 o 0.0); TRUE altrimenti |
string | boolean | FALSE se la stringa è vuota o è la stringa "0"; TRUE altrimenti |
array | boolean | FALSE se l'array non ha alcun elemento; TRUE altrimenti |
boolean | integer o float | 1 (o 1.0) se il valore logico è TRUE, 0 (o 0.0) se FALSE |
float | integer | intero ottenuto eliminando i decimali (verso lo zero) |
stringa | integer o float | il numero ottenuto convertendo la stringa se la stringa rappresenta un numero, 0 altrimenti |
integer o float | stringa | una stringa contenente il valore numerico |
boolean | string | una stringa vuota se il valore logico è FALSE, "1" se TRUE |
array | string | la stringa "Array" |
Ad esempio:
<?php $n=3; print $n+$m; ?>funziona perfettamente (a $m viene implicitamente assegnato il valore 0). ATTENZIONE: questo non vuol dire che tutto fili liscio! A seconda del livello di error_reporting impostato potrebbe visualizzarsi un warning sulla pagina HTML, del tipo:
Abbiamo visto che, la stampa sullo standard output (che il server HTTP copierà nella risposta al client) è la finalità naturale di ogni GCI. In PHP si utilizza:
<?php printf("%12.2f",$rata_mutuo); ?>
<?php print $n; echo $n; // producono un identico risultato ?>
<?php $a="Mario"; $b="Rossi"; print $a . " ". $b // Il risultato è Mario Rossi ?>
<?php print "Prima riga\n"; print "<br />\n"; print "Seconda riga\n"; ?>produce un file HTML con:
Prima riga <br /> Seconda riga
<?php $a=1; $b="1"; $c = ($a==$b); var_dump($c); print "<br />\n"; $c = ($a===$b); var_dump($c); ?>produce nel file HTML
bool(true) <br /> bool(false)L'operatore === è utile per non confondere stringhe con valori numerici o booleani. Ad esempio le seguenti affermazioni sono tutte false:
2 === 2.0 2 === "2" 0 === FALSEmentre queste sono tutte vere:
2 == 2.0 2 == "2" 0 == FALSE
<?php $orto=array("rapanelli"=>"2Kg", "insalata"=>"3Kg", "patate"=>"20Kg"); $frigorifero=array("patate"=>"0.1Kg", "zucchine"=>"1Kg"); print "\$orto unito a \$frigorifero:\n"; $verdure_a_disposizione=$orto+$frigorifero; print_r($verdure_a_disposizione); print "\$frigorifero unito a \$orto:\n"; $verdure_a_disposizione=$frigorifero+$orto; print_r($verdure_a_disposizione); ?>scrive nel file HTML:
$orto unito a $frigorifero: Array ( [rapanelli] => 2Kg [insalata] => 3Kg [patate] => 20Kg [zucchine] => 1Kg ) $frigorifero unito a $orto: Array ( [patate] => 0.1Kg [zucchine] => 1Kg [rapanelli] => 2Kg [insalata] => 3Kg )Controllo del flusso di esecuzione
Per quanto riguarda il controllo di flusso, il PHP assomiglia molto al linguaggio Java (BENE!).
if( condizione_logica_1 ) { // codice che viene eseguito se condizione_logica_1 è TRUE } else { // codice che viene eseguito se condizione_logica_1 è FALSE }Come in Java, è possibile non utilizzare le parentesi graffe se l'istruzione è solo una (vale per tutti i costrutti di controllo). A differenza del Java:
if( condizione_logica_1 ) { // codice che viene eseguito se condizione_logica_1 è TRUE } elseif( condizione_logica_2 ) { // codice che viene eseguito se condizione_logica_2 è TRUE } elseif( condizione_logica_3 ) { // codice che viene eseguito se condizione_logica_3 è TRUE } else { // codice che viene eseguito se tutte le condizioni // precedenti sono FALSE }
switch(variabile) { case valore_1: // codice che viene eseguito se variabile==valore_1 break; case valore_2: // codice che viene eseguito se variabile==valore_2 break; case valore_3: case valore_4: // codice che viene eseguito se (variabile==valore_3) o se (variabile==valore_4) break; default: // codice che viene eseguito se nessuna delle condizioni // precedenti è verificata }
for($i=1; $i<10; $i++) { // codice da eseguire fino a che la condizione rimane TRUE }
$i=1; while($i<10) { // codice da eseguire fino a che la condizione rimane TRUE $i++; }
foreach($nome_array as $k => $v) { // Codice da eseguire per ogni elemento dell'array. // All'i-esimo ciclo $v conterrà: // $k conterrà il valore della chiave dell'elemento i-esimo // $v conterrà il valore dell'elemento i-esimo }Esempio:
<?php $a=array("Mario" => 2, "Luigi" => 1, "Teresa" => 5); foreach($a as $dipendente => $giorni) { if($giorni == 1) print $dipendente . " ha " . $giorni . " giorno di ferie"; else print $dipendente . " ha " . $giorni . " giorni di ferie"; print "<br />\n"; } ?>produce:
Mario ha 2 giorni di ferie<br /> Luigi ha 1 giorno di ferie<br /> Teresa ha 5 giorni di ferie<br />Se le chiavi degli elementi non interessano, è possibile utilizzare la forma compatta:
foreach($nome_array as $v) { // Codice da eseguire per ogni elemento dell'array. // All'i-esimo ciclo $v conterrà il valore dell'elemento i-esimo }
Nell'esempio seguente, l'utente è invitato ad inserire l'età, che (vedi la scorsa lezione) il client invierà nella richiesta HTTP alla CGI controlla_eta.php.
<html> <head> <title>Che età hai?</title> </head> <body> Inserisci la tua età: <form action="controlla_eta.php" method="get"> <input type="text" name="eta" \> <input type="submit" value="Invia"> </form> </body> </html>
Come fa la CGI controlla_eta.php ad accedere al valore dell'età? In generale quali sono le informazioni esterne disponibili ad uno script PHP?
<?php print "Hai " . $_GET["eta"] . " anni!"; ?>(al posto di $_GET si potrebbe usare anche il nome obsoleto $HTTP_GET_VARS: sconsigliato!)
<?php print "Hai " . $_POST["eta"] . " anni!"; ?>(al posto di $_POST si potrebbe usare anche il nome obsoleto $HTTP_POST_VARS: sconsigliato!)
<?php
if( isset($_COOKIE["visite"]) )
$numero_visite=(int)$_COOKIE["visite"]+1;
else
$numero_visite=1;
// Il cookie verrà cancellato dal client dopo 3600 secondi = 1 ora
setcookie("visite", $numero_visite, time()+3600);
#setcookie("visite", $numero_visite, time()-3600);
?>
<html>
<head>
<title>Piccola prova cookie</title>
</head>
<body>
<?php
if( $numero_visite==1 )
{
print "<h2>Benvenuto!</h2>\n";
print "Nell'ultima ora hai visitato questa pagina 1 volta\n";
}
else
{
print "<h2>Bentornato!</h2>\n";
print "Nell'ultima ora hai visitato questa pagina $numero_visite volte\n";
}
?>
</body>
</html>
Il server chiede al client di creare il cookie nell'header della
risposta HTTP:
HTTP/1.x 200 OK
Date: Fri, 30 Apr 2004 20:23:34 GMT
Server: Apache/1.3.27 (Win32) PHP/4.3.3
X-Powered-By: PHP/4.3.3
Set-Cookie: visite=1; expires=Fri, 30-Apr-2004 21:23:34 GMT
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
la pagina HTML prodotta (alla prima visita) è:
<html> <head> <title>Piccola prova cookie</title> </head> <body> <h2>Benvenuto!</h2> Nell'ultima ora hai visitato questa pagina 1 volta </body> </html>Il client accetta la proposta del server e crea un file chiamato (Windows 2000 + IE) sassi@saturno[1].txt che contiene:
visite 1 saturno/ 1024 1795114496 29634299 155982864 29634291 *Tutte le volte che il client fa una richiesta ad un server, verifica se ha un cookie di quel server. In caso affermativo, include nella richiesta le variabili contenute nel cookie!
GET /provacookie.php HTTP/1.1
Host: saturno
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6) Gecko/20040206 Firefox/0.8
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: visite=1
Cache-Control: max-age=0
<html>
<head>
<title>Informazioni sul server!</title>
</head>
<body>
<?php
foreach($_SERVER as $chiave => $valore)
print "$chiave : $valore <br />\n";
?>
</body>
</html>
<html> <head> <title>Somma di due numeri</title> </head> <body> <h2>SOMMA di 2 NUMERI</h2> <form action="somma.php" method="get"> <table border="0"> <tr> <th>Inserisci il primo addendo</th> <td><input type="text" name="add1" /></td> </tr> <tr> <th>Inserisci il secondo addendo</th> <td><input type="text" name="add2" /></td> </tr> <tr> <th></th> <td><input type="submit" value="Somma!" /></td> </tr> </table> </form> </body> </html>e "somma.php":
<html>
<head>
<title>Risultato della somma</title>
</head>
<body>
<h2>RISULTATO della SOMMA</h2>
<?php
$somma=$_GET['add1']+$_GET['add2'];
#print "Il risultato di " . $_GET['add1'] . " + " . $_GET['add2'] " è $somma\n";
print "Il risultato di {$_GET['add1']} + {$_GET['add2']} è $somma\n";
?>
</body>
</html>
<html>
<head>
<title>Una tabella scritta da uno script in PHP</title>
</head>
<body bgcolor="#FFFFFF">
</body>
<b>Potenze del 2 e del 3 (da 0 a 10)</b><br /><br />
<table border="3" cellpadding="10">
<td></td>
<th>2</th>
<th>3</th>
</tr>
<?php
for($i=0; $i<=10; $i++)
{
print "<tr>\n";
print "<th>$i</th>\n";
print "<td bgcolor=\"#FFFF00\">" . pow(2,$i) . "</td>\n";
print "<td bgcolor=\"#0099AA\">" . pow(3,$i) . "</td>\n";
print "</tr>\n";
}
?>
</table>
</html>
<?php
if(isset($_REQUEST["importo"]) and isset($_REQUEST["anni"])
and isset($_REQUEST["interesse"]))
{
$importo=$_REQUEST["importo"];
$anni=$_REQUEST["anni"];
$interesse=$_REQUEST["interesse"];
$interesse_mensile=(double)$interesse/(12.0*100.0);
$rata_mensile=(double)$importo*$interesse_mensile/
(1.0-1.0/pow(1.0+$interesse_mensile,12*$anni));
}else
{
$importo="";
$anni="";
$interesse="";
}
?>
<html>
<head>
<title>:: Calcolo rata mutuo ::</title>
</head>
<body>
<b>CALCOLO DELLA RATA DEL MUTUO</b>
<br /><br />
<?php
print "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"GET\">\n";
print "<table border=\"0\" cellpadding=\"4\">\n";
print "\t<tr>\n";
print "\t<th align=\"right\">Importo del prestito (€): </th>\n";
print "\t<td align=\"right\"><input name=\"importo\"" .
"value=\"$importo\" type=\"text\"></td>\n";
print "\t<td></td>\n";
print "\t</tr>\n";
print "\t<tr>\n";
print "\t<th align=\"right\">Durata del mutuo (anni): </th>\n";
print "\t<td align=\"right\"><input name=\"anni\"" .
"value=\"$anni\" type=\"text\"></td>\n";
print "\t<td></td>\n";
print "\t</tr>\n";
print "\t<tr>\n";
print "\t<th align=\"right\">Interesse (%): </th>\n";
print "\t<td align=\"right\"><input name=\"interesse\"" .
"value=\"$interesse\" type=\"text\"></td>\n";
print "\t<td align=\"right\">\n" .
"\t<input type=\"submit\" value=\"Calcola\">\n" . "\t</td>\n";
print "\t</tr>\n";
if(isset($_REQUEST["importo"]) and isset($_REQUEST["anni"])
and isset($_REQUEST["interesse"]))
{
print "\t<tr>\n";
print "\t<th align=\"right\">Rata mensile (€): </th>\n";
print "\t<td align=\"right\" bgcolor=\"FFEE00\">" . sprintf("%12.2f",$rata_mensile) . "</td>\n";
print "\t<td></td>\n";
print "\t</tr>\n";
print "\t<tr>\n";
print "\t<th align=\"right\">Totale interessi (€): </th>\n";
print "\t<td align=\"right\" bgcolor=\"FFEE00\">" .
sprintf("%12.2f",$rata_mensile*12*$anni-(double)$importo) . "</td>\n";
print "\t<td></td>\n";
print "\t</tr>\n";
print "\t<tr>\n";
print "\t<th align=\"right\">Totale (€): </th>\n";
print "\t<td align=\"right\" bgcolor=\"FFEE00\">\n" .
sprintf("%12.2f",$rata_mensile*12*$anni) . "</td>\n";
print "\t<td></td>\n";
print "\t</tr>\n";
}
print "</table>\n";
print "</form>\n";
if(isset($_REQUEST["importo"]) and isset($_REQUEST["anni"])
and isset($_REQUEST["interesse"]))
{
?>
<br />
<br />
<b>La ripartizione mensile del mutuo è la seguente:</b>
<br />
<br />
<?php
$debito_residuo=(double)$_REQUEST['importo'];
$capitale_restituito=0.0;
$interesse_pagato=0.0;
?>
<table border="1" cellpadding="4">
<tr>
<th>Mese</th>
<th>Rata interesse</th>
<th>Rata capitale</th>
<th>Rata totale</th>
<th>Capitale restituito</th>
<th>Debito residuo</th>
<th>Interesse pagato</th>
</tr>
<tr>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="right"><?php printf("%12.2f",$capitale_restituito); ?></td>
<td align="right"><?php printf("%12.2f",$debito_residuo); ?></td>
<td align="right"><?php printf("%12.2f",$interesse_pagato); ?></td>
</tr>
<?php
for($i=1;$i<=12*(int)$_REQUEST['anni'];$i++)
{
$rata_interesse=$debito_residuo*$interesse_mensile;
$rata_capitale=$rata_mensile-$rata_interesse;
$capitale_restituito+=$rata_capitale;
$debito_residuo-=$rata_capitale;
$interesse_pagato+=$rata_interesse;
if($i%2===0):
$bgcolor="\"FFFF00\"";
else:
$bgcolor="\"0099AA\"";
endif;
print("\t<tr>\n\t<th>$i</th>\n");
printf("\t<td bgcolor=$bgcolor align=\"right\">%12.2f</td>\n",$rata_interesse);
printf("\t<td bgcolor=$bgcolor align=\"right\">%12.2f</td>\n",$rata_capitale);
printf("\t<td bgcolor=$bgcolor align=\"right\">%12.2f</td>\n",$rata_interesse+$rata_capitale);
printf("\t<td bgcolor=$bgcolor align=\"right\">%12.2f</td>\n",$capitale_restituito);
printf("\t<td bgcolor=$bgcolor align=\"right\">%12.2f</td>\n",$debito_residuo);
printf("\t<td bgcolor=$bgcolor align=\"right\">%12.2f</td>\n",$interesse_pagato);
print("\t</tr>\n");
}
?>
</table>
<?php
}
?>
</body>
</html>
Un ambiente PHP funzionante è composto da almeno tre componenti:
Installarli separatamente è piuttosto brigoso anche se non difficile. Se volete esercitarvi a casa, è molto più conveniente utilizzare la distribuzione EasyPHP. La versione 2.0beta1 contiene:
A prescindere delle versioni di volta in volta disponibili, ad esercitazione utilizzaremo i quattro software appena elencati.
Mentre sviluppate i vostri script, è essenziale consultare il manuale ufficiale PHP. Fatelo per risolvere ogni dubbio o per scoprire che funzioni sono messe a disposizione. Il PHP evolve molto velocemente e con lui anche il manuale. La versione aggiornata la potete scaricare da http://www.php.net/download-docs.php; una copia locale la trovate premendo F1 all'interno di un file php in SciTE.
Esercizio 1: Prendiamo confidenza con il PHP/I
Salvate i file somma.htm e somma.php. Quindi copiateli nella vostra cartella sul WEB server. In questa pagina trovate un riassunto della procedura.
Dal vostro browser, caricate la pagina "somma.htm" e verificate che tutto funzioni. Analizzate attentamente i due file. Modificateli opportunamente in modo che utilizzino il metodo POST invece che il GET.
Esercizio 2: Prendiamo confidenza con il PHP/II
Salvate il file iserver.php che visualizza il contenuto dell'array superglobal $_SERVER. Copiatelo sul server. Eseguite lo script e con l'aiuto del file di help PHP analizzate l'output (in particolare HTTP_USER_AGENT, HTTP_HOST e SCRIPT_URL). Guardate anche il file HTML prodotto (con MS Internet Explorer, Visualizza->HTML; con FireFox/Mozilla, View->Page Source).
Esercizio 3
Rifai in PHP l'esercizio 3 della lezione lez13e14.html: scrivi un tuo programma "tabelline.php" che crei una pagina HTML ("tabelline.html") con la tabella delle "tabelline" da 1 a 10. La tabella deve avere le intestazioni di riga e di colonna (<th> </th>).
Per verificare se lo script funziona caricalo sul server ed eseguilo!
Esercizio 4
Preparare un form HTML in cui l'utente inserisce i coefficienti di una equazione di secondo grado. I dati vengono inviati tramite il metodo POST ad uno script PHP che produce una pagina HTML con la soluzione.
©2007 Roberto Sassi