Nozioni base di PHP

Giovedì, 28 Novembre 2007

OBIETTIVI DELLA LEZIONE

In questa lezione affrontiamo le strutture base del PHP:

  1. Variabili
  2. Tipi di dato
  3. Operatori
  4. Controllo del flusso di esecuzione
  5. Scambio dati tra FORM HTML e script PHP

Il nostro primo script 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>";
?>
&nbsp;ti stavo aspettando. <br />
Il tuo numero di matricola è nel titolo.
</body>
</html>

Contesto della lezione

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.

PHP

Primi passi

Variabili

In PHP:

Tipi di dato

Tra le variabili che il PHP ammette dalla versione 4 in poi, oggi consideriamo:

quattro tipi di variabili scalari:

un tipo di variabile composta:

e un tipo di variabile speciale

Conversioni di tipo

Stampa sullo stdout

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:

Operatori

Aritmetici

Somma (+), sottrazione (-), moltiplicazione (*), divisione (/) e resto della divisione intera (%). A differenza del Java, il risultato dell'operazione è sempre un float, anche se la divisione avviene tra due interi.

Assegnamento

L'operatore di assegnamento fondamentale è il segno di uguale (=). Come in Java, a+=3; corrisponde a a=a+3;. Questo vale per gli altri operatori aritmetici e per l'operatore di concatenamento di stringhe: $s.=" cognome"; equivale a $s=s . " cognome";.

Relazionali

Uguale (==), diverso (!= oppure <>), maggiore (>), maggiore e uguale (>=), minore (<) e minore e uguale (<=).
Restituiscono TRUE se la relazione è verificata, FALSE altrimenti.
E' possibile confrontare variabili di tipo diverso. In questo caso, le variabili oggetto del confronto, vengono prima convertite ad un tipo comune.
Se, oltre al valore della variabile, si vuole verificare che anche il tipo sia coincidente, si deve utilizzare l'operatore identico (===) o non-identico (!==). Questa è una novita rispetto al Java. Esempio:
<?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 === FALSE
mentre queste sono tutte vere:
2 == 2.0
2 == "2"
0 == FALSE

Logici

AND (and oppure &&), OR (or oppure ||), NOT (!) e XOR (xor)

Array

Due array possono essere confrontati con gli operatori relazionali visti in precedenza. Una novità è l'operatore di UNIONE (+) tra due array: $c=$a+$b. Come funziona: tutti gli elementi di $b che non hanno chiavi uguali ad elementi in $a vengono aggiunti agli elementi di $a e posti in $c. Esempio:
<?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!).

Strutture condizionali: if

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
}

Strutture condizionali: switch

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
}

Iterazione: for

for($i=1; $i<10; $i++)
{
	// codice da eseguire fino a che la condizione rimane TRUE
}

Iterazione: while

$i=1;
while($i<10)
{
	// codice da eseguire fino a che la condizione rimane TRUE
	$i++;
}

Iterazione: foreach (NOVITA'!!!)

foreach è un costrutto non presente in Java. Serve per scandire gli array del PHP.
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
}

Le variabili PROVENIENTI dall'ESTERNO

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?

$_GET

$_GET è un array associativo che contiene le variabili inviate allo script corrente attraverso il metodo GET. Esempio:
<?php
print "Hai " . $_GET["eta"] . " anni!";
?>
(al posto di $_GET si potrebbe usare anche il nome obsoleto $HTTP_GET_VARS: sconsigliato!)

$_POST

$_POST è un array associativo che contiene le variabili inviate allo script corrente attraverso il metodo POST. Esempio:
<?php
print "Hai " . $_POST["eta"] . " anni!";
?>
(al posto di $_POST si potrebbe usare anche il nome obsoleto $HTTP_POST_VARS: sconsigliato!)

$_COOKIE

$_COOKIE è un array associativo che contiene le variabili inviate allo script corrente attraverso cookies HTTP.
Come abbiamo visto nelle scorse due lezioni, un cookie è un piccolo file creato dal client, sul suo filesystem, su richiesta esplicita del server. Il client si può rifiutare di accettare (creare) il cookie (è una delle impostazioni di ogni browser).
HTTP è stateless cioè ogni pagina è scollegata da ogni altra. Se questo può andare bene per condividere delle informazioni online, di certo è riduttivo per creare applicazioni complesse, come siti di vendita online.
Il cookie è un contenitore per alcune (poche) informazioni, che il server invita il client a rimandargli ogni volta che invia una richiesta. Da queste informazioni il server può riconoscere il client univocamente (circa...). E' l'equivalente del codice che l'operatrice telefonica vi consegna quando telefonate per aprire una chiamata e che dovete fornire nelle chiamate successive per essere riconosciuti.
(l'obsoleto $HTTP_COOKIE_VARS è pressapoco simile a $_COOKIE: sconsigliato!)
Capiamolo meglio con un esempio (provacookie.php):
<?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

$_REQUEST

$_REQUEST è un array associativo che contiene tutte le variabili contenute negli array $_GET, $_POST e $_COOKIE.
Va usato con attenzione evitando variabili con lo stesso nome.

$_SERVER

$_SERVER è un array associativo che contiene molte informazioni sul server che sta eseguendo il modulo PHP.
Per vederle tutte:
<html>
<head>
<title>Informazioni sul server!</title>
</head>
<body>

<?php
foreach($_SERVER as $chiave => $valore)
    print "$chiave : $valore <br />\n";
?>

</body>
</html>

Alcuni ESEMPI

Esempio 1

La somma di due numeri. File somma.htm:
<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>

Esempio 2

Creiamo lo stesso file HTML prodotto nell'esercizio CreaFileHtml1.java della lezione Lez13e14 (potenze.php).

<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>

Esempio 3

Un esempio più complesso: FORM HTML e SCRIPT PHP nello stesso file (mutuo.php).

<?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 (&euro;): </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 (&euro;): </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 (&euro;): </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 (&euro;): </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>

Lab

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