Corso di Sistemi Informativi Modulo II Corso di Laurea Magistrale in Ingegneria Gestionale A. A. 2013 - 2014 PHP: Hypertext Preprocessor Caratteristiche avanzate Eufemia Tinelli, Giuseppe Loseto 1 Contenuti • PHP ad oggetti – Definizione di classi, metodi e oggetti • PDO & PDOStatement: Interazione con i database Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 2 PHP ad oggetti • Con la versione 4 di PHP è stato introdotto il supporto al paradigma di programmazione orientato agli oggetti, poi migliorato nella versione 5 • PHP 5 consente di: • definire classi (individuare tutte le caratteristiche e i comportamenti di un determinato tipo di oggetti: decidere quali attributi e metodi sono disponibili a tutti gli script e quali sono privati) • • • • creare oggetti che siano istanza di classi creare gerarchie di oggetti (eredità semplice) utilizzare l’incapsulamento (information hiding) utilizzare il polimorfismo (overloading dei metodi) Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 3 Creare una classe in PHP5 <?php class Prova { public $attr_public; private $attr_private; protected $attr_protected; public function construct(parametri) { // operazioni di inizializzazione } public function destruct(parametri) { // operazioni eseguite prima della distruzione} public function publicMethod(parametri) { … } protected function protectedMethod(parametri) { … } private function privateMethod(parametri) { … } } ?> Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 4 Instanziare una classe • Il costruttore (implementato dal metodo construct) viene eseguito ogni volta che si crea un nuovo oggetto. Può ricevere dei parametri che servono ad inizializzare i valori delle proprietà interne dell’oggetto da creare • Il distruttore (implementato dal metodo destruct) che verranno chiamati ogni qualvolta il garbage collector di PHP distruggerà l'oggetto. $oggetto= new nome_classe(parametri del costruttore) • Il meccanismo per accedere a una variabile (o metodo) interna ad una classe è rappresentato dalla seguente sintassi, dove $this rappresenta l’oggetto che sarà costruito a runtime: $this->nome variabile $this->nome_metodo(parametri) • Per accedere a una proprietà o a un metodo di un oggetto si utilizza la sintassi: $oggetto ->nome_variabile $oggetto ->nome_metodo(parametri) Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 5 Passaggio dei parametri • Nella metodologia a oggetti i passaggi dei parametri alle funzioni possono avvenire o per valore o per riferimento • Nel PHP 5 gli oggetti vengono passati solo per riferimento Æ non si fa una copia dell’oggetto, ma viene inoltrato alla funzione un indirizzo della posizione dell’oggetto in memoria • Passaggio esplicito per riferimento: Per passare per riferimento anche variabili di tipi primitivi basta aggiungere, all’interno della dichiarazione della funzione, il carattere & prima del nome del parametro da passare <?php // Passaggio per riferimento function incremento(&$num){ $num ++; return $num; } $numero = 3; incremento($numero); echo $numero; // Stampa 4; ?> <?php // forzare anche il ritorno di tipi primitivi per riferimento function &incrementaNum(&$num){ $num += 10; return $num; } ?> Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 6 Superclassi, sottoclassi e overriding: Esempio (1) <?php class A { <?php class A { public function sayHello() { echo "Hello!"; } public function sayHello() { echo "Hello!"; } } } class B extends A { public function sayHello() { echo "Ciao Ciao!"; } } class B extends A { $b = new B(); } $b = new B(); // stampa "Ciao Ciao!" $b->sayHello(); ?> public function sayHello() { parent::sayHello(); echo "Ciao Ciao!"; } // stampa "Hello! Ciao Ciao!" $b->sayHello(); ?> Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 7 Superclassi, sottoclassi e overriding: Esempio (2) <?php class A { public function construct($a, $b) { $this->a = $a; $this->b = $b; } // metodi... } class B extends A { public function construct($a, $b, $c) { parent:: construct($a, $b); $this->c = $c; } // metodi... } $b = new B(10, 20, 30); echo $b->a; // stampa 10 echo $b->b; // stampa 20 echo $b->c; // stampa 30 ?> Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 8 PDO - PHP Data Objects (2) • Rappresenta un persistent layer di elevata astrazione grazie al quale è possibile interfacciare ed utilizzare allo stesso modo qualunque database, rendendo di fatto portabili il codice sorgente e le applicazioni che ne fanno uso • La portabilità è garantita utilizzando drivers che, implementando le PDO Interfaces, espongo metodi comuni che incapsulano caratteristiche specifiche e proprietarie di ogni DB utilizzabile (non richiedere più l'utilizzo di funzioni specifiche come, per esempio, le mysql_* e pgsql_* functions) • Installazione – basta decommentare le estensioni che interessano, es.: extension=php_pdo_mysql.dll extension=php_pdo_pgsql.dll extension=php_pdo_sqlite.dll • DSN (Data Source Name) permette a PHP di scegliere correttamente il driver specifico in fase di connessione al DB. E’ costituito da: driver ':' stringa di connessione (specifica per ogni DB) Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 9 Esempi PDO PostgreSQL – ch06.zip • Connessione & disconnessione (pdo-conn-test.php) • Gestione degli errori (adv-pdo-test.php) CREATE TABLE "user" ( "id" SERIAL PRIMARY KEY NOT NULL, "username" character varying(32), "password_hash" character varying(32), "first_name" character varying(64), "last_name" character varying(64)); GRANT ALL PRIVILEGES ON "user" TO "chaptersix"; GRANT ALL PRIVILEGES ON "user_id_seq" TO "chaptersix"; INSERT INTO "user"("username", "password_hash", "first_name", "last_name") VALUES('ed', md5('berkhamsted'), 'Ed', 'Lecky-Thompson'); INSERT INTO "user"("username", "password_hash", "first_name", "last_name") VALUES('steve', md5('newyork'), 'Steve', 'Nowicki'); INSERT INTO "user"("username", "password_hash", "first_name", "last_name") VALUES('marie', md5('leicester'), 'Marie', 'Ellis'); INSERT INTO "user"("username", "password_hash", "first_name", "last_name") VALUES('harriet', md5('cambridge'), 'Harriet', 'Frankland'); Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 10 Esempio preparare gli statement: due modalità per passare parametri variabili alle query SQL $i = 0; $strUsername = ‘ed’; $strQuery = "SELECT * FROM \"user\" WHERE username = ‘$strUsername’ "; $objStatement = $objPDO->prepare($strQuery); $objStatement->execute(); while ($arRow = $objStatement->fetch(PDO::FETCH_ASSOC)) { print "Row $i<br />\n"; foreach ($arRow as $key => $value) { print " - Column $key, value $value<br />\n"; } $i++; } La stringa della query è elaborata dal motore SQL La stringa della query è elaborata direttamente da PHP Definisco solo un parametro da elaborare successivamente $i = 0; $strUsername = ‘ed’; $strQuery = "SELECT * FROM \"user\" WHERE username = :username"; $objStatement = $objPDO->prepare($strQuery); $objStatement = $objPDO->bindParam(‘:username’, $strUsername, PDO::PARAM_STR); $objStatement->execute(); while ($arRow = $objStatement->fetch(PDO::FETCH_ASSOC)) { print "Row $i<br />\n"; foreach ($arRow as $key => $value) { print " - Column $key, value $value<br />\n"; } $i++; } Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 11 Creazione di istanze singleton Come evitare la creazione di molteplici istanze della classe PDO in una data richiesta? <?php Class PDOFactory { public static function getPDO($strDSN) { $strKey = md5($strDSN); Implementazione del pattern Singleton if(!($GLOBALS[“PDOS”][$strKey] instanceof PDO)) { $GLOBALS[“PDOS”][$strKey] = new PDO($strDSN); { return($GLOBALS[“PDOS”][$strKey]); } Al posto di $objPDO = new PDO($strDSN); dobbiamo usare la seguente istruzione: $objPDO = PDOFactory::getPDO($strDSN); Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 12 Riferimenti • E. L. Thompson, S. D. Nowicki, T. Myer, PHP6 - Guida per lo sviluppatore, Hoepli, 2009 • P. B. MacIntyre, PHP – Le tecniche per scrivere il codice migliore, Hops, 2010. Eufemia Tinelli, Giuseppe Loseto - A.A. 2013-2014 21