gianfrasoft corso di php parte 3
TRANSCRIPT
PHP5terza parte - strutture evolute
Gianfranco Fedele
Analista programmatore
gianfrasoft.wordpress.com
www.linkedin.com/in/gianfrasoft
PHP5: OOP Introduzione / 1
• I concetti base della OOP: classe ed oggetto (o istanza): una classe èl’astrazione di un oggetto, mentre un oggetto è istanza di una classe.
• La classe definisce un nuovo tipo di dato, caratterizzato da:
– Un insieme di variabili, detti attributi (o proprietà)
– da un insieme di funzioni che operano su di essi, detti metodi.
• Caratteristiche della OOP:
– Ereditarietà – processo mirato alla creazione di gerarchie interne alle classi, grazie ad esso saranno maggiori le opportunità di riutilizzare porzioni del listato alla base di un applicativo.
– Polimorfismo – strettamente collegato alle dinamiche proprie dell'ereditarietà; con il polimorfismo è possibile originare comportamenti e risultati diversi impiegando i medesimi metodi a carico di oggetti differenti.
– Incapsulamento – possibilità di rendere "invisibili" in sede di scrittura del codice determinati dettagli ricollegati allo sviluppo di una classe specifica.
gianfrasoft.wordpress.com - 2008
• In PHP la dichiarazione di una classe avviene tramite la parola chiave class, seguita dal nome della classe e dal corpo.
• Il corpo della classe ne fornisce l’implementazione ed è costituito da dichiarazioni di proprietà e metodi.
• Una proprietà è una variabile dichiarata all'interno della classe; la dichiarazione deve essere esplicita, attraverso la parola chiave var.
• La dichiarazione di un metodo è del tutto analoga a quella di una funzione.
• Accesso ad una proprietà o metodonella classe:
e fuori dalla classe:
PHP5: OOP Introduzione / 2
$this->variabile;
$this->metodo(...);
$oggetto->variabile;
$oggetto->metodo(...);
gianfrasoft.wordpress.com - 2008
• La parola chiave new ci consente di istanziare una classe, cioè creare un oggetto istanza di una classe.
• Il costruttore di classe è il metodo che è richiamato automaticamente alla creazione di un'istanza della classe.
• Se all'interno di una classe base non è presente un costruttore, in automatico viene invocato quello della classe padre..
PHP5: OOP Introduzione / 3
// Questa classe non ha un costruttore dichiaratoclass Persona {
var $nome, $cognome, $eta; // Proprieta'// Metodifunction presenta() {
echo "Ciao, mi chiamo ";echo $this->nome . " " . $this->cognome;echo " ed ho " . $this->eta . " anni.";
}}
// Creazione di una istanza della classe Persona$tizio = new Persona();
// Invoca il metodo sull’oggetto Persona$tizio->presenta();
gianfrasoft.wordpress.com - 2008
PHP5: OOP Costruttori e distruttori
• Nell’ambito di ciascuna classe è possibile dichiarare un costruttore ed un distruttore:
– Il costruttore è il metodo __construct() e viene richiamato ogniqualvolta vieneistanziato un oggetto della classe stessa.
– Il distruttore è il metodo __destruct() e viene richiamato ogniqualvolta vieneeliminato un oggetto della classe stessa.
• Per compatibilità verso PHP4 viene lasciata possibilità di dichiarare ilcostruttore col nome della classe stessa ma, se presente, quello nuovo avrà la precedenza.
class ClasseDiProva
{
function __construct() {
echo "* sono nel costruttore.<br />";
}
function __destruct() {
echo "* Sono nel distruttore.<br />";
}
function Funzione() {
echo "* Sono in Funzione.";
}
}
$a = new ClasseDiProva;
$a->Funzione();
* Sono nel costruttore.
* Sono in Funzione.
* Sono nel distruttore.
gianfrasoft.wordpress.com - 2008
PHP5: OOP Ereditarietà
• In PHP è consentito creare classi che estendono le funzioni di un’altra classe. Queste si diranno classi derivate.
• Non è consentita in PHP l’ereditarietà multipla.• Le classi si estendono mediante la parola chiave extends.
// Definizione della classe Animale class Animale {
private $specie;
// Costruttore public function __construct($specie){
$this->specie = $specie; }
// Ritorna la specie public function getSpecie(){
return $this->specie; }
// Imposta la specie public function setSpecie($specie){
$this->specie = $specie; }
}
// Definizione della classe Mammifero class Mammifero extends Animale {
private $corna;
public function __construct($specie){ $this->setSpecie($specie);
}
public function haCorna(){ return $this->corna;
}
public function setCorna($corna){ $this->corna = $corna;
} }
// Creo il leone come Mammifero
$mammifero = new Mammifero("leone");
$mammifero->setCorna(false);
// Cambio da leone a cervo
$mammifero->setSpecie("cervo"); // setSpecie() ereditato
// Il cervo ha le corna
$mammifero->setCorna(true);
gianfrasoft.wordpress.com - 2008
PHP5: OOP Polimorfismo
• E’ consentito, all’interno di una classe derivata, riferirsi alle funzioni ed alle variabili della classe base. Infatti, mediante l’operatore “::” è possibile, in generale, invocare metodi di classi non istanziate.
• Le funzioni richiamate della classe non possono, però, accedere alle variabili dell'oggetto ($this) ma possono comunque accedere alle variabili locali e globali.
class ClasseA {
function stampa_frase()
{
echo "Questa è la ClasseA<br>";
}
}
class ClasseB extends ClasseA {
function stampa_frase()
{
echo "Questa è la ClasseB<br>\n";
ClasseA::stampa_frase();
}
}
ClasseA::stampa_frase();
$b = new ClasseB;
$b->stampa_frase();
Questa è la ClasseA
Questa è la ClasseB
Questa è la ClasseA
gianfrasoft.wordpress.com - 2008
PHP5: OOP Incapsulamento
• I metodi e gli attributi possono essere dichiarati, nell’ambito delle classi, come:
– pubblici (parola chiave public) accessibili dall’esterno di un oggetto;
– privati (parola chiave private) non accessibili che dall’interno della classe;
– protetti (parola chiave protected) possono essere richiamati solo dall’interno
della classe stessa oppure da una sua derivata, ma non direttamente dallo script.
class prova
{
private $variabile;
function get_variabile() {
return $this->variabile;
}
protected function set_default() {
$this->variabile = 5;
}
function __construct() {
$this->set_default();
}
}
$oggetto = new prova;
echo "\$variabile vale ".$oggetto->get_variabile();
echo "\n";
$oggetto->variabile = 6; // Errore di protezionegianfrasoft.wordpress.com - 2008
PHP5: OOP direttiva final
• In una classe derivata è possibile impedire la ridefinizione di determinati metodi e o la derivazione da determinate classi, usando la direttiva final.
class ClasseBase
{
public $attributo;
public final function metodo() {
echo "Sono un metodo finale.";
}
}
class SottoClasse extends ClasseBase
{
public function metodo() { // Genera un errore fatale
echo "Sono un metodo derivato male.";
}
}
gianfrasoft.wordpress.com - 2008
PHP5: OOP clonazione / 1
• Assegnare ad una variabile l’stanza di un oggetto significa caricarne il riferimento all’istanza: da ciò deriva che tutte le copie della stessa variabile conterranno il riferimento allo stesso oggetto.
• Per duplicare un oggetto è sufficiente mettere la parola chiave clone dopo l'operatore di assegnazione "=“.
class Classe {
public $valore;
public function Classe($v) {
$this->valore = $v;
}
}
$istanza1 = new Classe(5);
$istanza2 = $istanza1; // Assegnazione per riferimento
$istanza3 = clone $istanza1; // Clonazione oggetto
$istanza2->valore = 7; // Modifica anche $istanza1
$istanza3->valore = 13;
echo $istanza1->valore; // Non stampa 5 ma 7
echo $istanza2->valore; // Stampa 7
echo $istanza3->valore; // Stampa 13 gianfrasoft.wordpress.com - 2008
PHP5: OOP clonazione / 2
• Volendo è possibile controllare il processo di clonazione. Per farlo PHP ci consente di definire all'interno delle nostre classi il metodo __clone().
class Classe {
public $valore;
public function Classe($v) {
$this->valore = $v;
}
public function __clone()
{
$this->valore = "Sono stato clonato!";
}
}
$istanza1 = new Classe(5);
$istanza2 = clone $istanza1; // Clonazione oggetto
echo $istanza1->valore; // Stampa 5
echo $istanza2->valore; // Stampa “Sono stato clonato!”
gianfrasoft.wordpress.com - 2008
PHP5: Eccezioni
• In PHP5 vengono definiti i blocchi nell’ambito dei quali è possibile catturare le eccezioni. Le parole chiave da utilizzare sono throw, try e catch.
• Le eccezioni vengono gestite tramite una classe chiamata exception che fornisce di default 3 funzioni:
– getmessage(): restituisce il parametro passato al momento della throw.
– getfile(): restituisce il file che ha generato l'eccezione, utile nel caso della
presenza di include().
– getline(): restituisce la linea in cui presente l'invocazione della eccezione catturata.
• Le eccezioni vengono gestite mediante la classe Exception. La classe Exception è altresì estendibile al fine di costruire nuove eccezioni personalizzate. Nel costruttore
della nuova eccezione si
dovrà richiamare il costruttore
della classe exception.
try {
$a = -1;
throw new Exception("\$a è negativo<br>")
echo "Dopo la throw<br>";
}
catch (Exception $e) {
echo "Eccezione:".$e->getMessage()."<br>";
}
echo "fine";gianfrasoft.wordpress.com - 2008
PHP5: MySql / 1
• In PHP sono presenti numerose funzioni per la connessione alle basi dati MySql. La lista completa è disponibile su: http://it2.php.net/manual/it/ref.mysql.php
• Di seguito un esempio di query:
$connessione = mysql_connect("localhost", "root", "")
or die("Connessione non riuscita: ".mysql_error());
mysql_selectdb("nome_db");
if (mysql_connect_errno())
{
echo("Errore durante la connessione al server MySQL");
exit();
}
else echo("Connessione effettuata con successo");
$risultato = mysql_query("SELECT * FROM nomi", $connessione)
or die(“Query non riuscita: ".mysql_error());
while ($riga = mysql_fetch_assoc($risultato))
echo("ID: " . $riga['id'] . " NOME: " . $riga['nome'] . "<br>");
mysql_free_result($risultato);
mysql_close($connessione);gianfrasoft.wordpress.com - 2008
PHP5: MySql / 2
• Di seguito un esempio di update:
• Notare che le stringhe che rimangono aperte sul rigo s’interrompono col carattere a capo senza restituire errori di tipo unterminated string.
$connessione = mysql_connect("localhost", "root", "", "rubrica");
$modifica = “
-- Questo è un commento SQL
UPDATE operazioni
SET
campo = ?
";
mysql_query($modifica, $valore) or die(mysql_error());
mysql_close($connessione);
gianfrasoft.wordpress.com - 2008
PHP5: Mantenere lo stato
• La mancanza di stato nel protocollo HTTP (per il quale si parla di protocollo stateless) impone di individuare soluzioni alternative per la conservazione dei valori delle variabili.
• Le soluzioni individuate a tutt’oggi sono:
– moduli nascosti (input hidden)
– database
– cookie
– sessioni
gianfrasoft.wordpress.com - 2008
PHP5: Cookie / 1
• I cookie sono un meccanismo generale per memorizzare e recuperare informazioni sul client della connessione.
• Utilizzando i cookie e possibile mantenere le informazioni in modo persistente e quindi condividerle tra più script.
• Un cookie gestisce coppie nome/valore; in PHP è una array a tutti gli effetti.
• Un cookie ha una data di scadenza, decorsa la quale esso scompare automaticamente (per default, scompare alla chiusura del browser).
• Ad ogni cookie sono associati anche un dominio ed un percorso (per default, il nome di dominio ed il percorso correnti).
• Ogni cookie, infine, ha un attributo secure che, se impostato, ne consente il funzionamento solo su connessioni sicure (HTTPS).
gianfrasoft.wordpress.com - 2008
PHP5: Cookie / 2
• L’impostazione di un cookie avviene con la funzione setcookie(). Sul client viene impostata prima del tag <HTML> (a livello di intestazioni HTTP).
• Una volta impostato, un cookie è accessibile da PHP come una qualsiasi variabile globale.
• L’array associativo $_COOKIE, contiene tutte le coppie nome/valore relative ai cookie impostati.
• Il cookie assume il valore (viene impostato) solo dopo che il client ha inviato una riposta al server che lo ha definito.
$scadenza = time() + 60*60*24*10; // 10 gg
$percorso = "/";
$nome = "nome del cookie";
$valore = "valore del cookie";
setcookie($nome, $valore,
$scadenza, $percorso)
or die("non posso settare il cookie");
while (list($nome,$valore) =
each($_COOKIE))
echo "<h2>Nome del cookie: $nome -
Valore: $valore<\h2>";
gianfrasoft.wordpress.com - 2008
PHP5: Sessioni / 1
• Il meccanismo delle sessioni è un espediente pensato per ovviare al problema della mancanza di stato nel protocollo HTTP.
• Con le sessioni è possibile associare uno stato ad ogni client e mantenerlo nell'arco di più accessi.
• Il mantenimento di una sessione richiede la collaborazione di client (il browser) e server. Tutte le informazioni della sessione sono sul server.
• Il server codifica (mediante serializzazione) le informazioni di sessione su file e le ripristina alla successiva richiesta dello stesso client.
• Il client deve fornire al server le informazioni per associare alla richiesta la sessione corrispondente.
• Ciò è reso possibile da un identificativo di sessione (session ID) univoco generato all’avvio di una nuova sessione.
gianfrasoft.wordpress.com - 2008
PHP5: Sessioni / 2
• La problematica principale riguardo le sessioni, è la propagazione del session ID. Le tecniche di propagazione sono tramite cookies e tramite URL.
• Grazie ad un cookie, l'identificativo di sessione viene memorizzato sul client e rimane accessibile in PHP come variabile globale. Ciò non e sufficientemente affidabile: il visitatore, potrebbe aver configurato il proprio browser con i cookie disabilitati.
• La propagazione tramite URL è del tutto identica al passaggio di parametri con il metodo GET: Si tratta di modificare i link alle varie pagine PHP in modo che contengano, nella parte di query string, il valore della costante SID. La costante SID è una costante che viene definita solo se il browser utente non supporta i cookies. Nel caso sia stato spedito il cookie, SID è una costante stringa vuota.
• Gli URL possono essere riscritti automaticamente abilitando la transparent session ID propagation agendo sulla direttiva session.use_trans_sid. Per modificare la direttiva in run time si può utilizzare uno dei comandi:
<? session_start(); ?><a href=“altro_script.php?<?= htmlspecialchars(SID) ?>&">Altro script</a>
<? /* htmlspecialchars serve a prevenire attacchi di tipo XSS (cross site scripting) mediante code injection */ ?>
ini_set('session.use_trans_sid', false);
// oppure
session.use_trans_sid = 0
gianfrasoft.wordpress.com - 2008
PHP5: Sessioni / 3
• Le funzioni principali per la gestione delle sessioni sono:
– session_start(), crea una nuova sessione o la ripristina se esistente basata sull'id di sessione che viene passato attraverso una variabile GET o un cookie.
– session_register(), registra variabili come variabili di sessione;
– session_destroy(), distrugge una sessione, liberando le risorse.
• L'interprete PHP verifica, in base ai cookie e ai parametri nella URL, se è stato fornito un identificativo di una sessione: in caso affermativo provvede a ripristinare la sessione corrispondente, diversamente ne avvia una nuova.
• Affinché session_start() possa impostare il cookie contenente il SID, dovrà essere invocata prima che l’output sia inviato al browser.
• A questo punto qualsiasi variabile può essere resa variabile di sessione, tramite la funzione session_register().
session_start();
if (!session_is_registered('accessi'))
session_register('accessi');
if (empty($_SESSION['accessi'])) {
$_SESSION['accessi'] = 1;
} else {
$_SESSION['accessi']++;
}
gianfrasoft.wordpress.com - 2008
PHP5: Sessioni / 4
• Il session id va continuamente rigenerato per motivi di sicurezza (sessionfixation attack). Ciò può essere realizzato mediante il comando session_regenerate_id().
gianfrasoft.wordpress.com - 2008
PHP5terza parte - FINE
Gianfranco Fedele
Analista programmatore
gianfrasoft.wordpress.com
www.linkedin.com/in/gianfrasoft