Un po' di relax e sessioni PHP

Venerdì, 10 Dicembre 2004

OBIETTIVI DELLA LEZIONE

In questa lezione:

  1. Vedremo cosa sono le sessioni e perchè servono
  2. Miglioreremo la conoscenza di base del linguaggio PHP

Approfondimento HTTP: richiesta del client e risposta del server

La comunicazione tra un client ed un server HTTP è sempre fatta da una richiesta HTTP e da una risposta HTTP. Il client richiede al server la pagina che desidera. Il server la preleva dal suo disco, e la invia corredata da un header HTTP che contiene numerose informazioni circa quale sia il server, la tabella di codici utilizzata, etc...


Approfondimento HTTP: cookie

Il server, oltre alla pagina richiesta, può includere nell'header della risposta la richiesta al client di ricevere un cookie. Il cookie è di fatto una variabile che ha un nome ed un valore. Il client (se è abilitato a ricevere cookies) salva il nome ed il valore della variabile sul proprio disco in un file che ha lo stesso nome del server che ha inviato il cookie (questo per distinguere tra cookie di siti differenti). Il cookie scade: dopo un certo tempo, specicificato dal server, il file del cookie viene rimosso dal disco dal client.





Prima di effettuare ogni richiesta al server, il client verifica se ha sul suo disco un cookie di quel server (cioè che ha lo stesso nome del server). Se lo trova ne copia il contenuto nell'header della richiesta HTTP.





Lato server, in PHP, troveremo il valore delle variabili cookie che ci sono state inviate dal client nella variabile superglobale $_COOKIE. Nell'esempio sopra, dopo il passo 5, $_COOKIE["visite"] conterrà il valore 1.

Approfondimento PHP: variabili esterne $_GET e $_POST

Il client HTTP deve richiedere la pagina al server con uno dei due metodi GET e POST. Come abbiamo visto nelle scorse lezioni, utilizzando il metodo GET gli eventuali controlli provenienti da un form vengono includi nell'URL. In alternativa con il metodo POST vengono inclusi nel corpo della richiesta HTTP. Esempio:



nome: cognome:


...
<form action="provaform.php" method="GET">
nome: <input type="text" name="nome">
cognome: <input type="text" name="cognome">
<input type="submit" value="Visualizza">
</form>
...

La richiesta HTTP sarà:

GET /~sassi/LIA2004/provaform.php?nome=Giovanni&cognome=Rossi HTTP/1.1
Host: www.dti.unimi.it

Lato server, il nostro script può accedere ai valori dei controlli inviati dall'utente tramite la variabile $_GET, che viene popolata automaticamente dal modulo PHP (molto comodo!). Nell'esempio $_GET["nome"] conterrà il valore "Giovanni" e $_GET["cognome"] conterrà il valore "Rossi"

Se invece la La richiesta HTTP fosse stata:

...
<form action="provaform.php" method="POST">
nome: <input type="text" name="nome">
cognome: <input type="text" name="cognome">
<input type="submit" value="Visualizza">
</form>
...

La richiesta HTTP sarebbe diventata:

POST /~sassi/LIA2004/provaform.php HTTP/1.0
Host: www.dti.unimi.it
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

nome=Giovanni&cognome=Rossi

Content-Length è il numero di caratteri contenuti nel corpo della richiesta, mentre Content-Type è il tipo di codifica effettuata. Lato server, il nostro script può accedere ai valori dei controlli inviati dall'utente tramite la variabile $_POST, anch'essa popolata automaticamente dal modulo PHP. Nell'esempio $_POST["nome"] conterrà il valore "Giovanni" e $_POST["cognome"] conterrà il valore "Rossi"




PHP e SESSIONI

HTTP è un protocollo senza memoria di stato e, di sua natura, ogni coppia "domanda del client"/"risposta del server" è indipendente dalle altre. Una SESSIONE è semplicemente una serie di domande/risposte effettuate da un client ad un server che condividono uno stato (condividono informazioni che persistono tra una connessione e le successive).
Abbiamo visto come sia possibile utilizzare un cookie per far si che il valore di alcune variabili permanga tra connessioni indipendenti. Di fatto l'esempio 4 costituiva un primo rudimentale esempio di sessione.
D'altra parte, per applicazioni in cui la sicurezza è critica il cookie ha un punto debole: le informazioni che si vogliono conservare tra una pagina e l'altra vengono salvate in un file sul disco del client e sono quindi modificabili dall'utente.
Una soluzione a questo problema è quello di far memorizzare tramite un cookie al client solo un codice identificativo e salvare le informazioni che devono essere persistenti sul server, accociandole al codice identificativo.
Un esempio (essessione1.php):

<?php
session_start();

if( !isset($_SESSION['numero_visite'])  )
{
    $_SESSION['numero_visite']=1;
}
else
{
    $_SESSION['numero_visite']++;
}
?>

<html>
<head>
<title>Titolo</title>
</head>
<body>

Il numero di volte che ti sei connesso a questa pagina è
<b><?php print $_SESSION['numero_visite']; ?></b>.

</body>
</html>

Tutti gli script che vogliono accedere alla sessione devono iniziare con la funzione session_start(). Come funziona?:

  1. se $_COOKIE non contiene la variabile PHPSESSID (la sessione non è ancora cominciata), session_start() genera PHPSESSID, un codice di 32 cifre, e aggiunge nella risposta la richiesta di un cookie che lo contenga:
    HTTP/1.x 200 OK
    Date: Mon, 10 May 2004 08:07:29 GMT
    Server: Apache/1.3.26 (Unix) Debian GNU/Linux PHP/4.1.2 mod_ssl/2.8.9 OpenSSL/0.9.6g mod_perl/1.26
    X-Powered-By: PHP/4.1.2
    Set-Cookie: PHPSESSID=42b93d2d874a2f169896583a9e4d85db; path=/
    [...]
    
    Inoltre crea sul server un file dove verranno salvate le variabili da conservare per tutta la durata della sessione. Il nome del file contiene il valore di PHPSESSID. As esempio, viene creato il file sess_42b93d2d874a2f169896583a9e4d85db.

  2. se $_COOKIE contiene la variabile PHPSESSID (la sessione è già cominciata), legge il file sess_... e copia nell'array associativo $_SESSION tutte le variabili contenute nel file.
    Ad esempio ecco la risposta del client dopo che la sessione è cominciata:
    GET /~sassi/LIA2004/essessione1.php HTTP/1.1
    Host: www.dti.unimi.it
    [...]
    Cookie: PHPSESSID=42b93d2d874a2f169896583a9e4d85db
    [...]
    
    mentre il contenuto del file di sessione sess_42b93d2d874a2f169896583a9e4d85db è
    numero_visite|i:5;
    
    La variabile $_SESSION['numero_visite'] conterrà il valore 5.

Per fare in modo che il valore di una variabile sia disponibile per tutta la sessione, basta aggiungere un elemento all'array $_SESSION. I dati vengono automaticamente salvati nel file di sessione.

Quando si decide di chiudere una sessione:

// elimina tutte le variabili dalla sessione
session_unset();
// chiude la sessione
session_destroy();

La funzione session_start() fa quindi cose diverse a seconda che trovi o meno un file con il nome corrispondente al cookie PHPSESSID ricevuto.








Le sessioni NON sono un modo per autenticare l'utente, ma solo per capire che le richieste vengono da uno stesso utente (che eventualmente abbiamo autenticato).

PHP II

In questa breve sezione aumentiamo la conoscenza di base del PHP

Funzioni

Come in C, anche in PHP è possibile costruire delle funzioni, che ritornino o meno dei valori. La sintassi generale è

function nome_della_funzione($parametro1, $parametro2)
{
	// corpo della funzione
	return $valore_restituito;
}
Anche per le funzioni, non è necessario specificare né il tipo dei parametri, né il tipo del valore che viene restituito.
Non è necessario ma è buona abitudine dichiarare le funzioni all'inizio del file PHP: aumenta la leggibilità.
Esempio: funzione che calcola il fattoriale di un numero

<?php
function fattoriale($n)
{
    $risultato=1;
    for($i=2; $i<=$n; $i++)
        $risultato*=$i;
    return $risultato;
}
?>

<html>
<head>
<title>Fattoriale di un numero</title>
</head>
<body>

<?php
if( isset($_GET['numero']) )
{
    print "Il fattoriale di {$_GET['numero']} è " . fattoriale($_GET['numero']);
}
else
{
?>

<form action="<?php print $_SERVER['PHP_SELF']?>", method="get">
Calcola il fattoriale di
<input type="text" name="numero">
<input type="submit" value="Calcola!">
</form>

<?php
}
?>

</body>
</html>

I parametri sono passati per valore. Se si desidera che un parametro sia passato per riferimento, nella dichiarazione della funzione bisogna anteporre l'operatore & al nome della variabile.
Ne stiamo passando il puntatore? Di certo qualcosa di simile, ma poco ci importa. L'importante, al di là dei dettagli implementativi, è che il valore della variabile viene effettivamente modificato.
ATTENZIONE: l'operatore & va usato SOLO nella dichiarazione della funzione.
Esempio: il fattoriale di un numero calcolato attraverso di una provedura:

<?php
function fattoriale($n, &$risultato)
{
    $risultato=1;
    for($i=2; $i<=$n; $i++)
        $risultato*=$i;
    return $risultato;
}
?>

[...]

<?php
if( isset($_GET['numero']) )
{
    fattoriale($_GET['numero'], $r);
    print "Il fattoriale di {$_GET['numero']} è $r";
}
else
{

[...]
Le funzioni in PHP possono essere ricorsive.

Includere un FILE: include($nome_file)

Immaginate di voler includere un banner e un footer fissi nel vostro sito. Basta salvarli in due files e chiedere al PHP di includerli nella pagina.
Esempio
Dato il file header.inc:
<html>
<head>
<title>Il mio sito</title>
</head>
<body>
<font color="#FF0000"><h2>IL MIO SITO</h2></font>
<hr size="1">
ed file footer.inc:
<hr size="1">
Contatta il <a href="mailto:webmaster@ilmiosito.it">WebMaster</a>!
</body>
</html>
ecco lo script che li include (hf.php):

<?php
include("header.inc");
?>

<br />
<h2>Contenuto del sito</h2>
<br />

<?php
include("footer.inc");
?>


Lab

Server WEB

I dati da inserire sono:

Host name weblab.crema.unimi.it
User name php_labest
Password php_labest1234
Protocol FONDAMENTALE! selezionate "sftp"

Una volta stabilita la connessione, create (se non lo avete già fatto) una cartella che abbia per nome il vostro userid al polo (es: rsassi). Copiate nella cartella i vostri files.

Per visualizzare la pagina miapagina.php andate all'indirizzo http://weblab.crema.unimi.it/php_labest/rsassi/miapagina.php dove ad rsassi sostituite il nome della cartella che avete creato.

easyPHP

Fate partire i vari server (Start->Programmi->EasyPHP->EasyPHP). Copiate i vostri files nella cartella: C:\Programmi\EasyPHP1-7\www (modificando opportunamente il path in base alla vostra installazione.

Per visualizzare la vostra pagina, cliccate con il tasto destro sull'icona PHP che avete vicino all'orologio. Selezionate "Local Web". Nel browser che vi si apre, aggiungete all'URL il nome della vostra pagina.

Esercizio 1

Preparare lo script memorizzanome1.php che inizia una sessione e, dopo aver chiesto all'utente il nome, lo memorizza nella variabile di sessione "nome". Se "nome" è già contenuto in $_SESSION, presenta all'utente una pagina di saluto contenente il nome dell'utente.
Preparare lo script memorizzanome2.php che legge il valore della variabile di sessione "nome" e presenta all'utente una pagina di benvenuto contenente il nome.
Funzionano entrambi? Chiudete il brower. Apritelo di nuovo e visualizzate memorizzanome2.php. La sessione è ancora aperta?

©2004 Roberto Sassi