Guida PHP
Guida PHP
per principianti
Guida PHP di base..............................................................................................................................4 Cos' PHP........................................................................................................................................4 La programmazione web: lato client e lato server...........................................................................5 Caratteristiche e vantaggi di PHP....................................................................................................6 PHP e l'H !L................................................................................................................................." La str#tt#ra sintattica del ling#aggio...............................................................................................$ % commenti.....................................................................................................................................&' Le variabili.....................................................................................................................................&( % tipi di dato....................................................................................................................................&4 )alore booleano.........................................................................................................................&4 %ntero.........................................................................................................................................&5 )irgola mobile...........................................................................................................................&5 *tringa.......................................................................................................................................&5 +rra,.........................................................................................................................................&" -ggetto......................................................................................................................................&" .spressioni e operatori aritmetici di PHP......................................................................................&" /li operatori logici e le espressioni booleane in PHP...................................................................&$ /li operatori di con0ronto.........................................................................................................&$ /li operatori logici....................................................................................................................(& Le espressioni................................................................................................................................(( %str#zione %0....................................................................................................................................(1 %0 ...............................................................................................................................................(1 %str#zioni .lse e .lsei0...................................................................................................................(5 .lse ...........................................................................................................................................(5 .lsei0 ........................................................................................................................................(5 %str#zione *witch e operatore ternario...........................................................................................(6 *witch .......................................................................................................................................(6 L'operatore ternario ..................................................................................................................(" % cicli: 0or2 while e do.....................................................................................................................(" Ciclo 3or ..................................................................................................................................(4 %l ciclo 5hile ............................................................................................................................(4 %l ciclo do...while ......................................................................................................................($ 6scire da #n ciclo .....................................................................................................................($ Ciclo 3oreach ...........................................................................................................................1' /li arra,.........................................................................................................................................1' Le 0#nzioni in PHP: gestire le variabili.........................................................................................1( Le 0#nzioni in PHP: gestire le stringhe..........................................................................................14 Le 0#nzioni in PHP: gestire gli arra,.............................................................................................1" Le 0#nzioni in PHP: gestire le date................................................................................................1$ *crivere 0#nzioni personalizzate....................................................................................................4' *cope e argomenti 0acoltativi.........................................................................................................4( &
Lo scope delle variabili ............................................................................................................4( +rgomenti 0acoltativi ...............................................................................................................41 Le variabili /. e P-* ...............................................................................................................44 %l metodo /. ..........................................................................................................................44 %l metodo P-* ........................................................................................................................45 !antenere lo stato: i coo7ie...........................................................................................................46 !antenere lo stato: le sessioni.......................................................................................................4" +ccedere ai 0ile..............................................................................................................................44 6tilizzare *8Lite...........................................................................................................................5' %nterrogare database !,*8L.........................................................................................................5( Prepared statement....................................................................................................................54 La con0ig#razione di PHP..............................................................................................................55 Guida PHP teorica............................................................................................................................5$ %ntrod#zione...................................................................................................................................5$ Le variabili.....................................................................................................................................5$ Le costanti......................................................................................................................................6' % tipi di dato 9 %...............................................................................................................................6& %nteger ......................................................................................................................................6( 3loat .........................................................................................................................................6( *trings ......................................................................................................................................6( % tipi di dato 9 %%..............................................................................................................................61 +rra, ........................................................................................................................................61 -b:ects .....................................................................................................................................64 -peratori di base............................................................................................................................65 /li operatori aritmetici .............................................................................................................65 +ssegnazione ...........................................................................................................................65 +ltri operatori................................................................................................................................66 *tr#tt#re di controllo: i02 else e else i0............................................................................................6" %0 ...............................................................................................................................................6" .lse ...........................................................................................................................................6" .lsei0 ........................................................................................................................................64 *tr#tt#re di controllo: while2 0or2 switch........................................................................................64 5hile ........................................................................................................................................64 3or ............................................................................................................................................6$ *witch .......................................................................................................................................6$ Le 0#nzioni con iniziale +..............................................................................................................6$ Le 0#nzioni con iniziale ;.............................................................................................................."' Le 0#nzioni con iniziale C.............................................................................................................."( Le 0#nzioni con iniziale <............................................................................................................."4 Le 0#nzioni con iniziale ..............................................................................................................."6 Le 0#nzioni con iniziali 3 e /........................................................................................................"4 Le 0#nzioni con iniziali H2 %2 =2 > e L............................................................................................4' Le 0#nzioni con iniziali !2 -2 P e ?..............................................................................................4& Le 0#nzioni con iniziali *2 e 6....................................................................................................41 3#nzioni relative alla crittazione....................................................................................................44 3#nzioni legate al protocollo 3 P 9 %.............................................................................................46 0tp@connect ...............................................................................................................................46 0tp@login ...................................................................................................................................46 0tp@pwd ....................................................................................................................................4" 3#nzioni legate al protocollo 3 P 9 %%............................................................................................4" (
0tp@cd#p e 0tp@chdir .................................................................................................................4" 0tp@m7dir e 0tp@rmdir ...............................................................................................................4" 0tp@nlist ....................................................................................................................................44 0tp@get ......................................................................................................................................44 0tp@p#t ......................................................................................................................................44 3#nzioni legate al protocollo 3 P 9 %%%..........................................................................................4$ 0tp@size .....................................................................................................................................4$ 0tp@mdtm ..................................................................................................................................4$ 0tp@rename e 0tp@delete ............................................................................................................4$ 0tp@A#it .....................................................................................................................................4$ Le estensioni..................................................................................................................................$' %l perch delle estensioni ..........................................................................................................$& La programmazione ad oggetti......................................................................................................$& Le classi astratte.............................................................................................................................$1 Le costanti di classe e altre 0#nzionalitB........................................................................................$4 C#ove classi b#ilt9in......................................................................................................................$6 Guida PHP pratica.........................................................................................................................&'& %ntrod#zione.................................................................................................................................&'& % primi esempi con PHP...............................................................................................................&'& 6n contatore di visite personalizzato...........................................................................................&'1 .seg#ire l'#pload di #n 0ile..........................................................................................................&'6 %nvio di email da #na pagina web................................................................................................&'" %l modello di #n'applicazione dinamica.......................................................................................&'$ +ccedere al database !,*8L......................................................................................................&'$ %nterrogare e modi0icare #na tabella............................................................................................&&' Le tabelle e la str#tt#ra dei 0ile....................................................................................................&&( La vis#alizzazione degli articoli..................................................................................................&&( L'inserimento di #n articolo e la vis#alizzazione del dettaglio....................................................&&4 Guida PHP e MySql pratica...........................................................................................................&&" %ntrod#zione.................................................................................................................................&&" ;asi di dati e modello relazionale................................................................................................&&" La connessione a !,*8L............................................................................................................&&$ Chi#s#ra di #na connessione a !,*8L.......................................................................................&(& L'estensione !,*8Li..................................................................................................................&(( Creazione del database.................................................................................................................&(4 *elezione del database.................................................................................................................&(5 Creazione delle tabelle.................................................................................................................&(" La str#tt#ra delle tabelle..............................................................................................................&(4 La tabella per il login...................................................................................................................&1' 3#nzioni PHP per l'estrazione dei dati.........................................................................................&11 L'+#tenticazione..........................................................................................................................&14 %nserimento dei post.....................................................................................................................&16 La 0ormattazione dei post............................................................................................................&14 )is#alizzazione dei post nella homepage....................................................................................&1$ )is#alizzazione di #n singolo post...............................................................................................&4& %l mod#lo per l'inserimento dei commenti...................................................................................&41 !oderazione dei commenti.........................................................................................................&45 Conteggio e vis#alizzazione dei commenti.................................................................................&44 6n semplice motore di ricerca per il blog....................................................................................&4$
Cos' PHP
+ metB degli anni Covanta il 5eb era ancora 0ormato in gran parte da pagine statiche2 cio da doc#menti H !L il c#i conten#to non poteva cambiare 0ino a A#ando A#alc#no non interveniva man#almente a modi0icarlo. Con l'evol#zione di %nternet2 perD2 si cominciD a sentire l'esigenza di rendere dinamici i conten#ti2 cio di 0ar sE che la stessa pagina 0osse in grado di proporre conten#ti diversi2 personalizzati in base alle pre0erenze degli #tenti2 opp#re estratti da #na base di dati FdatabaseG in contin#a evol#zione. PHP nasce nel 19942 ad opera di ?asm#s Lerdor02 come #na serie di macro la c#i 0#nzione era A#ella di 0acilitare ai programmatori l'amministrazione delle homepage personali: da A#i trae origine il s#o nome2 che allora signi0icava app#nto Personal Home Page. %n seg#ito2 A#este macro 0#rono riscritte ed ampliate 0ino a comprendere #n pacchetto chiamato 3orm %nterpreter FPHPH3%G. .ssendo #n progetto di tipo open so#rce Fcio Icodice apertoI2 A#indi disponibile e modi0icabile da t#ttiG2 ben presto si 0ormD #na ricca com#nitB di svil#ppatori che portD alla creazione di PHP 3: la versione del ling#aggio che diede il via alla crescita esponenziale della s#a popolaritB. ale popolaritB era dov#ta anche alla 0orte integrazione di PHP con il 5eb server +pache Fil piJ di00#so in reteG2 e con il database !,*8L. ale combinazione di prodotti2 integralmente ispirata alla 0iloso0ia del 0ree so0tware2 diventD ben presto vincente in #n mondo in contin#a evol#zione come A#ello di %nternet. +lla 0ine del &$$4 erano circa (5'.''' i server 5eb che s#pportavano PHP: #n anno dopo s#peravano il milione. % ( milioni 0#rono toccati in aprile del ('''2 e alla 0ine dello stesso anno erano addiritt#ra 4.4''.'''. %l (''' stato sic#ramente l'anno di maggiore crescita del PHP2 coincisa anche con il rilascio della ersione 42 con #n n#ovo motore FKendG molto piJ veloce del precedente ed #na l#nga serie di n#ove 0#nzioni2 0ra c#i A#elle importantissime per la gestione delle sessioni. La crescita di PHP2 nonostante sia rimasta bloccata 0ra l#glio e ottobre del (''&2 poi proseg#ita toccando A#ota ".1''.''' server alla 0ine del (''&2 per s#perare i &' milioni alla 0ine del (''(2 A#ando stata rilasciata la ersione 4!3!". La contin#a evol#zione dei ling#aggi di programmazione concorrenti e l'incremento notevole dell'#tilizzo del ling#aggio anche in applicazioni enterprise ha portato la Kend a svil#ppare #na n#ova versione del motore per s#pportare #na str#tt#ra ad oggetti molto piJ rigida e potente. Casce cosE PHP #2 che si propone come innovazione nell'ambito dello svil#ppo web open so#rce sopratt#tto grazie agli str#menti di s#pporto pro0essionali 0orniti con la distrib#zione standard ed al grande s0orzo di Kend che2 grazie alla partnership con %;!2 sta cercando di spingere s#l mercato sol#zioni di s#pporto enterprise a A#esto ottimo ling#aggio. Lo svil#ppo di PHP procede com#nA#e con d#e progetti paralleli che s#pportano ed evolvono sia la versione 4 che la versione 5. 8#esta scelta stata 0atta poich t#ttora sono pochi i 0ornitori di hosting che hanno deciso di 0are il porting dei propri server alla n#ova versione del ling#aggio. 4
-ggi PHP conosci#to come PHP: H,perteLt Preprocessor2 ed #n ling#aggio completo di scripting2 so0isticato e 0lessibile2 che p#D girare praticamente s# A#alsiasi server 5eb2 s# A#alsiasi sistema operativo F5indows o 6niLHLin#L2 ma anche !ac2 +*H4''2 Covell2 -*H( e altriG2 e consente di interagire praticamente con A#alsiasi tipo di database F*8Lite2 !,*8L2 Postgre*8L2 *8L *erver2 -racle2 *,;ase2 +ccess e altriG. *i p#D #tilizzare per i piJ svariati tipi di progetti2 dalla semplice home page dinamica 0ino al grande portale o al sito di e9commerce.
delle pagine richieste. Cell'esempio che abbiamo visto prima2 pagina& aveva l'estensione .html2 mentre pagina( aveva l'estensione .php: s#lla base di A#esto2 il server sa che nel secondo caso deve eseg#ire PHP2 mentre nel primo p#D spedire il 0ile cosE com'. %n realtB il server deve essere istr#ito per poter 0are ciD: generalmente gli si dice di eseg#ire PHP per le pagine che hanno estensione .php. O possibile com#nA#e assegnargli A#alsiasi altra estensione F0ino a A#alche anno 0a veniva #tilizzata phtml2 anche se ormai la pratica cad#ta in dis#soG. *i possono #tilizzare anche le estensioni standard .htm e .html2 ma ciD signi0icherebbe chiamare PHP per t#tte le pagine richieste2 anche se non contengono codice PHP: A#esto rallenterebbe in#tilmente il lavoro del server e d#nA#e meglio evitarlo.
str#menti di s#pporto pro0essionali per gli svil#ppatori2 A#ali Kend *t#dio 5.'2 Kend *a0e /#ard ed altri str#menti che coprono per0ettamente t#tto il processo di svil#ppo e mantenimento del so0tware. Con t#tto rose e 0iori p#rtroppo: per esempio il 0atto che PHP venga distrib#ito in d#e versioni di00erenti Ft#ttora la 4 e la 5G li%ita gli s iluppatori nell'#tilizzo delle caratteristiche della n#ova versione2 dato che la maggior parte dei servizi di hosting contin#ano ad aggiornare A#ella precedente. -ltret#tto il 0atto che PHP 0#nzioni ad estensioni non sempre #n vantaggio2 dato che spesso e volentieri i vari servizi di hosting hanno con0ig#razioni di00erenti. 6n'altra lac#na2 che obbliga gli svil#ppatori a svil#ppare codice speci0ico per raggirarla2 la mancanza del s#pporto per caratteri 6nicode che rende piJ complicato lo svil#ppo di applicazioni m#ltiling#a per paesi che accettano caratteri speciali all'interno delle loro parole. 3ort#natamente la versione 6 di PHP Fche t#tt'ora in svil#ppoG incl#derB nativamente A#esto s#pporto. %nsomma: PHP #n ottimo ling#aggio2 leader tra A#elli open so#rce per lo svil#ppo web2 molto semplice da imparare e s#bito prod#ttivo. -ltret#tto ha #na serie di str#menti di appoggio molto completi e con la versione 5 #n rob#sto s#pporto per la programmazione ad oggetti. +nche se con A#alche di0etto2 penso sia la scelta piJ adeg#ata per #n gran n#mero di sit#azioni.
PHP e l'H+M$
PHP #n ling#aggio la c#i 0#nzione 0ondamentale A#ella di prod#rre codice H !L2 che A#ello dal A#ale sono 0ormate le pagine 5eb. !a2 poich PHP #n ling#aggio di programmazione2 abbiamo la possibilitB di analizzare diverse sit#azioni Fl'inp#t degli #tenti2 i dati conten#ti in #n databaseG e di decidere2 di conseg#enza2 di produrre codice H+M$ condi&ionato ai ris#ltati dell'elaborazione. 8#esto 2 in parole povere2 il 5eb dinamico. Come abbiamo visto precedentemente2 A#ando il server riceve #na richiesta per #na pagina PHP2 la 0a analizzare dall'interprete del ling#aggio2 il A#ale restit#isce #n 0ile contenente solo il codice che deve essere inviato al browser Fin linea di massima H !L2 ma p#D esserci anche codice =ava*cript2 0ogli di stile C** o A#al#nA#e altro conten#to 0r#ibile da #n browser2 come immagini e doc#menti Pd0G. <etto A#esto2 come avviene la prod#zione di codice H !LN La prima cosa da sapere come 0a l'interprete PHP a discernere A#ale porzione di #n 0ile contiene codice da elaborare e A#ale codice da restit#ire solamente all'#tente. 8#esta 0ase di riconoscimento molto importante2 dato che permette a PHP di essere incl#so all'interno di normale codice H !L in modo da renderne dinamica la creazione. %l codice PHP deve essere compreso 0ra appositi tag di apert#ra e di chi#s#ra2 che sono i seg#enti:
<?php //tag di apertura ?> //tag di chiusura
#tto ciD che conten#to 0ra A#esti tag deve corrispondere alle regole sintattiche del PHP2 ed codice che sarB eseg#ito dall'interprete e non sarB inviato direttamente al browser al browser. Per generare l'o#tp#t da inviare al browser attraverso codice PHP viene normalmente #tilizzato il costr#tto echo. )ediamo #n semplice esempio2 composto da codice H !L e codice PHP Fil codice PHP evidenziato in rossoG:
<html> <head> <title> <?php echo "Pagina di prova PHP"; ?>
"
</title> </head> <bod > <?php echo "!uona giornata""; ?> </bod > </html>
8#indi l'#tente vedrB s#l s#o browser la riga I;#ona giornataMI. O opport#no ricordare che il dato da inviare al browser che seg#e il comando echo p#D essere racchi#so tra parentesi e che al comando possono essere date in inp#t piJ stringhe FA#esto il nome che viene dato ad #na ripetizione di A#al#nA#e carattere compreso tra d#e apici singoli F# #G o doppi F" "GG2 separate da virgole2 cosE:
echo "!uongiorno a tutti""$ "<br />%n"$ "& una bellissima giornata";
*e si decide di #tilizzare il separatore virgola2 non possono essere #tilizzate le parentesi. Cel prosieg#o del corso #seremo spesso il verbo 'stampare' ri0erito alle azioni prodotte dal comando echo o da istr#zioni con 0#nzionalitB analoghe FA#ali print2 sprint' e altroG: ricordiamoci perD che si tratta di #na convenzione2 perch in A#esto caso la 'stampa' non avviene s# carta2 ma s#ll'inp#t che verrB inviato al browserM 3acciamo caso ad #n dettaglio: nelle istr#zioni in c#i stampavamo I;#ongiorno a t#ttiI2 abbiamo inserito2 dopo il <br />2 il simbolo %n. 8#esto simbolo ha #na 0#nzione abbastanza importante nella programmazione e nello scripting che serve piJ che altro per dare leggibilitB al codice H !L che stiamo prod#cendo. %n0atti PHP2 A#ando trova A#esta combinazione di caratteri 0ra virgolette2 li tras0orma in #n carattere di ritorno a capo: A#esto ci permette di controllare l'impaginazione del nostro codice H !L. ;isogna perD stare molto attenti a non con0ondere il codice H !L con il la,o#t della pagina che l'#tente vis#alizzerB s#l browser: in0atti2 s#l browser solo il tag <br /> che 0orza il testo ad andare a capo. 8#ando A#esto tag non c'2 il browser allinea t#tto il testo proseg#endo s#lla stessa linea Falmeno 0ino a A#ando gli altri elementi della pagina e le dimensioni della 0inestra non gli IconsiglianoI di 0are diversamenteG2 anche se il codice H !L ha #n ritorno a capo. )ediamo di chiarire A#esto concetto con #n paio di esempi:
<?php echo "prima riga%n"; echo "seconda riga<br />"; echo "ter(a riga"; ?>
8#esto perch il codice PHP2 mettendo il codice 'newline' dopo il testo 'prima riga'2 0a sE che il codice H !L venga 0ormato con #n ritorno a capo dopo tale testo. %l 0ile ricev#to dal browser A#indi andrB a capo proprio lE. %l browser2 perD2 non trovando #n tag che gli indichi di andare a capo2 a00iancherB la 0rase 'prima riga' alla 0rase 'seconda riga'2 limitandosi a mettere #no spazio 0ra le d#e. *#ccessivamente accade l'esatto contrario: PHP prod#ce #n codice H !L nel A#ale il testo 'seconda riga' seg#ito dal tag <br />2 ma non dal codice 'newline'. Per A#esto2 nel 0ile H !L2 'seconda riga<br />' e 'ter(a riga' vengono attaccati. %l browser2 perD2 A#ando trova il tag <br /> porta il testo a capo. +vrete 0orse notato che in 0ondo ad ogni istr#zione PHP abbiamo messo #n p#nto e virgolaP in0atti la sintassi del PHP prevede che il p#nto e virgola debba obbligatoriamente chi#dere ogni istr#zione. ?icordiamoci A#indi di metterlo sempre2 con A#alche eccezione che vedremo piJ avanti. <a A#anto abbiamo detto 0inora emerge #na realtB molto importante: chi v#ole avvicinarsi al PHP deve giB avere #na conoscenza appro0ondita di H !L e di t#tto A#anto p#D 0ar parte di #na pagina web Fsi consiglia per A#esto di leggere le nostre /#ide all'H !L Fhttp:HHLhtml.html.itHg#ideHleggiH5&Hg#ida9 htmlHG2 al =ava*cript Fhttp:HH:avascript.html.itHg#ideHleggiH(6Hg#ida9:avascript9per9esempiHG2 e ai C** Fhttp:HHcss.html.itHg#ideHleggiH(Hg#ida9css9di9baseHGG. 8#esto perch lo scopo principale di PHP proprio la prod#zione di A#esti codici Fanche se va ricordato che p#D essere #tilizzato per scopi di00erenti2 come ling#aggio di shell o per la creazione di applicazioni des7top grazie all'estensione PHP9/ > Fhttp:HHphp.html.itHarticoliHleggiH444Hintrod#zione9a9phpgt7HGG.
+bbiamo perD la possibilitB di #sare anche alc#ne sintassi alternative2 che sono com#nA#e sconsigliate per permettere #na corretta distrib#zione e portabilitB dei propri progetti. %n primo l#ogo2 in script scritti in versioni precedenti di PHP2 potremmo trovare il classico tag <script> con speci0icato esplicitamente il ling#aggio PHP:
<script language)"php"> ....... </script>
6n'altra possibilitB A#ella di #sare i tag brevi2 che devono essere abilitati man#almente $
?icordiamoci t#ttavia che in PHP 5 la con,igura&ione standard disabilita i tag brevi. 6n'#ltima possibilitB A#ella di #sare i tag in Istile +*PI:
<* .... *>
+nche A#esti perD devono essere abilitati in php.ini e sono praticamente in#tilizzati dalla maggior parte dei programmatori. #tta A#esta varietB di sintassi ca#sata dalla volontB degli svil#ppatori di mantenere la retroco%patibilit- con le vecchie versioni che2 a ca#sa di scelte di00erenti di design2 permettevano l'#tilizzo di tag alternativi. O bene ricordare che rimane b#ona pratica #tilizzare i tag completi evitando se possibile i tag brevi ed escl#dendo le altre possibilitB. Per chi non ci avesse 0atto caso2 p#nt#alizzo #n concetto molto importante: i tag deli%itano il codice PHP2 ed il codice conten#to al loro interno non sarB inviato al browser2 ma compilato e eseg#ito. <a A#esto potremmo ded#rre che t#tto ciD che sta 0#ori da A#esti tag non verrB toccato da PHP2 che si limiterB a passarlo al browser cosE com'2 event#almente ripetendolo in base a sit#azioni particolari che vederemo in seg#ito. %n linea di massima bene ricordare che scrivere:
<?php echo "<strong>"; ?> prova</strong>
e:
<strong>prova</strong>
. co%%enti
6n altro argomento molto importante legato alla sintassi di PHP sono i co%%enti. Chi ha esperienza2 anche minima2 di programmazione2 sa bene che molte volte i commenti si rivelano di importanza decisiva A#ando si tratta di mettere le mani s# #n programma realizzato da A#alc#n altro2 e anche A#ando il programma stato scritto da noi stessi2 sopratt#tto se passato A#alche tempo dalla realizzazione. % commenti svolgono #n r#olo 0ondamentale in A#esta 0ase di IrivisitazioneI del codice2 in A#anto possono 0acilitare di molto la comprensione di passaggi apparentemente osc#ri. O bene A#indi non risparmiare mai #n commento A#ando possibile Fsenza com#nA#e esagerare altrimenti2 al posto di chiarire il codice lo renderete ancora piJ illeggibileG2 anche perch il loro #tilizzo non appesantisce l'esecu&ione dello script Fl'interprete PHP salta t#tte le parti che riconosce come commentiG2 n il tras0erimento della pagina al browser Fin0atti i commenti2 essendo conten#ti all'interno del codice PHP2 0anno parte di ciD che non viene inviato al browserG. +bbiamo tre diverse possibilitB per posizionare i commenti all'interno del nostro codice: la prima &'
La seconda sono i commenti in stile Perl e P,thon2 contraddistinti dall'#so del cancelletto Fanche se ormai obsoleti e poco #tilizzatiG:
<?php - +ommento in stile Perl - e p thon ?>
.ntrambi A#esti tipi di commenti sono limitati ad #na sola riga: l'interprete PHP2 A#ando trova le barre o il cancelletto2 salta t#tto ciD che si trova da A#el p#nto 0ino al termine della riga. 8#esto ci permette di porre il commento anche s#lla stessa riga del codice commentato2 cosE:
<?php echo #!uongiorno a tutti <br />#; //stampo un messaggio di saluto print #.sclusi /uelli antipatici#; - 'accio una precisa(ione // 0uesta riga contiene solo commento ?>
L'#ltimo tipo di commento che abbiamo a disposizione permette di speci0icare commenti m#ltilinea senza dover ripetere i caratteri ogni n#ova riga grazie ad #na coppia di caratteri #tilizzati per l'apert#ra e la chi#s#ra. #tto il codice che seg#e HR viene considerato commento da PHP 0inch non incontra la serie di caratteri RH. 6n semplice esempio: SNphp HR 8#esto #n commento m#ltiriga speci0icando #tilizzando la stessa sintassi #sata in =ava e C RH echo HR commento RH ICiao a t#ttiI HR i commenti vengono saltatiRHP NT ?ig#ardo i commenti m#ltilinea2 importante ricordare che non possono essere innestati e che com#nA#e rappresentano #n separatore per l'interprete PHP. Per A#esto motivo le seg#enti sintassi sono errate: SNphp HR Commento HR m#ltilinea RH 8#i verrB generato #n errore ... RH ecHR A#esta sintassi errata RHho IprovaIP NT &&
La scelta di A#ale tipo di commento #tilizzare solitamente soggettiva2 anche se spesso vengono #tilizzati i commenti m#ltiriga per doc#mentare il codice e A#elli a riga singola per aggi#ngergli dei semplici app#nti s#l 0#nzionamento logico.
$e ariabili
Le variabili sono componenti 0ondamentali di A#alsiasi ling#aggio di programmazione2 in A#anto ci consentono di trattare i dati del nostro progra%%a senza sapere a priori A#ale sarB il loro valore. Possiamo immaginare #na variabile come #na specie di contenitore all'interno del A#ale viene conservato il valore che ci interessa2 e che p#D cambiare di volta in volta. %n PHP possiamo scegliere il nome delle variabili #sando lettere2 n#meri ed il trattino di sottolineat#ra2 o #nderscore F1G. %l primo carattere del nome deve essere perD #na lettera o #n #nderscore Fnon #n n#meroG. <obbiamo inoltre ricordare che il nome delle variabili sensibile all'uso delle %aiuscole e delle %inuscole: di conseg#enza2 se scriviamo d#e volte #n nome di variabile #sando le mai#scole in maniera di00erente2 per PHP si tratterB di d#e variabili distinteM %n PHP il nome delle variabili preced#to dal si%bolo del dollaro F2G. PHP ha #na caratteristica che lo rende molto piJ 0lessibile rispetto ad altri ling#aggi di programmazione: non richiede2 in0atti2 che le variabili vengano dichiarate prima del loro #so. Possiamo A#indi permetterci di ri0erirci ad #na variabile direttamente con la s#a valorizzazione:
<?php 2a ) 3; ?>
Con A#esta riga di codice de0iniamo la variabile a2 assegnandole il valore 3. %n 0ondo all'istr#zione abbiamo il p#nto e virgola2 che2 come giB accennato in precedenza2 deve chi#dere t#tte le istr#zioni PHP. L'#tilitB di #na variabile diventa 0ondamentale nel momento in c#i possibile #tilizzarla all'interno di espressioni matematiche o logiche. )ediamo #n semplice esempio:
<?php 2a ) 4; 2b ) 5; 2c ) 2a 6 2b; echo "7l risultato dell#opera(ione 84 6 59 : ;"; echo 2c; ?>
%n A#esto brano di codice abbiamo valorizzato tre variabili: a2 alla A#ale stavolta abbiamo dato il valore 4P b2 a c#i abbiamo assegnato il valore 5 e c2 che dovrB ass#mere il valore del prodotto di a e b. %n0ine abbiamo stampato il ris#ltato otten#to. .videntemente2 dopo l'esec#zione del codice c varrB <=. &(
Cegli esempi abbiamo visto l'ini&iali&&a&ione delle ariabili2 termine che sta ad indicare la prima volta in c#i assegniamo #n valore ad #na variabile. %n realtB2 possiamo ri0erirci ad #na variabile anche senza che sia stata inizializzata2 anche se A#esta ris#lta #n'operazione sconsigliata e potrebbe generare errori d#rante l'esec#zione in base ad alc#ne direttive di con0ig#razione di PHP che vedremo piJ avanti. +d esempio2 s#pponendo che nel nostro script non sia stata valorizzata ness#na variabile (2 potremmo avere #n'istr#zione di A#esto genere:
<?php echo 2(; ?>
8#esto codice non prod#rrB alc#n o#tp#t2 in A#anto la variabile ( non esiste. /li errori generati A#ando si cerca di #tilizzare in lett#ra #na variabile non inizializzata sono di tipo .1>?@7+.: sono gli errori di livello piJ basso2 cio meno gravi2 che normalmente non vengono mostrati da PHP2 ma che possiamo abilitare attraverso il 0ile di con0ig#razione php.ini. 6n errore di A#esto genere in e00etti non compromette il b#on 0#nzionamento dello script2 che in0atti viene eseg#ito regolarmenteP perD potrebbe essere #g#almente indice di #n A#alche errore commesso da chi ha scritto il codice. 3acciamo #n esempio per chiarire meglio A#anto esposto:
<?php 2a ) A5; 2b ) 24; 2risultato ) 2a , 2b; echo 2risulato; ?>
8#esto codice vorrebbe assegnare i valori A5 e 24 a d#e variabili2 poi sommarli e in0ine stampare il ris#ltato. PerD contiene #n errore: nell'istr#zione di stampa abbiamo indicato la variabile risulato invece che risultato. Chi ha scritto il codice si aspetterebbe di vedere comparire s#l browser il ris#ltato 1B<2 invece non troverB proprio n#lla2 perch la variabile risulato non de0inita2 e A#indi non ha ness#n valore. *i p#D perdere anche molto tempo alla ricerca del problema Fin realtB A#esto sembra #n problema banalissimo2 ed in e00etti lo P perD ricordiamoci che #n caso del genere potrebbe presentarsi in #n contesto molto piJ complesso2 ed inoltre molto spesso #n errore semplice come A#esto si dimostra molto piJ di00icile da scovare per chi lo ha commessoG. 8#i perD la segnalazione di errore di PHP p#D venirci in ai#to: in0atti2 se siamo abit#ati ad #tilizzare le variabili nella maniera piJ corretta2 cio dopo averle inizializzate2 #n errore come A#esto ci indica chiaramente che abbiamo sbagliato a scrivere il nome. Per A#esto il nostro consiglio A#ello di tenere abilitata la isuali&&a&ione degli errori anche di tipo .1>?@7+.2 e di #tilizzare le variabili solo se inizializzate o dopo aver controllato la loro esistenza. %n A#esto modo impareremo da s#bito a programmare in maniera piJ corretta e2 anche se impiegheremo A#alche min#to in piJ per cominciare2 risparmieremo tante ore Fe tanto 0egatoG per il 0#t#ro... Concl#diamo A#esta lezione s#lle variabili con #n accenno alle variabili dinamiche2 pratica t#ttora sconsigliata ma che potrebbe capitarvi di incontrare in contesti relativi a script di vecchia 0att#raP in A#alche sit#azione p#D presentarsi la necessitB di #tilizzare delle variabili senza sapere a priori il loro nome. %n A#esti casi2 il nome di A#este variabili sarB conten#to in #lteriori variabili. &1
3acciamo #n esempio: col codice seg#ente stamperemo a video il conten#to delle variabili pippo2 pluto e paperino:
<?php 2pippo ) #gawrsh"#; 2pluto ) #bau"#; 2paperino ) #/uacC"#; 2nome ) #pippo#; echo 22nome.#<br>#; 2nome ) #pluto#; echo 22nome.#<br>#; 2nome ) #paperino#; echo 22nome.#<br>#; ?>
%l ris#ltato s#l browser sarB gawrsh"2 bau" e /uacC"2 ciasc#no s#lla propria riga Fin0atti ogni istr#zione print crea il tag H !L SbrT che indica al browser di andare a capoP vedremo piJ avanti che il p#nto serve a concatenare i valori che vengono stampatiG. %l doppio segno del dollaro ci permette in0atti di #sare la variabile nome come contenitore del nome della variabile di c#i vogliamo stampare il valore. %n pratica2 come se avessimo detto a PHP: Ustampa il valore della variabile che si chiama come il valore della variabile nomeV. 8#esto era #n esempio banale2 e l'#so delle variabili dinamiche era in realtB per0ettamente in#tile2 in A#anto sapevamo benissimo come si chiamavano le variabili che ci interessavano. PerD in sit#azioni reali p#D capitare di trovarsi in #n ambito nel A#ale non sappiamo come si chiamano le variabili2 e dobbiamo #sare altre variabili per ricavarne il nome2 oltrech il valore.
. tipi di dato
6na variabile p#D contenere diversi tipi di valori2 ogn#no dei A#ali ha #n comportamento ed #n'#tilitB di00erente. +nalizzeremo brevemente i tipi di dato che PHP permette di #tilizzare all'interno del proprio codice premettendo che PHP2 a di00erenza di altri ling#aggi2 associa il tipo di dato al valore e non alla variabile Fad esempio possiamo assegnare alla stessa variabile #na stringa e poi #n n#mero senza incorrere in alc#n erroreG ed e00ett#a conversioni a#tomatiche dei valori nel momento in c#i siano richiesti tipi di dato di00erenti Fad esempio in #n'espressioneG.
/alore booleano
% tipi di dato boolean servono per indicare i valori vero o 0also all'interno di espressioni logiche. %l tipo booleano associato alle variabili che contengono il ris#ltato di #n'espressione booleana opp#re i valori tr#e e 0alse. )ediamo #n rapido esempio:
<?php 2vero ) true; 2'also ) 'alse; ?>
&4
.ntero
6n n#mero intero2 positivo o negativo2 il c#i valore massimo Fassol#toG p#D variare in base al sistema operativo s# c#i gira PHP2 ma che generalmente si p#D considerare2 per ricordarlo 0acilmente2 di circa ( miliardi F( elevato alla 1&esima potenzaG.
<?php 2int1 ) 124; 2int2 ) DA13; 2int< ) 3 6 E; //2int< vale 5B ?>
/irgola %obile
6n n#mero decimale Fa volte citato come Ido#bleI o IrealIG. +ttenzione: per indicare i decimali non si #sa la virgola2 ma il p#nto. +nche in A#esto caso la dimensione massima dipende dalla piatta0orma. Cormalmente com#nA#e si considera #n massimo di circa &.4e1'4 con #na precisione di &4 ci0re decimali. *i possono #tilizzare le seg#enti sintassi:
<?php 2vm1 ) 5.13<; // 5$13< 2vm2 ) <.2e3; // <$2 6 1BF3$ cio: <2B.BBB 2vm< ) 5.DE; // 5 6 1BFDE$ cio: 5/1BB.BBB.BBB ) B$BBBBBBB5 ?>
Stringa
6na stringa #n A#alsiasi insieme di caratteri2 senza limitazione normalmente conten#to all'interno di #na coppia di apici doppi o apici singoli. Le stringhe delimitate da apici sono la 0orma piJ semplice2 consigliata A#ando all'interno della stringa non vi sono variabili di c#i vogliamo ricavare il valore:
<?php 2'rase ) #Gnna disse; "+iao a tutti"" ma nessuno rispose#; echo 2'rase; ?>
8#esto codice stamperB la 0rase: '+nna disse: ICiao a t#ttiMI ma ness#no rispose'. /li apici doppi ci consentono di #sare le stringhe in #na maniera piJ so0isticata2 in A#anto2 se all'interno della stringa delimitata da virgolette PHP riconosce #n nome di variabile2 lo sostit#isce con il valore della variabile stessa.
<?php 2nome ) #Gnna#; echo "2nome : simpatica... a pochi"; // stampa; Gnna : simpatica... a pochi echo #2nome : simpatica... a pochi#; // stampa; 2nome : simpatica... a pochi echo "H2nomeI : simpatica a pochi"; // : una sintassi alternativa$ con lo stesso e''etto della prima ?>
Ci sono #n paio di regole molto importanti da ricordare A#ando si #sano le stringhe delimitate da apici o virgolette: siccome p#D capitare che #na stringa debba contenere a s#a volta #n apice o #n &5
paio di virgolette2 abbiamo bisogno di #n sistema per 0ar capire a PHP che A#el carattere 0a parte della stringa e non il s#o delimitatore. %n A#esto caso si #sa il cosiddetto 'carattere di escape'2 cio la barra rovesciata Fbac7slash: WG. )ediamo alc#ni esempi:
<?php echo #@orniamo un%#altra volta#; // stampa; @orniamo un#altra volta echo "@orniamo un#altra volta"; // stampa; @orniamo un#altra volta echo "@orniamo un%#altra volta"; // stampa; @orniamo un%#altra volta echo #@orniamo un#altra volta#; // causa un errore$ perch: l#apostro'o viene scambiato per l#apice di chiusura echo #Gnna disse "+iao" e se ne andJ#; // stampa; Gnna disse "+iao" e se ne andJ echo "Gnna disse %"+iao%" e se ne andJ"; // stampa; Gnna disse "+iao" e se ne andJ echo #Gnna disse %"+iao%" e se ne andJ#; // stampa; Gnna disse %"+iao%" e se ne andJ echo "Gnna disse "+iao" e se ne andJ"; // errore ?>
<a A#esti esempi si p#D capire che il bac0slash deve essere #tilizzato come carattere di escape A#ando vogliamo incl#dere nella stringa lo stesso tipo di carattere che la delimitaP se mettiamo #n bac7slash davanti ad #n apice doppio in #na stringa delimitata da apici singoli Fo viceversaG2 anche il bac7slash entrerB a 0ar parte della stringa stessa2 come si vede nel terzo e nel settimo esempio. %l bac7slash viene #sato anche come 'escape di s stesso'2 nei casi in c#i vogliamo esplicitamente incl#derlo nella stringa:
<?php echo "0uesto; echo #0uesto; echo "0uesto; echo "0uesto; ?> %"%%%" : un bacCslash"; %#%%%# : un bacCslash#9; #%# : un bacCslash"9; #%%# : un bacCslash"9; // // // // stampa; stampa; stampa; stampa; 0uesto; 0uesto; 0uesto; 0uesto; "%" #%# #%# #%# : : : : un un un un bacCslash bacCslash bacCslash bacCslash
+nalizziamo il primo esempio: il primo bac7slash 0a l'escape del primo paio di virgoletteP il secondo bac7slash 0a l'escape del terzo2 che A#indi viene incl#so nella stringaP il A#arto 0a l'escape del secondo paio di virgolette. %l secondo esempio eA#ivale al primo2 con l'#so degli apici al posto delle virgolette. Cegli #ltimi d#e casi non necessario 0are l'escape del bac7slash2 in A#anto il bac7slash che vogliamo stampare non p#D essere scambiato per #n carattere di escape Fin0atti vicino ad esso ci sono degli apici2 che in #na stringa delimitata da virgolette non hanno bisogno di escapeG. <i conseg#enza2 0are o non 0are l'escape del bac7slash in A#esta sit#azione la stessa cosa2 e di0atti i d#e esempi 0orniscono lo stesso ris#ltato. Passiamo ad esaminare l'#ltimo modo di rappresentare le stringhe: la sintassi heredoc2 poco #tilizzata se non in sit#azioni nelle A#ali necessario speci0icare stringhe molto l#nghe. 8#esta ci consente di delimitare #na stringa con i caratteri <<< seg#iti da #n identi0icatore Fin genere si #sa .?K2 ma solo #na convenzione: possibile #tilizzare A#alsiasi stringa composta di caratteri al0an#merici e #nderscore2 di c#i il primo carattere deve essere non n#merico: la stessa regola dei nomi di variabileG. #tto ciD che seg#e A#esto delimitatore viene considerato parte della stringa2 0ino a A#ando non viene ripet#to l'identi0icatore seg#ito da #n p#nto e virgola. +ttenzione: l'identi0icatore di chi#s#ra deve occ#pare #na riga a s stante2 deve iniziare a colonna & e non deve contenere ness#n altro carattere Fnemmeno spazi v#otiG dopo il p#nto e virgola.
<?php 2nome ) "Paolo";
&6
8#esto codice stamperB '%l mio nome Paolo'. %n0atti la sintassi heredoc risolve i nomi di variabile cosE come le virgolette. ?ispetto a A#este #ltime2 con A#esta sintassi abbiamo il vantaggio di poter incl#dere delle virgolette nella stringa senza 0arne l'escape:
<?php 2'rase ) "ciao a tutti"; 2stringa ) <<<.?@ 7l mio saluto : "2'rase" .?@; echo 2stringa; ?>
1rray
Possiamo considerare #n arra, come #na ariabile co%plessa2 che contiene #na serie di valori2 ciasc#no dei A#ali caratterizzato da #na chiave2 o indice che lo identi0ica #nivocamente. 3acciamo #n primo esempio2 de0inendo #n arra, composto di cinA#e valori:
2colori ) arra 8#bianco#$ #nero#$ #giallo#$ #verde#$ #rosso#9;
+ A#esto p#nto ciasc#no dei nostri cinA#e colori caratterizzato da #n indice n#merico2 che PHP assegna a#tomaticamente a partire da '. Per rec#perare #n determinato valore dalla variabile che contiene l'arra,2 s#00iciente speci0icare il s#o indice all'interno di parentesi A#adre dietro al nome della variabile:
echo 2coloriL1M; // stampa #nero# echo 2coloriL5M; // stampa #rosso#
/li arra, verranno trattati in modo piJ appro0ondito nella prossima lezione.
2ggetto
Le classi e gli oggetti sono d#e degli argomenti s#i A#ali gli svil#ppatori di PHP hanno vol#to p#ntare maggiormente nella n#ova versione. L'argomento verrB trattato in modo appro0ondito nella /#ida eorica a PHP.
-peratore di assegnazione
2nome ) #Niorgio#;
%l simbolo ')' serve in0atti ad assegnare alla variabile 2nome il valore #Niorgio#. %n generale2 possiamo dire che con l'operatore di assegnazione prendiamo ciD che sta alla destra del segno di #g#alianza F')'G ed assegnamo lo stesso valore a ciD che sta a sinistra. Potremmo ad esempio assegnare ad #na variabile il valore di #n'altra variabile:
2a ) 3; 2b ) 2a;
Con la prima istr#zione assegnamo ad 2a il valore 32 con la seconda assegnamo a 2b lo stesso valore di 2a. +ltri operatori molto 0acili da comprendere sono A#elli che permettono di e00ett#are operazioni aritmetiche s#i dati: addizione2 sottrazione2 divisione2 moltiplicazione2 mod#lo. -perazioni aritmetiche
2a 2b 2c 2d 2e ) ) ) ) ) < 3 4 E A , D 6 / * A; 2; =; 2; 5; // // // // // // addi(ione sottra(ione moltiplica(ione divisione modulo 8il modulo : il resto della divisione intera$ in /uesto caso <9
6no degli operatori piJ #tilizzati A#ello che serve per concatenare le stringhe( il punto. Concatenare le stringhe
2nome ) #pippo#; 2stringa1 ) #ciao # . 2nome; // 2stringa1 vale #ciao pippo#
Con l'operatore di assegnazione si p#D anche #sare #na variabile per e00ett#are #n calcolo il c#i ris#ltato deve essere assegnato alla variabile stessa. +d esempio2 s#pponiamo di avere #na variabile di c#i vogliamo a#mentare il valore:
2a ) 2a , 1B; // il valore di 2a aumenta di 1B
Con A#esta istr#zione2 viene eseg#ito il calcolo che sta alla destra del segno ')' ed il ris#ltato viene memorizzato nella variabile indicata a sinistra. ?is#lta chiaro che il valore della variabile 2a prima dell'istr#zione viene #tilizzato per il calcolo2 ma dopo che l'istr#zione stata eseg#ita viene #tilizzata per memorizzare il ris#ltato2 A#indi il s#o valore cambia. 6n ris#ltato di A#esto tipo si p#D ottenere anche con gli operatori di assegnazione combinati2 che ci permettono di rendere il codice piJ compatto: -perazioni di calcolo
2O 2O 2O 2O 2O 2O 2O ,) 5; D) <; .) 2a; . 2a9 /) 3; 6) 5; *) 2; // incrementa 2O di 5 8e/uivale a 2O ) 2O , 59 // decrementa 2O di < 8e/uivale a 2O ) 2O D <9 // il valore della stringa 2a viene concatenato a 2O 8e/uivale a 2O ) // e/uivale a 2O ) 2O / 3 // e/uivale a 2O ) 2O 6 5 // e/uivale a 2O ) 2O * 2
&4
%n A#esto modo diciamo a PHP che vogliamo assegnare alla variabile speci0icata a sinistra il ris#ltato dell'operazione che si trova prima del simbolo #g#ale applicandola alla variabile stessa ed al valore speci0icato a destra. PiJ 0acile a 0arsi che a dirsi. Cel caso 0osse necessario incrementare e decrementare #na variabile di #na sola #nitB2 ci vengono incontro gli operatori di incremento e decremento: %ncremento e decremento
2a,,; ,,2a; // incrementa di 1 2aDD; DD2a; // decrementa di 1
La di00erenza tra anteporre e posporre l'operatore di incremento o decremento 0ondamentale nel momento in c#i si #tilizzando A#esti operatori all'interno di espressioni. Per ora vi basti sapere che anteporre l'operatore alla variabile dice al compilatore di incrementare la variabile e s#ccessivamente #tilizzare il s#o valore all'interno dell'espressione2 mentre posporre l'operatore in0orma il compilatore che dovrB #tilizzare nell'espressione il valore att#ale e s#ccessivamente applicarvi l'incremento o il decremento.
&$
6na piccola osservazione s#l terzo con0ronto: siccome abbiamo assegnato il valore di 2b #sando la notazione col p#nto decimale2 per PHP 2b #na variabile del tipo in virgola mobile2 anche se in realtB il s#o valore intero. Per A#esto il con0ronto di identitB restit#isce 0also. 3ino a A#i abbiamo visto com#nA#e casi molto semplici perch t#tte le variabili avevano valori n#merici. /li stessi con0ronti perD si possono 0are anche con altri tipi di variabili2 ed in particolare con le stringhe. %n A#esto caso il con0ronto viene 0atto basandosi s#ll'ordine al0abetico dei caratteri: vale a dire che vengono considerati 'minori' i caratteri che 'vengono prima' nell'ordine al0abetico. 8#indi 'a' minore di 'b'2 'b' minore di 'c'2 eccetera. %noltre t#tte le lettere min#scole sono 'maggiori' delle lettere mai#scole2 e t#tte2 mai#scole e min#scole2 sono 'maggiori' delle ci0re da ' a $:
2a ) #Pario#; 2b ) #Niorgio#; 2c ) #Niovanni#; 2d ) #antonio#; 2e ) #5 gatti#; 2a 2b 2d 2c < < > > 2b; 2c; 2a; 2e; // // // // 'also$ la #N# precede la #P# vero$ la #r# 8#Nior#9 precede la #v# 8#Niov#9 vero$ la #a# minuscola : #maggiore# di /ualsiasi lettera maiuscola vero$ ogni lettera : #maggiore# di /ualsiasi ci'ra
<ato che PHP #n ling#aggio con #na tipizzazione debole permette di con,rontare tra loro ariabili contenenti tipi di dato di,,erenti cercando di tras0ormare le variabili in valori con0rontabili. *e per esempio e00ett#assimo #n con0ronto F))G tra #na variabile contenente l'intero #no F1G ed #na contenente la stringa #no F#1#G otterremmo #n valore di veritB dato che PHP tras0ormerebbe entrambi i valori in n#meri in modo che siano con0rontabili. Per assegnare A#esto valore n#merico2 PHP controlla se all'inizio della stringa ci sono dei n#meri: se ne trova2 considererB t#tti i n#meri che trova inizialmente come il valore n#merico di A#ella stringa. *e non ne trova2 il valore della stringa sarB B:
2a ) A; 2b ) 3; 2c)#molte persone#; 2d)#A persone#; 2e)#3#; 2a )) 2d; // vero$ 2d vale A 2a ))) 2d; // 'also$ valgono entrambi A ma 2a : un intero mentre 2d : una stringa 2b > 2c; // vero$ 2b vale 3 mentre 2c vale B 2e > 2c; // 'also; /uesto : un con'ronto 'ra due stringhe$ /uindi valgono le regole viste prima
Prestiamo attenzione all'#ltimo esempio: il valore di 2e era stato assegnato #sando gli apici2 e A#esto 0a sE che PHP lo consideri #na stringa anche se il conten#to #n n#mero. %l con0ronto 0ra #n n#mero e #na stringa p#D avvenire in maniera vol#ta2 ma piJ probabile che avvenga per caso2 A#ando cio #na variabile che pensavamo contenesse #n n#mero contiene in realtB #na stringa. O evidente che in A#esto caso potremo 0acilmente ottenere #n ris#ltato diverso da A#ello che ci aspettavamo2 o2 viceversa2 potremmo ottenere cas#almente il ris#ltato atteso: in A#est'#ltima sit#azione possibile che ris#ltati inaspettati arrivino piJ avanti nello script2 se #tilizzeremo di n#ovo la stessa variabile. %n t#tte A#este sit#azioni2 tener presente il modo in c#i PHP tratta A#esti con0ronti p#D essere di ai#to per spiegarci comportamenti apparentemente bizzarri del nostro script. O com#nA#e b#ona norma assic#rarsi che d#e espressioni restit#iscano ris#ltati dello stesso tipo A#ando si e00ett#ano con0ronti2 opp#re #tilizzare gli operatori ))) e ")) che tengono conto anche del tipo di dato #tilizzato.
('
2peratore
Per A#anto rig#arda gli operatori 'and' e 'or'2 le d#e diverse notazioni di00eriscono per il livello di precedenza in caso di espressioni complesse. %n0atti2 siccome possibile combinare molti operatori in espressioni anche assai complicate2 necessario sapere con A#ale ordine PHP val#ta i diversi operatori. 8#este regole ricalcano le regole algebriche in base alle A#ali moltiplicazioni e divisioni hanno la precedenza s# addizioni e sottrazioni2 ma sono piJ complesse perch devono considerare anche gli altri operatori. )ediamo A#indi A#al l'ordine di prioritB dei diversi operatori2 iniziando da A#elli che hanno la prioritB maggiore: &. -peratori di incremento e decremento F,, DDG (. !oltiplicazione2 divisione2 mod#lo F6 / *G 1. +ddizione e sottrazione F, DG 4. -peratori di con0ronto per minore e maggiore F< <) )> >G 5. -peratori di con0ronto per #g#aglianza e dis#g#aglianza F)) ))) ")G 6. -peratore logico 'and'2 nella notazione col simbolo FRRG ". -peratore logico 'or'2 nella notazione col simbolo FQQG 4. -peratori di assegnazione2 compresi A#elli 'sintetici' F) ,) D) /) 6) *) .)G $. -peratore logico 'and'2 nella notazione letterale FGndG &'.-peratore logico 'Lor' FSorG &&.-peratore logico 'or'2 nella notazione letterale F?rG +bbiamo giB visto prima2 in occasione degli esempi s#gli operatori logici2 l'applicazione di A#esti principi di precedenza: in0atti in t#tte A#elle espressioni venivano val#tati prima gli operatori di con0ronto e2 solo dopo2 A#elli logici. 6n'altra classica rappresentazione di esempio A#ella dell'espressione algebrica:
3 , 5 6 2; // /uesta espressione vale 1< e non 1E$ // perchT la moltiplica(ione viene eseguita prima
(&
// l#ordine di esecu(ione
Come abbiamo visto2 cosE come avviene in algebra2 #sando le parentesi possiamo determinare a nostro piacere A#ali operatori devono essere val#tati per primi. Per A#esto motivo2 sebbene sia possibile imparare a memoria l'ordine di precedenza che abbiamo visto poco 0a2 il nostro consiglio A#ello di non tenerne conto2 e di utili&&are se%pre le parentesi A#ando abbiamo bisogno di costr#ire #n'espressione #n po' complessa: in A#esto modo rid#rremo il rischio di errori2 e sopratt#tto renderemo il nostro codice molto piJ leggibile. %n0atti leggere #n'espressione regolata dalle parentesi molto piJ immediato che non doversi ricordare A#ali degli operatori hanno la precedenza s#gli altri.
$e espressioni
<opo A#esta breve introd#zione s#gli operatori2 possiamo de0inire #n'espressione come #na A#alsiasi combinazione di 0#nzioni Fv. lezioni s#ccessiveG2 valori e operatori che si risolvono in #n valore. Cel caso visto prima2 l'espressione "Q1 ha come valore &'. %n generale2 in PHP2 A#alsiasi cosa #tilizzabile come #n valore p#D essere considerata #n'espressione. )ediamo alc#ni rapidi esempi:
13 6 <; // espressione il cui valore : 53 #Niacomo# . # Uerdi#; // espressione il cui valore : #Niacomo Uerdi# 2a , 2b; // espressione il cui valore : dato dalla somma // dei valori delle variabili 2a e 2b
Come possiamo vedere2 A#indi2 la presenza di operatori 0a sE che il valore dell'espressione ris#lti diverso da A#ello dei singoli valori che 0anno parte dell'espressione stessa. )ediamo #n caso particolare2 A#ello dell'operatore di assegnazione:
2a ) =; // il valore di /uesta espressione : =
8#ando #siamo #na espressione per assegnare #n valore ad #na variabile2 il valore che tale espressione ass#me #g#ale a A#ello che si trova a destra dell'operatore di assegnazione Fche anche A#ello che viene assegnato all'operatore di sinistraG. 8#esto signi0ica che noi possiamo scrivere
echo #Paolo#; // stampa #Paolo# echo 82nome ) #Paolo#9; // stampa sempre #Paolo#
Le d#e espressioni hanno in0atti lo stesso valore2 cio 'Paolo'. 8#indi con le d#e istr#zioni viste sopra otteniamo s#l browser lo stesso ris#ltato. La di00erenza2 ovviamente2 che con la seconda2 oltre a stampare il valore a video2 abbiamo anche assegnato lo stesso valore alla variabile Xnome. )ediamo A#alche altro esempio:
A > 5; //valore dell#espressione; true 8vero9 2a ) A > 5; //valore dell#espressione; lo stesso di prima; //la variabile 2a assume /uindi il valore true 2b ) 3 6 5; //valore dell#espressione; 2B; viene assegnato a 2b
((
Precedentemente avevamo accennato ad #na di00erenza nella val#tazione dell'espressione 0ra i diversi modi di #tilizzare gli operatori di incremento e di decremento. )ediamo ora di appro0ondire A#esto concetto:
2a ) 1B; 2b ) 1B; ,,2a; // incrementiamo 2a$ che diventa 11; l#espressione vale 11 2b,,; // anche 2b diventa 11; /ui perJ l#espressione vale 1B
La di00erenza A#esta: se #siamo l'operatore di incremento Fo di decrementoG prima della variabile2 l'espressione ass#me il n#ovo valore della variabile stessa. *e invece lo mettiamo dopo2 l'espressione prenderB il valore che la variabile aveva prima dell'operazione. <i conseg#enza:
2a ) 2b ) echo echo echo 3; 3; ,,2a; // 2a diventa =$ e viene stampato #=# 2b,,; // anche 2b diventa =$ ma viene stampato #3# ,,2b; // a /uesto punto 2b : diventato A$ e viene stampato #A#
.stru&ione .,
Con le str#tt#re di controllo andiamo ad analizzare #n altro degli aspetti 0ondamentali della programmazione: la possibilit- cio di eseguire opera&ioni di erse2 ed event#almente di eseg#irle piJ volte2 in base alla val#tazione di determinate condizioni. %n A#esta lezione esamineremo le istr#zioni che ci permettono di eseg#ire o non eseg#ire certe porzioni di codice.
.,
La principale di A#este istr#zioni la i'2 la c#i sintassi piJ elementare la seg#ente:
i'8 <condi(ione> 9 H <codice> I
<opo l'i'2 deve essere indicata 0ra parentesi #n'espressione da val#tare FcondizioneG. 8#esta espressione verrB val#tata in senso booleano2 cio il s#o valore sarB considerato vero o 0also. Cel caso in c#i l'espressione non abbia #n valore booleano2 PHP convertirB com#nA#e A#esto valore in booleano #tilizzando precise regole che vedremo tra A#alche riga. <#nA#e2 se la condizione vera2 l'istr#zione s#ccessiva viene eseg#ita. %n caso contrario2 viene ignorata. Potremmo anche avere la necessitB di eseg#ire2 nel caso in c#i la condizione sia vera2 non #na sola ma piJ istr#zioni. 8#esto per0ettamente possibile2 ma dobbiamo ricordarci di comprendere A#esto blocco di istr#zioni 0ra d#e parentesi gra00e2 ad esempio cosE:
// .... i' 82nome )) #Vuca#9 H echo "ciao Vuca"<br>"; echo "dove sono i tuoi amici?<br>"; I echo "ciao a tutti voi";
(1
%n A#esto modo2 se la variabile 2nome ha e00ettivamente il valore 'L#ca' vengono eseg#ite le d#e istr#zioni s#ccessive2 comprese 0ra le parentesi gra00e. <opo avere val#tato la condizione ed event#almente eseg#ito le d#e istr#zioni previste2 lo script proseg#irB con ciD che sta 0#ori dalle parentesi gra00e. 8#indi nel nostro esempio la 0rase Iciao a t#tti voiI viene prodotta in ogni caso. O b#ona norma #sare com#nA#e le parentesi gra00e per delimitare il codice condizionato2 anche A#ando costit#ito da #na sola istr#zione: in0atti A#esto rende il codice piJ leggibile2 ed inoltre potrebbe evitarci degli errori se ci dovesse capitare di voler aggi#ngere delle istr#zioni al blocco condizionato dimenticando di aggi#ngere le gra00e. <obbiamo notare #n particolare2 rig#ardo alla sintassi di A#esta istr#zione: per la prima volta2 vediamo che in A#esto costr#tto mancano i p#nto e virgola. %n0atti la i' e la condizione espressa 0ra parentesi non devono averliP contin#iamo invece a metterli nel blocco di codice condizionato. +bbiamo detto poco 0a che la condizione espressa 0ra parentesi potrebbe non avere #n valore booleano. PHP perD in grado di considerare booleano A#alsiasi valore2 in base ad alc#ne regole molto semplici. 3acciamo #n altro esempio banale:
i' 839 H print "ciao Vuca""; I
8#esto codice2 da #n p#nto di vista logico2 non ha ness#n senso2 ma ci permette di capire come PHP interpreta le nostre espressioni. %n0atti in A#esto caso la stringa Iciao L#caMI verrB sempre stampata. 8#esto perch2 per PHP2 il valore 52 cosE come A#alsiasi n#mero diverso da '2 considerato 'vero'. %n sostanza2 PHP considera come 0alsi: il valore n#merico '2 nonch #na stringa che contiene ''' #na stringa v#ota #n arra, con zero elementi #n valore C6LL2 cio #na variabile che non stata de0inita o che stata eliminata con #nsetFG2 opp#re a c#i stato assegnato il valore C6LL esplicitamente
8#alsiasi altro valore2 per PHP #n valore vero. 8#indi A#alsiasi n#mero2 intero o decimale p#rch diverso da '2 A#alsiasi stringa non v#ota2 se #sati come espressione condizionale saranno considerati veri. 8#indi anche la banale espressione che abbiamo #tilizzato nell'esempio di prima. +nalizziamo ora #n caso che spesso crea problemi se non viene compreso 0in dalle prime batt#te. )ediamo A#esto codice
2a ) A; i' 82a ) 59 echo #2a : uguale a 5"#;
+ prima vista2 A#alc#no potrebbe essere ingannato da A#este istr#zioni2 sopratt#tto chi ha precedenti esperienze di programmazione in ling#aggi str#tt#rati diversamente2 nei A#ali #n'espressione come 2a ) 5 potrebbe essere sia #n'assegnazione che #n test. Costoro in0atti si aspetteranno che A#esto blocco di codice non stampi niente2 e rimarrebbero molto sorpresi2 A#alora lo provassero2 di vedere invece s#l browser la 0rase 'Xa #g#ale a 4'. 8#esto s#ccederebbe perch l'espressione che abbiamo messo 0ra parentesi #n'assegnazione: cio essa assegna alla variabile Xa il valore 4. L'istr#zione seg#ente viene A#indi eseg#ita2 per il motivo che abbiamo visto prima: il valore della nostra espressione 42 che per PHP #n valore vero. *e invece che i' 82a ) 59 avessimo scritto i' 82a ) B9 l'istr#zione seg#ente sarebbe stata saltata2 perch la nostra condizione avrebbe preso valore '2 cio 0also. Per ottenere il ris#ltato corretto logicamente2 avremmo dov#to #tilizzare l'operatore di con0ronto: (4
?icordiamoci A#indi2 A#ando vogliamo veri0icare se il valore di #na variabile #g#ale a A#alcosa2 di #tilizzare l'operatore condizionale di #g#aglianza2 cio il doppio #g#ale FIYYIG. %n caso contrario2 non solo otterremo molto spesso ris#ltati diversi da A#elli che ci saremmo aspettati2 ma avremo anche modi0icato il valore di #na variabile che volevamo soltanto veri0icare.
La parola chiave else2 che signi0ica 'altrimenti'2 deve essere posizionata s#bito dopo la parentesi gra00a di chi#s#ra del codice previsto per il caso 'vero' Fo dopo l'#nica istr#zione prevista2 se non abbiamo #sato le gra00eG. +nche per 'else' valgono le stesse regole: niente p#nto e virgola2 parentesi gra00e obbligatorie se dobbiamo esprimere piJ di #n'istr#zione2 altrimenti 0acoltative. -vviamente il blocco di codice speci0icato per 'else' viene ignorato A#ando la condizione vera2 mentre viene eseg#ito se la condizione 0alsa. Le istr#zioni i' possono essere nidi0icate #na dentro l'altra2 consentendoci cosE di creare codice di #na certa complessitB. .sempio:
i' 82nome )) #Vuca#9 H i' 82cognome )) #Wossi#9 H print "Vuca Wossi : di nuovo 'ra noi"; I else H print "Gbbiamo un nuovo Vuca""; I I else H print "ciao 2nome""; I
%n A#esto caso2 abbiamo nidi0icato #n #lteriore test all'interno del primo caso2 A#ello in c#i 2nome ha il valore 'L#ca'. +bbiamo in0atti previsto #n messaggio diverso2 a seconda del valore della variabile 2cognome.
3lsei,
6n'#lteriore possibilitB che ci 0ornisce l'istr#zione i' in PHP A#ella di #tilizzare la parola chiave elsei'. +ttraverso A#esta possiamo indicare #na seconda condizione2 da val#tare solo nel caso in c#i A#ella precedente ris#lti 0alsa. %ndicheremo A#indi2 di seg#ito2 il codice da eseg#ire nel (5
caso in c#i A#esta condizione sia vera2 ed event#almente2 con else2 il codice previsto per il caso in c#i anche la seconda condizione 0alsa.
i' 82nome )) #Vuca#9 H print "bentornato Vuca""; I elsei' 82cognome )) #Uerdi#9 H print "!uongiorno$ signor Uerdi"; I else H print "ciao 2nome""; I
%n A#esto caso2 abbiamo #n'istr#zione da eseg#ire A#ando 2nome vale 'L#ca'P nel caso in c#i ciD non sia vero2 prevista #na seconda istr#zione se 2cognome ')erdi'P se nemmeno A#esto vero2 allora verrB eseg#ita la terza istr#zione. <a notare che2 se 2nome 'L#ca' e Xcognome ')erdi'2 viene com#nA#e eseg#ita solo la prima istr#zione2 perch dopo avere veri0icato la condizione2 t#tti gli altri casi vengono saltati.
L'istr#zione switch prevede che indichiamo2 0ra parentesi2 #n'espressione che verrB val#tata per il s#o valore FA#esta volta non si tratta necessariamente di #n valore booleanoG. <i seg#ito2 tra parentesi gra00e2 esprimeremo #na serie di espressioni da con0rontare con A#ella indicata prima: dal momento in c#i ne trova #na il c#i valore #g#ale2 PHP eseg#e il codice indicato di seg#ito2 0ino a A#ando non incontra #n'istr#zione breaC. Come possiamo vedere dall'esempio2 le espressioni da con0rontare con la prima vengono preced#te dalla parola chiave case e seg#ite dai d#e p#nti. L'istr#zione de'ault p#D essere indicata come '#ltimo caso'2 che si considera veri0icato A#ando ness#no dei casi precedenti ris#ltato vero. L'indicazione de'ault p#D anche essere assente. O molto importante comprendere la 0#nzione dell'istr#zione breaC in A#esta sit#azione: in0atti2 A#ando PHP veri0ica #no dei casi2 eseg#e non solo il codice che trova s#bito dopo2 ma anche t#tto A#ello che trova di seg#ito2 compreso A#ello relativo ai casi seg#enti. 8#esto 0ino a A#ando non trova2 app#nto2 #n'istr#zione breaC. *e non mettessimo #n'istr#zione breaC alla 0ine di #n blocco di codice relativo ad #n caso particolare2 l'esec#zione contin#erebbe eseg#endo anche il case s#ccessivo. 8#esto comportamento ci permette perD di prevedere #n #nico comportamento per piJ (6
%n A#esto caso2 abbiamo previsto #n #nico messaggio per il caso in c#i la variabile 2nome valga 'L#ca'2 '/iorgio' o '3ranco'.
$'operatore ternario
L'operatore ternario cosE chiamato perch 0ormato da tre espressioni: il valore restit#ito A#ello della seconda o della terza di A#este espressioni2 a seconda che la prima sia vera o 0alsa. %n pratica2 si p#D considerare2 in certi casi2 #na maniera molto sintetica di e00ett#are #na i'. FXaltezza TY &4'G N 'alto' : 'normale' P 8#esta espressione prenderB il valore 'alto' se la variabile 2alte((a maggiore o #g#ale a &4'2 e 'normale' nel caso opposto. Come vediamo2 l'espressione condizionale conten#ta 0ra parentesi e seg#ita da #n p#nto interrogativo2 mentre d#e p#nti separano la seconda espressione dalla terza. 8#esto costr#tto p#D essere #tilizzato2 ad esempio2 per valorizzare velocemente #na variabile senza ricorrere all'i': Xtipologia Y FXaltezza TY &4'G N 'alto' : 'normale'P eA#ivale a scrivere
i' 82alte((a >) 1EB9 2tipologia ) #alto# ; else 2tipologia ) #normale#;
Come potete vedere2 in termini di spazio il risparmio abbastanza signi0icativo. ;isogna perD stare attenti ad ab#sare di A#esta 0orma2 perch a volte p#D rendere piJ di00icoltosa la leggibilitB del nostro script2 anche se ris#lta di ind#bbia #tilitB nel caso in c#i si necessiti rendere piJ compatto il codice.
ogni singolo dato Fo gr#ppo di dati correlatiG2 che sarB poi ripet#to per t#tte le ricorrenze di tali dati.
Ciclo 6or
%niziamo s#bito con #n esempio Fcome al solito abbastanza banaleG: s#pponiamo di voler mostrare i m#ltipli da & a &' di #n n#mero2 ad esempio 5. La prima sol#zione A#ella di #sare il ciclo 'or:
'or 82mul ) 1; 2mul <) 1B; ,,2mul9 H 2ris ) 3 6 2mul; echo "3 6 2mul ) 2ris <br/>"; I
8#esto costr#tto2 simile a A#ello #sato in altri ling#aggi2 #tilizza la parola chiave 'or2 seg#ita2 0ra parentesi2 dalle istr#zioni per de0inire il cicloP di seg#ito2 si racchi#dono 0ra parentesi gra00e t#tte le istr#zioni che devono essere eseg#ite ripet#tamente. Le tre istr#zioni inserite 0ra le parentesi tonde e separate da p#nto e virgola vengono trattate in A#esto modo: la pri%a viene eseg#ita #na sola volta2 all'inizio del cicloP la ter&a viene eseg#ita alla 0ine di ogni iterazione del cicloP la seconda deve essere #na condizione2 e viene val#tata prima di ogni iterazione del ciclo: A#ando ris#lta 0alsa2 l'esec#zione del ciclo viene interrotta2 ed il controllo passa alle istr#zioni dopo le parentesi gra00e. 8#ando invece vera2 le istr#zioni 0ra parentesi gra00e vengono eseg#ite. -vviamente possibile che tale condizione ris#lti 0alsa 0in dal primo test: in A#esto caso2 le istr#zioni conten#te 0ra le parentesi gra00e non saranno eseg#ite nemmeno #na volta. %l 0ormato standard A#indi A#ello che abbiamo visto sopra2 che #tilizza le parentesi tonde per de0inire #n 'contatore': con la prima istr#zione lo si inizializza2 con la seconda lo si con0ronta con #n valore limite oltre il A#ale il ciclo deve terminare2 con la terza lo si incrementa dopo ogni esec#zione. Con il ciclo 'or2 cosE come con t#tti gli altri cicli2 molto importante stare attenti a non creare #na situa&ione in cui il ciclo non raggiunge %ai una ia d'uscita Fil cosiddetto 'loop'G: in A#esto caso2 in0atti2 lo script rieseg#irebbe il nostro ciclo all'in0inito. Cel nostro esempio di prima potrebbe s#ccedere2 ad esempio2 se sbagliassimo a scrivere il nome della variabile 2mul nell'istr#zione di incremento: se avessimo scritto 2mus,,2 avremmo incrementato A#esta variabile2 che non viene #tilizzata nel ciclo2 dopo ciasc#na delle s#e esec#zioniP in A#esto modo 2mul rimarrebbe sempre #g#ale ad &2 ed il nostro ciclo stamperebbe all'in0inito I5 R & Y 5I2 perch 2mul non diventerebbe mai maggiore di &'. %n molte sit#azioni classiche di programmazione2 #n errore di A#esto genere potrebbe costringerci a 0orzare la chi#s#ra del programma o addiritt#ra a spegnere la macchina: nel caso di PHP2 A#esto di solito non s#ccede2 in A#anto gli script PHP hanno #n limite di tempo per la loro esec#zione2 oltre il A#ale si arrestano. ale limite normalmente di 1' secondi2 ed com#nA#e impostabile attraverso il 0ile php.ini.
.l ciclo 7hile
)ediamo ora #n altro tipo di ciclo2 piJ semplice nella s#a costr#zione: il ciclo while. 8#esto si p#D considerare come #na specie di i' ripet#ta piJ volte: in0atti la s#a sintassi prevede che alla parola chiave while seg#a2 0ra parentesi2 la condizione da val#tare2 e 0ra parentesi gra00e2 il codice da rieseg#ire 0ino a A#ando tale condizione rimane vera. )ediamo con #n esempio come ottenere lo stesso ris#ltato dell'esempio precedente:
2mul ) 1; while 82mul <) 1B9 H 2ris ) 3 6 2mul;
(4
%l ciclo while2 rispetto al 'or2 non ci mette a disposizione le istr#zioni per inizializzare e per incrementare il contatore: A#indi dobbiamo inserire A#este istr#zioni nel 0l#sso generale del codice2 per c#i mettiamo l'inizializzazione prima del ciclo2 e l'incremento all'interno del ciclo stesso2 in 0ondo. +nche in A#esta sit#azione2 com#nA#e2 il concetto 0ondamentale che l'esec#zione del ciclo termina A#ando la condizione 0ra parentesi non piJ veri0icata: ancora #na volta2 A#indi2 possibile che il ciclo non sia eseg#ito mai2 nel caso in c#i la condizione ris#lti 0alsa 0in da s#bito.
.l ciclo do!!!'hile
.siste invece #n'altra 0orma2 simile al while2 con la A#ale possiamo assic#rarci che il codice indicato tra le parentesi gra00e venga eseg#ito almeno #na volta: si tratta del do...while
2mul ) 11; do H 2ris ) 3 6 2mul; print8"3 6 2mul ) 2ris<br>"9; 2mul,,; I while 82mul <) 1B9
Con A#esta sintassi2 il while viene spostato dopo il codice da ripetere2 ad indicare che la val#tazione della condizione viene eseg#ita solo dopo l'esec#zione del codice 0ra parentesi gra00e. Cel caso del nostro esempio2 abbiamo inizializzato la variabile Xm#l col valore &&2 per creare #na sit#azione nella A#ale2 con i cicli visti prima2 non avremmo otten#to alc#n o#tp#t2 mentre con l'#so del do...while il codice viene eseg#ito #na volta nonostante la condizione indicata 0ra parentesi sia 0alsa 0in dall'inizio. L'esempio stamperB A#indi I5 R && Y 55I.
8scire da un ciclo
+bbiamo visto che PHP termina l'esec#zione di #n ciclo A#ando la condizione a c#i sottoposto non piJ veri0icata. +bbiamo perD a disposizione altri str#menti per modi0icare il comportamento del nostro script dall'interno del ciclo: in0atti possiamo dire a PHP di non completare la presente iterazione e passare alla s#ccessiva Fcon continueG opp#re di interrompere de0initivamente l'esec#zione del ciclo Fcon breaCG. )ediamo #n esempio:
'or 82ind ) 1; 2ind < 3BB; 2ind,,9 H i' 82ind * 1BB )) B9 H breaC; Ielsei' 82ind * 23 )) B9 H continue; I echo "valore; 2ind <br/>"; I
8#esto codice imposta #n ciclo per essere eseg#ito 5'' volte2 con valori di Xind che vanno da & a 5''. %n realtB2 le istr#zioni che abbiamo posto al s#o interno 0anno sE che la stampa del valore di Xind non venga eseg#ita ogni volta che 2ind corrisponde ad #n m#ltiplo di (5 Fin0atti l'istr#zione 'contin#e' 0a sE che PHP salti la 'print' e passi direttamente all'iterazione s#ccessiva2 incrementando la variabileG2 e che il ciclo si interrompa del t#tto A#ando Xind raggi#nge il valore &''.
($
Ciclo 6oreach
.siste #n #ltimo tipo di ciclo2 ed #n ciclo particolare perch costr#ito appositamente per il trattamento degli arra, e di particolari oggetti chiamati %teratori: si tratta del 'oreach. 8#esto ci permette di costr#ire #n ciclo che viene ripet#to per ogni elemento di #na collezione passata come argomento. La sintassi la seg#ente:
'oreach 82arr as 2chiave )> 2valore9 H <codice> I
+ll'interno delle parentesi gra00e avremo a disposizione2 nelle d#e variabili che abbiamo de0inito 2chiave e 2valore2 l'indice e il conten#to dell'elemento che stiamo trattando. O da notare che2 nel caso ci interessi soltanto il valore e non la chiave Fad esempio perch le chiavi sono n#mericheG2 possiamo anche evitare di estrarre la chiave stessa:
'oreach 82arr as 2valore9 H <codice> I
Gli array
Precedentemente abbiamo accennato il tipo di dato arra, con il seg#ente esempio: Xcolori Y arra,F'bianco'2 'nero'2 'giallo'2 'verde'2 'rosso'GP 6sando A#esto tipo di de0inizione2 PHP associa a ciasc#no dei valori che abbiamo elencato #n indice n#merico2 a partire da '. 8#indi2 in A#esto caso2 'bianco' ass#merB l'indice '2 'nero' l'indice &2 e cosE via 0ino a 'rosso' che avrB indice 4. Per ri0erirsi ad #n singolo elemento dell'arra, si indica il nome dell'arra, seg#ito dall'indice conten#to 0ra parentesi A#adre: echo XcoloriZ([P HHstampa 'giallo' .siste poi #n metodo per aggi#ngere #n valore all'arra,P A#esto metodo p#D essere #sato anche2 come alternativa al precedente2 per de0inire l'arra,: XcoloriZ[ Y 'bl#'P Con A#esto codice verrB creato #n n#ovo elemento nell'arra, 2colori2 che avrB l'indice 5. 8#esta sintassi in0atti p#D essere ItradottaI come Iaggi#ngi #n elemento in 0ondo all'arra, XcoloriI. Come abbiamo detto2 A#esta sintassi valida anche per de0inire #n arra,2 in alternativa a A#ella #sata prima: in0atti2 se ipotizziamo che l'arra, 2colori non 0osse ancora de0inito2 A#esta istr#zione lo avrebbe de0inito creando l'elemento con indice '. O nat#ralmente possibile anche indicare direttamente l'indice2 anche in modo non consec#tivo:
2coloriL<M ) #arancio#; 2coloriLAM ) #viola#;
<opo A#esta istr#zione2 l'elemento con indice 12 che prima valeva 'verde'2 avrB il valore cambiato in 'arancio'. %noltre avremo #n n#ovo elemento2 con indice "2 con il valore 'viola'. O da notare che2 dopo A#este istr#zioni2 il nostro arra, ha #n Ib#coI2 perch dal codice 5 si salta direttamente al codice ": s#ccessivamente2 se #seremo di n#ovo l'istr#zione di IincrementoI con le parentesi A#adre v#ote2 il n#ovo elemento prenderB l'indice 4. %n0atti PHP2 A#ando gli proponiamo #n'istr#zione di A#el tipo2 va a cercare l'elemento con l'indice piJ alto2 e lo a#menta di & per creare A#ello n#ovo. 1'
!a l'argomento arra, non si limita a A#esto: in0atti gli indici degli elementi non sono necessariamente n#merici. Possono essere anche delle stringhe: XpersonaZ'nome'[ Y '!ario'P Con A#esta istr#zione abbiamo de0inito #n arra, di nome 2persona2 creando #n elemento la c#i chiave 'nome' ed il c#i valore '!ario'. O da ricordare che le chiavi n#meriche ed associative possono coesistere nello stesso arra,. )ediamo #n esempio banale2 ipotizzando la 0ormazione di #na sA#adra di calcio:
2'orma(ioneL1M )#!u''on#; 2'orma(ioneL2M )#Panucci#; 2'orma(ioneL<M )#>esta#; 2'orma(ioneL5M )#+annavaro#; 2'orma(ioneL3M )#+oco#; 2'orma(ioneL=M )#Gmbrosini#; 2'orma(ioneLAM )#@acchinardi#; 2'orma(ioneLEM )#Perrotta#; 2'orma(ioneL4M )#@otti#; 2'orma(ioneL1BM )#7n(aghi#; 2'orma(ioneL11M )#Uieri#; 2'orma(ioneL#ct#M ) #@rapattoni#;
%n A#esto caso abbiamo creato #n arra, con dodici elementi2 di c#i #ndici con chiavi n#meriche2 ed #no con chiave associativa. *e in seg#ito volessimo aggi#ngere #n elemento #sando le parentesi A#adre v#ote2 il n#ovo elemento prenderB l'indice &(. +vremmo pot#to creare lo stesso arra, #sando l'istr#zione di dichiarazione dell'arra,2 cosE: X0ormazione Y arra,F& YT ';#00on'2 'Pan#cci'2 'Cesta'2 'Cannavaro'2 'Coco'2 '+mbrosini'2 ' acchinardi'2 'Perrotta'2 ' otti'2 '%nzaghi'2 ')ieri'2 'ct' YT ' rapattoni'GP +nalizziamo il 0ormato di A#esta istr#zione: per prima cosa abbiamo creato il primo elemento2 assegnandogli esplicitamente la chiave &. Come possiamo vedere2 il sistema per 0are ciD di indicare la chiave2 seg#ita dal simbolo )> e dal valore dell'elemento. *e non avessimo indicato & come indice2 PHP avrebbe assegnato al primo elemento l'indice '. Per gli elementi s#ccessivi2 ci siamo limitati ad elencare i valori2 in A#anto PHP2 per ciasc#no di essi2 crea la chiave n#merica a#mentando di & la piJ alta giB esistente. 8#indi 'Pan#cci' prende l'indice (2 'Cesta' il 1 e cosE via. +rrivati all'#ltimo elemento2 siccome vogliamo assegnargli #na chiave associativa2 siamo obbligati ad indicarla esplicitamente. O da notare che A#ando abbiamo #sato le chiavi associative le abbiamo indicate ,ra apici: ciD necessario per mantenere la 'p#lizia' del codice2 in A#anto2 se non #sassimo gli apici Fcome spesso si vede 0areG2 PHP genererebbe #n errore di tipo 'notice'2 anche se lo script 0#nzionerebbe #g#almente Fdato che il valore verrebbe convertito a#tomaticamente in #na stringaG. )ediamo ora A#alche esempio di creazione e stampa dei valori di #n arra,: XpersonaZ'nome'[ Y '!ario'P HHcorretto XpersonaZcognome[ Y '?ossi'P HR0#nziona2 ma genera #n errore 'notice'RH echo XpersonaZ'cognome'[P HHstampa '?ossi': corretto echo Iciao XpersonaZnome[IP HRstampa 'ciao !ario': corretto Fniente apici 0ra virgoletteGRH echo Iciao XpersonaZ'nome'[IP HHC-C 36CK%-C+2 /.C.?+ .??-?. echo Iciao \XpersonaZ'nome'[]IP HRcorretto: per #sare gli apici 0ra virgolette dobbiamo comprendere il t#tto 0ra parentesi gra00eRH echo Iciao I . XpersonaZ'nome'[P HRcorretto: come alternativa2 #siamo il p#nto per concatenare Fv. lez.&' s#gli operatoriGRH +bbiamo cosE visto in A#ale maniera possiamo creare ed assegnare valori agli arra,2 #sando indici 1&
n#merici o associativi2 impostando esplicitamente le chiavi o lasciando che sia PHP ad occ#parsene. )ediamo ora in che modo possiamo creare str#tt#re complesse di dati2 attraverso gli arra, a piJ dimensioni. 6n arra, a piJ dimensioni #n arra, nel A#ale #no o piJ elementi sono degli arra, a loro volta. *#pponiamo di voler raccogliere in #n arra, i dati anagra0ici di piJ persone: per ogni persona registreremo nome2 cognome2 data di nascita e cittB di residenza Xpersone Y arra,F arra,F'nome' YT '!ario'2 'cognome' YT '?ossi'2 'data@nascita' YT '&$"1H'6H&5'2 'residenza' YT '?oma'G2 arra,F'nome' YT 'Paolo'2 'cognome' YT ';ianchi'2 'data@nascita' YT '&$64H'4H'5'2 'residenza' YT ' orino'G2 arra,F'nome' YT 'L#ca'2 'cognome' YT ')erdi'2 'data@nascita' YT '&$64H&&H(6'2 'residenza' YT 'Capoli'GGP print XpersoneZ'[Z'cognome'[P HH stampa '?ossi' print XpersoneZ&[Z'residenza'[P HH stampa ' orino' print XpersoneZ([Z'nome'[P HH stampa 'L#ca' Con A#esto codice abbiamo de0inito #n arra, ,or%ato a sua olta da tre array2 che sono stati elencati separati da virgole2 per c#i ciasc#no di essi ha ricev#to l'indice n#merico a partire da '. +ll'interno dei singoli arra,2 invece2 t#tte le chiavi sono state indicate come associative. <a notare che2 sebbene in A#esto caso ciasc#no dei tre arra, 'interni' abbia la stessa str#tt#ra2 in realtB possibile dare a ciasc#n arra, #na str#tt#ra a#tonoma. )ediamo #n altro esempio: Xpersone Y arra,F & YT arra,F'nome' YT '!ario ?ossi'2 'residenza' YT '?oma'2 'r#olo' YT 'impiegato'G2 ( YT arra,F'nome' YT 'Paolo ;ianchi'2 'data@nascita' YT '&$64H'4H'5'2 'residenza' YT ' orino'G2 'totale@elementi' YT (GP print XpersoneZ&[Z'residenza'[P HH stampa '?oma' print XpersoneZ'totale@elementi'[P HH stampa '(' %n A#esto caso il nostro arra, 0ormato da d#e arra,2 ai A#ali abbiamo assegnato gli indici & e (2 e da #n terzo elemento2 che non #n arra, ma #na variabile intera2 con chiave associativa 'totale@elementi'. % d#e arra, che costit#iscono i primi d#e elementi hanno #na str#tt#ra diversa: mentre il primo 0ormato dagli elementi 'nome'2 'residenza' e 'r#olo'2 il secondo 0ormato da 'nome'2 'data@nascita' e 'residenza'.
1(
*i tratta semplicemente di indicare il nome della 0#nzione2 seg#ito da parentesi tonde. 8#este parentesi devono contenere i parametri da passare alla 0#nzione2 ma vanno obbligatoriamente indicate anche se non ci sono parametri2 nel A#al caso rimangono v#ote come nell'esempio che abbiamo visto sopra. Cel caso poi in c#i la 0#nzione restit#isca #n valore2 possiamo indicare la variabile in c#i immagazzinarlo:
2valore ) nome1'un(ione89;
%n A#esto modo2 la variabile 2valore riceverB il ris#ltato della 0#nzione. Le 0#nzioni possono essere #tilizzate anche all'interno di espressioni: in tal caso il valore restit#ito verrB #tilizzato d#rante la val#tazione dell'espressione:
2prova ) 81B 6 numero1anni899 D numero1casuale89;
+bbiamo detto che le 0#nzioni possono essere incorporate nel ling#aggio opp#re de0inite dall'#tente: in A#esta lezione passeremo in rassegna alc#ne 0ra le 0#nzioni incorporate maggiormente #tilizzate in PHP2 tenendo perD presente che tali 0#nzioni sono n#merosissime2 rivolte agli scopi piJ disparati2 e che A#indi non ne avremo che #na visione molto parziale. Consiglio la cons#ltazione del man#ale online per #na trattazione piJ completa delle 0#nzionalitB e dei casi particolari. Cominciamo dalle principali 0#nzioni che operano s#lle variabili in generale: empt 8valore9 veri0ica se la variabile che le passiamo v#ota opp#re no. Per 'v#ota' si intende che la variabile p#D contenere #na stringa v#ota o #n valore n#merico pari a '2 ma p#D anche essere non de0inita o essere impostata al valore C6LL Fl'event#ale indicazione di #na variabile non de0inita2 in A#esto caso2 non genera errore noticeG. ?estit#isce #n valore booleano Fvero o 0alsoG. isset8valore9 veri0ica se la variabile de0inita. 6na variabile ris#lta non de0inita A#ando non stata inizializzata o stata impostata col valore >YVV. ?estit#isce #n valore booleano. is1null8valore9 veri0ica se la variabile eA#ivale a >YVV2 ma genera #n errore 'notice' se viene eseg#ito s# #na variabile non de0inita. ?estit#isce #n valore booleano. is1int8valore9$ is1integer8valore9$ is1long8valore9 veri0ica se la variabile di tipo intero. Le tre 0#nzioni sono eA#ivalenti. ?estit#iscono #n valore booleano. is1'loat8valore9$ is1double8valore9$ is1real8valore9 veri0ica se la variabile di tipo n#merico do#ble Fo 0loatG. Le tre 0#nzioni sono eA#ivalenti. ?estit#iscono #n valore booleano. is1string8valore9 veri0ica se la variabile #na stringa. ?estit#isce #n valore booleano. is1arra 8valore9 veri0ica se la variabile #n arra,. ?estit#isce #n valore booleano. is1numeric8valore9 veri0ica se la variabile contiene #n valore n#merico. O molto importante la distinzione 0ra A#esta 0#nzione e is1int89 o is1'loat892 perch A#este #ltime2 nel caso di #na stringa che contiene valori n#merici2 restit#iscono 0also2 mentre is1numeric89 restit#isce vero. ?estit#isce #n valore booleano. gett pe8valore9 veri0ica A#ale tipo di dato le abbiamo passato. ?estit#isce #na stringa che rappresenta il tipo di dato2 ad esempio: boolean2 integer2 double2 string2 arra . O bene perD2 in #no 11
script2 non 0are a00idamento s# A#esti valori per ded#rre il tipo di dato2 perch in versioni 0#t#re di PHP alc#ne di A#este stringhe potrebbero essere modi0icate. !eglio #sare le 0#nzioni viste prima. print1r8valore9 stampa Fdirettamente s#l browserG in0ormazioni relative al conten#to della variabile che le abbiamo passato. O #tile in 0ase di deb#g2 A#ando a seg#ito di comportamenti 'strani' del nostro script vogliamo veri0icare il conten#to di certi dati. *e il valore passato #n arra,2 la 0#nzione ne evidenzia le chiavi ed i valori relativi. ?estit#isce #n valore booleano. unset8valore9 distr#gge la variabile speci0icata. %n realtB non si tratta di #na 0#nzione2 ma di #n costr#tto del ling#aggio2 e ne abbiamo giB parlato nella lez. 4. <opo l'unset892 l'esec#zione di empt 89 o is1null89 s#lla stessa variabile restit#irB vero2 mentre isset89 restit#irB 0also. Con restit#isce valori. )ediamo ora A#alche esempio per chiarire l'#tilizzo di A#este 0#nzioni:
2b 2a 2b 2b 2b 2a 2b 2b 2b 2c ) ) ) ) ) ) ) ) ) ) empt 82a9; // 2a non : ancora de'inita$ /uindi 2b sarZ vero 3; isset82a9; // vero is1'loat82a9; // 'also; 2a : un intero is1string82a9; // 'also #3#; is1int82a9; is1string82a9; is1numeric82a9; gett pe82b9; // // // // 'also; 2a ora : una stringa vero vero; la stringa ha un contenuto numerico 2c prende il valore #boolean#
%n A#esti esempi abbiamo sempre assegnato alla variabile 2b i valori booleani restit#iti dalle 0#nzioni. Cella pratica2 piJ 0reA#ente che tali valori non siano memorizzati in variabili2 ma che vengano #sati direttamente come condizioni2 ad esempio per delle istr#zioni di tipo i'. +ncora #n paio di esempi:
i' 8empt 82a99 H print 8#2a : vuota o non de'inita"#9; I else H print 8#2a contiene un valore#9; I i' 8is1numeric82a99H print 8#2a contiene un valore numerico#9; I else H print 8#2a non contiene un numero#9; I
strlen8stringa9 veri0ica la l#nghezza della stringa2 cio il n#mero di caratteri che la compongono. ?estit#isce #n n#mero intero. trim8stringa9 elimina gli spazi all'inizio e alla 0ine della stringa. ?estit#isce la stringa modi0icata. ltrim8stringa9 elimina gli spazi all'inizio della stringa. ?estit#isce la stringa modi0icata. rtrim8stringa9 elimina gli spazi alla 0ine della stringa. ?estit#isce la stringa modi0icata. substr8stringa$ intero L$ interoM9 restit#isce #na porzione della stringa2 in base al secondo parametro Fche indica l'inizio della porzione da estrarreG2 e all'event#ale terzo parametro2 che indica A#anti caratteri devono essere estratti. *e il terzo parametro non viene indicato2 viene restit#ita t#tta la parte 0inale della stringa a partire dal carattere indicato. . caratteri anno contati a partire da &ero2 per c#i se si chiama la 0#nzione con substr8stringa$ 59 verranno restit#iti t#tti i caratteri a partire dal A#into. *i p#D anche indicare #n n#mero negativo come carattere iniziale: in A#esto caso2 il carattere iniziale della porzione di stringa restit#ita verrB contato a partire dal 0ondo. +d esempio2 con substr8stringa$ D3$ <9 si otterranno tre caratteri a partire dal A#int#ltimo Fda notare che in A#esto caso il conteggio non inizia da zero2 ma da &: cio D1 indica l'#ltimo carattere2 D2 il pen#ltimo e cosE viaG. *e in0ine si indica #n n#mero negativo come terzo parametro2 tale parametro non verrB piJ #tilizzato come n#mero di caratteri restit#iti2 ma come n#mero di caratteri non restit#iti a partire dal 0ondo. .sempio: substr8stringa$ <$ D29 restit#isce i caratteri dal A#arto al terz#ltimo. La 0#nzione restit#isce la porzione di stringa richiesta. str1replace8stringa$ stringa$ stringa9 e00ett#a #na sostit#zione della prima stringa con la seconda all'interno della terza. +d esempio: str1replace8#p#$ #t#$ #pippo#9 sostit#isce le 'p' con le 't' all'interno di 'pippo'2 e A#indi restit#isce 'titto'. ?estit#isce la terza stringa modi0icata. .siste anche la 0#nzione str1ireplace892 che eA#ivalente ma che cerca la prima stringa nella terza senza tener conto della di00erenza 0ra mai#scole e min#scole. strpos8stringa$ stringa9 cerca la posizione della seconda stringa all'interno della prima. +d esempio: strpos8#Voren(o#$ #re#9 restit#isce (2 ad indicare la terza posizione. ?estit#isce #n intero che rappresenta la posizione a partire da ' della stringa cercata. *e la seconda stringa non presente nella prima2 restit#isce il valore booleano 3+L*.. La 0#nzione stripos89 0a la stessa ricerca senza tenere conto della di00erenza 0ra mai#scole e min#scole. strstr8stringa$ stringa9 cerca la seconda stringa all'interno della prima2 e restit#isce la prima stringa a partire dal p#nto in c#i ha trovato la seconda. strstr8#Voren(o#$ #re#9 restit#isce 'renzo'. ?estit#isce #na stringa se la ricerca va a b#on 0ine2 altrimenti il valore booleano 3+L*.. La 0#nzione stristrFG 0#nziona allo stesso modo ma non tiene conto della di00erenza 0ra mai#scole e min#scole. strtolower8stringa9 converte t#tti i caratteri al0abetici nelle corrispondenti lettere min#scole. ?estit#isce la stringa modi0icata. strtoupper8stringa9 15
converte t#tti i caratteri al0abetici nelle corrispondenti lettere mai#scole. ?estit#isce la stringa modi0icata. uc'irst8stringa9 tras0orma in mai#scolo il primo carattere della stringa. ?estit#isce la stringa modi0icata. ucwords8stringa9 tras0orma in mai#scolo il primo carattere di ogni parola della stringa2 intendendo come parola #na serie di caratteri che seg#e #no spazio. ?estit#isce la stringa modi0icata. eOplode8stringa$ stringa L$ interoM9 tras0orma la seconda stringa in #n arra,2 #sando la prima per separare gli elementi. %l terzo parametro p#D servire ad indicare il n#mero massimo di elementi che l'arra, p#D contenere Fse la s#ddivisione della stringa portasse ad #n n#mero maggiore2 la parte 0inale della stringa sarB interamente conten#ta nell'#ltimo elementoG. +d esempio: eOplode8# #$ #ciao Pario#9 restit#isce #n arra, di d#e elementi in c#i il primo 'ciao' e il secondo '!ario'. ?estit#isce #n arra,. <obbiamo 0are #n'annotazione relativa a t#tte A#este 0#nzioni2 in particolare A#elle che hanno lo scopo di modi0icare #na stringa: la stringa modi0icata il ris#ltato della 0#nzione2 che dovremo assegnare ad #na variabile apposita. Le variabili originariamente passate alla 0#nzione rimangono invariate. )ediamo alc#ni esempi s#ll'#so di A#este 0#nzioni:
2a ) #7.W7 .WG K?P.>7+G#; /6 2b diventa #ieri era domenica#$ 6 ma 2a rimane #7.W7 .WG K?P.>7+G# 6/ 2b ) strtolower82a9; strlen8#abcd#9; trim8# !uongiorno a tutti #9; substr8#!uongiorno a tutti#$ 59; substr8#!uongiorno a tutti#$ 5$ =9; /uinto9 substr8#!uongiorno a tutti#$ D59; substr8#!uongiorno a tutti#$ D5$ 29; /uartultimo9 substr8#!uongiorno a tutti$ 5$ D29; ter(ultimo9 // // // // restituisce 5 restituisce #!uongiorno a tutti# #giorno a tutti# 8ini(ia dal /uinto9 #giorno#8= caratteri a partire dal
// #utti# 8ultimi /uattro9 // #ut# 82 caratteri a partire dal // #giorno a tut# 8dal /uinto al
str1replace8#!uongiorno#$ #+iao#$ #!uongiorno a tutti#9; // #+iao a tutti# str1replace8#dom#$ #O#$ #Komani : domenica#9; // #Komani : Oenica# str1ireplace8#dom#$ #O#$ #Komani : domenica#9; // #Oani : Oenica# strpos8#Komani : domenica#$ #m#9; // 2 8prima #m# trovata9 strstr8#Komani : domenica#$ #m#9; // #mani : domenica# 8a partire dalla prima #m#9 strtoupper8#!uongiorno a tutti#9; // #!Y?>N7?W>? G @Y@@7# uc'irst8#buongiorno a tutti#9; // #!uongiorno a tutti#; ucwords8#buongiorno a tutti#9; // #!uongiorno G @utti#; /6 suddivide la stringa in un arra $ separando un elemento 6 ogni volta che trova una virgola; avremo /uindi un arra 6 di tre elementi; 8#Glberto#$#Pario#$#Niovanni#9 6/
16
eOplode8#$#$#Glberto$Pario$Niovanni#9; /6 in /uesto caso l#arra puJ contenere al massimo due elementi$ 6 per cui nel primo elemento andrZ #Glberto# e nel secondo il 6 resto della stringa; #Pario$Niovanni# 6/ eOplode8#$#$#Glberto$Pario$Niovanni#$29;
all'arra, e2 contemporaneamente2 modi0ica l'arra, in inp#t togliendogli lo stesso elemento. arra 1push8arra $ valore L$valore...M9 accoda i valori indicati all'arra,. .A#ivale all'#so dell'istr#zione di accodamento Xarra,Z[YXvalore 2 con il vantaggio che ci permette di accodare piJ valori t#tti in #na volta. ?estit#isce il n#mero degli elementi dell'arra, dopo l'accodamento. arra 1shi't8arra 9 estrae #n elemento come arra 1pop892 ma in A#esto caso si tratta del primo. +nche in A#esto caso l'arra, viene 'accorciato'2 ed inoltre gli indici n#merici vengono rin#merati. ?imangono invece invariati A#elli associativi. ?estit#isce l'elemento estratto dall'arra,. arra 1unshi't8arra $ valore L$valore...M9 inserisce i valori indicati in testa all'arra,. ?estit#isce il n#mero degli elementi dell'arra, dopo l'inserimento. implode8stringa$ arra 9 la 0#nzione opposta di eOplode892 e serve a ri#nire in #n'#nica stringa i valori dell'arra,. La stringa indicata come primo parametro viene interposta 0ra t#tti gli elementi dell'arra,. ?estit#isce la stringa ris#ltato dell'aggregazione. *#o sinonimo [oin89. .cco A#alche esempio s#ll'#so di A#este 0#nzioni:
2arr ) arra 8#Vuca#$ #Niovanni#$ #Patteo#$ #Paolo#$ #Gntonio#$ #Parco#$ #Niuseppe#9; 2n ) count82arr9; 2arr1 ) arra 1reverse82arr9; a #Vuca# echo 2arrL1M$ #<br>#; echo 2arr1L1M$ #<br>#; // 2n vale A // 2arr1 avrZ gli elementi invertiti$ da #Niuseppe# // #Niovanni# // #Parco#
/6 ora 2arr sarZ; 6 #Gntonio#$ #Niovanni#$ #Niuseppe#$ #Vuca#$ #Parco#$ # Patteo#$ #Paolo# 6/ sort82arr9; 2a ) in1arra 8#Niovanni#$ 2arr9; 2a ) in1arra 8#Xrancesco#$ 2arr9; 2ultimo ) arra 1pop82arr9; 2ultimo ) arra 1pop82arr9; rimasti 3 elementi 2primo ) arra 1shi't82arr9; // // // // 2a : vero [email protected] 2a : 'also 8XGV\.9 2ultimo : #Paolo# 8li avevamo ordinati"9 ora 2ultimo : #Patteo#$ e in 2arr sono
// primo : #Gntonio#
/6 #Patteo# e #Gntonio# vengono reinseriti in testa all#arra ; 6 2a riceve il valore = 6/ 2a ) arra 1unshi't82arr$ 2ultimo$ 2primo9; 2stringa ) implode8# #$ 2arr9; // 2stringa diventa #Patteo Gntonio Niovanni Niuseppe Vuca Parco# 6/ /6 2new1arr conterrZ 1< elementi; 6 #Patteo#$ #Gntonio#$ #Niovanni#$ 6 #Niuseppe#$ #Vuca#$ #Parco# 8/uesti sono i = provenienti da 2arr9$ 6 #Niuseppe#$ #Parco#$# Gntonio#$ #Paolo#$ 6 #Patteo#$ #Niovanni#$ #Vuca# 8/uesti sono i A di 2arr19. Nli indici andranno da B a 12. 6/ 2new1arr ) arra 1merge82arr$ 2arr19;
14
// 7mpostiamo ora un arra con chiavi associative; 2'amiglia ) arra 8#padre# )> #+laudio#$ #madre# )> #Paola#$ #'iglio# )> #Parco#$ #'iglia# )> #.lisa#9; // creiamo una copia del nostro arra per poter 'are esperimenti 2'am1 ) 2'amiglia; // ora 2'am1 sarZ #Paola#$ #Parco#$ #.lisa#$ #+laudio#$ con chiavi da B a < rsort82'am19; 2'am1 ) 2'amiglia; // ripristiniamo l#arra originale
/6 di nuovo 2'am1 sarZ #Paola#$ #Parco#$ #.lisa#$ #+laudio#$ 6 ma ciascuno con la sua chiave originale 6 8#madre#$ #'iglio#$ #'iglia#$ #padre#9 6/ arsort82'am19; 2a 2a 2a 2a ) ) ) ) arra arra arra arra 1Ce 1eOists8#'iglia#$ 2'am19; 1Ce 1eOists8#(io#$ 2'am19; 1search8#+laudio#$ 2'am19; 1search8#Patteo#$ 2'am19; // // // // 2a 2a 2a 2a : : : : @WY. XGV\. #padre# XGV\.
' l 4 H G i s
giorno della settimana2 n#merico F'Ydom2 6YsabG giorno della settimana2 test#ale F'*#nda,' 9 '*at#rda,' G giorno della settimana s# 1 lettere F'*#n' 9 '*at'G ora s# d#e ci0re F''9(1G ora F'9(1G min#ti s# d#e ci0re F''95$G secondi s# d#e ci0re F''95$G
La 0#nzione date89 restit#isce la stringa 0ormattata che rappresenta la data. %0ti%e9ore5 %inuti5 secondi5 %ese5 giorno5 anno: O #na 0#nzione molto #tile ma che va maneggiata con molta c#ra2 perch i parametri che richiede in inp#t Ft#tti n#meri interiG hanno #n ordine abbastanza particolare2 che p#D portare 0acilmente ad errori. *#lla base di A#esti parametri2 mCtime89 calcola il timestamp2 ma l'aspetto piJ interessante che possiamo #tilizzarla per 0are calcoli s#lle date. %n0atti2 se ad esempio nel parametro mese passiamo 152 PHP lo interpreterB come 12,22 cio I0ebbraio dell'anno s#ccessivoI2 e A#indi considererB il mese come 0ebbraio ed a#menterB l'anno di &. -vviamente lo stesso tipo di calcoli si p#D 0are s# t#tti gli altri parametri. ?estit#isce #n intero FtimestampG. chec0date9%ese5 giorno5 anno: )eri0ica se i valori passati costit#iscono #na data valida. ?estit#isce #n valore booleano. )ediamo A#indi A#alche esempio anche per A#este 0#nzioni:
// 2a // 2b // 2a 2a riceve il timestamp del 25/5/2BB< alle 13.3=.2B ) mCtime813$3=$2B$5$25$2BB<9; 2b sarZ "25 Gpr B< D 13;3=" ) date8#d P D H;i#$ 2a9; timestamp delle ore 15 di =B giorni dopo il 25/5/2BB< ) mCtime815$B$B$5$25,=B$2BB<9;
2c ) checCdate83$1$2BB<9; // vero 2c ) checCdate814$A$2BB<9; // 'also 814 non : un mese9 2c ) checCdate85$<1$2BB<9; // 'also 8<1 aprile non esiste9
4'
i' 8" is1numeric82num299 H return 'alse; I i' 8" is1numeric82num<99 H return 'alse; I i' 82num1 > 2num29 H i' 82num1 > 2num<9 H return 2num1; I else H return 2num<; I I else H i' 82num2 > 2num<9 H return 2num2; I else H return 2num<; I I
Come vediamo2 la de0inizione della 0#nzione avviene attraverso la parola chia e 'unction2 seg#ita dal nome che abbiamo individ#ato per la 0#nzione2 e dalle parentesi che contengono i parametri Fo argomentiG che devono essere passati alla 0#nzione. <i seg#ito2 conten#to 0ra parentesi gra00e2 ci sarB il codice che viene eseg#ito ogni volta che la 0#nzione viene richiamata. %l nome della 0#nzione deve essere necessariamente #nivoco2 A#esto signi0ica che non possibile de0inire d#e 0#nzioni aventi lo stesso nome. +ll'interno della 0#nzione vediamo l'istr#zione returnP A#esta istr#zione molto importante2 perch ter%ina la ,un&ione Fcio restit#isce il controllo allo script nel p#nto in c#i la 0#nzione stata chiamataG e contemporaneamente determina anche il valore restit#ito dalla 0#nzione. Cel nostro esempio2 i tre dati ricev#ti in inp#t vengono controllati2 #no dopo l'altro2 per veri0icare che siano n#merici: in caso negativo Fil test in0atti viene 0atto 0acendo precedere la 0#nzione is1numeric89 dal simbolo I"I di negazioneG2 la 0#nzione termina immediatamente2 restit#endo il valore booleano 'alse. 6na volta veri0icato che i tre valori sono n#merici2 vengono posti a con0ronto i primi d#e2 e poi A#ello dei d#e che ris#lta maggiore viene posto a con0ronto col terzo2 per ottenere cosE il maggiore dei tre2 che viene in0ine restit#ito come ris#ltato della 0#nzione. 8#ando sarB il momento di eseg#ire A#esta 0#nzione potremo A#indi #sare A#esto codice:
2a 2b 2c 2m ) ) ) ) 4; E; 13; il1maggiore82a$ 2b$ 2c9; // 2m diventa 13
+vete visto che abbiamo chiamato la 0#nzione usando dei no%i di ariabile di ersi da A#elli #sati nella 0#nzione stessa: la 0#nzione in0atti #sa 2num12 2num22 2num<2 mentre lo script che la richiama #tilizza 2a2 2b2 2c. O molto importante ricordare che non c' ness#na relazione de0inita tra i nomi degli argomenti che la 0#nzione #tilizza e A#elli che vengono indicati nella chiamata. CiD che determina la corrispondenza 0ra gli argomenti 2 in0atti2 semplicemente la posizione in c#i vengono indicati: nel nostro caso2 A#indi2 2a diventerB 2num1 all'interno della 0#nzione2 2b diventerB 2num2 e 2c diventerB 2num<. +vremmo pot#to richiamare la nostra 0#nzione anche passando direttamente i valori interessati2 4&
8#esto codice2 dopo avere de0inito la 0#nzione stampa892 assegna #n valore a tre variabili globali: 2a2 2b e 2c. )iene poi chiamata la 0#nzione stampa892 passandole i valori di 2b e 2c2 che nella 0#nzione si chiamano 2var1 e 2var2 ma che al s#o interno non vengono #tilizzati. )iene invece dichiarata la variabile globale Xa2 che valorizzata con la stringa 'ciao a t#tti'2 e A#indi A#esto ciD che viene stampato a video dall'istr#zione print. *e non ci 0osse l'istr#zione Iglobal XaI2 la variabile 2a ris#lterebbe non de0inita all'interno della 0#nzione2 e A#indi la print genererebbe #n errore. Coi com#nA#e sconsiglia%o di #tilizzare le variabili globali in A#esto modo2 perch 0anno perdere chiarezza allo script e alla 0#nzione stessa. ermine della 0#nzione e valore restit#ito. +bbiamo visto in precedenza che la 0#nzione termina con l'istr#zione ret#rn2 la A#ale p#D anche essere #tilizzata per restit#ire #n valore. Cel caso in c#i non sia scopo della 0#nzione A#ello di restit#ire #n valore2 #tilizzeremo semplicemente return. 4(
)iceversa2 nel caso in c#i volessimo restit#ire piJ di #n valore2 siccome la sintassi di PHP ci consente di restit#ire #na sola variabile2 potremo #tilizzare #n array. )ediamo #n esempio2 immaginando #na 0#nzione il c#i scopo sia A#ello di ricevere #n n#mero e di restit#ire il s#o doppio2 il s#o triplo e il s#o A#int#plo:
'unction multipli82num9 H 2doppio ) 2num 6 2; 2triplo ) 2num 6 <; 2/uintuplo ) 2num 6 3; 2ris ) arra 82doppio$ 2triplo$ 2/uintuplo9; return 2ris; I
Con A#esto sistema siamo ri#sciti a restit#ire tre valori da #na 0#nzione2 p#r rispettando la sintassi che ne prevede #no solo. -vviamente A#ando richiameremo la 0#nzione dovremo sapere che il ris#ltato riceverB #n arra,: Xa Y "P Xm#l Y m#ltipliFXaGP HH Xm#l sarB #n arra, a 1 elementi *e ci interessa2 possiamo anche #sare #n costr#tto del ling#aggio per distrib#ire immediatamente i tre valori s# tre variabili distinte: listFXdoppio2 Xtriplo2 XA#int#ploG Y m#ltipliFXaGP %l costr#tto list89 serve ad assegnare i valori di #n arra, FA#ello indicato a destra dell'#g#aleG ad #na serie di variabili che gli passiamo 0ra parentesi. -vviamente possibile #tilizzarlo non solo per IraccogliereI il ris#ltato di #na 0#nzione2 ma con A#alsiasi arra,: Xarr Y arra,F'!arco'2'Paolo'2'L#ca'GP listFXprimo2 Xsecondo2 XterzoG Y XarrP %n A#esto caso2 2primo prenderB il valore '!arco'2 2secondo il valore 'Paolo'2 Xterzo il valore 'L#ca'. 6n'#lteriore precisazione: poco 0a abbiamo detto che la 0#nzione termina con l'istr#zione return. %n realtB ciD non necessario: in0atti2 nel caso in c#i non ci siano valori da restit#ire2 possiamo anche omettere l'istr#zione return2 e l'esec#zione della 0#nzione terminerB A#ando arriverB in 0ondo al codice relativo2 restit#endo il controllo allo script principale Fo ad #n'altra 0#nzione che event#almente l'ha chiamataG.
1rgo%enti ,acoltati i
%n determinate sit#azioni possiamo prevedere delle 0#nzioni in c#i non obbligatorio che t#tti gli argomenti previsti vengano passati al momento della chiamata. +bbiamo visto2 in0atti2 nella lezione precedente2 che alc#ne 0#nzioni di PHP prevedono dei parametri 0acoltativi. La stessa cosa vale per le 0#nzioni de0inite da noi: se in0atti2 al momento in c#i de0iniamo le 0#nzioni2 prevediamo #n valore di de0a#lt per #n certo parametro2 A#el parametro diventerB 0acoltativo in 0ase di chiamata della 0#nzione2 e2 nel caso manchi2 la 0#nzione #tilizzerB il valore di de0a#lt. Come esempio consideriamo #na 0#nzione che stampa i dati anagra0ici di #na persona: 0#nction anagra0eFXnome2 Xindirizzo2 Xc0Y'non disponibile'G \ print ICome: XnomeSbr HTIP print I%ndirizzo: XindirizzoSbr HTIP print ICodice 0iscale: Xc0Sbr HTIP ] 41
8#esta 0#nzione prevede tre parametri in inp#t2 ma per il terzo previsto #n valore di de0a#lt Fla stringa 'non disponibile'G. 8#indi2 se la 0#nzione viene chiamata con soltanto d#e argomenti2 la variabile 2c' avrB proprio A#el valoreP se invece t#tti e tre gli argomenti vengono indicati2 il valore di de0a#lt viene ignorato. )ediamo d#e esempi di chiamata di A#esta 0#nzione: anagra0eF'!ario ?ossi'2 'via ?oma ('2 '?**!?+6$*&(+$44^'GP anagra0eF'Paolo )erdi'2 'via Parigi $'GP Cel primo caso otterremo A#esto o#tp#t a video: Come: !ario ?ossi %ndirizzo: via ?oma ( Codice 0iscale: ?**!?+6$*&(+$44^ Cel secondo caso: Come: Paolo )erdi %ndirizzo: via Parigi $ Codice 0iscale: non disponibile Cella seconda occasione il codice 0iscale non stato passato2 e la 0#nzione ha #tilizzato il valore di de0a#lt.
.l %etodo G3+
%l metodo /. consiste nell'accodare i dati all'indirizzo della pagina richiesta2 0acendo seg#ire il nome della pagina da #n p#nto interrogativo e dalle coppie nomeHvalore dei dati che ci interessano. Come e valore sono separati da #n segno di #g#ale. Le diverse coppie nomeHvalore sono separate dal segno '_'. 8#indi2 immaginando di avere la pagina prodotto.php che mostra le caratteristiche di #n prodotto passandole il codice e la categoria del prodotto stesso2 diciamo che2 per vis#alizzare i dati del prodotto +" della categoria (2 dovremo richiamare la pagina in A#esto modo: 44
Sa hre0YIprodotto.phpNcodYa"_catY(IT La stringa che si trova dopo il p#nto interrogativo2 contenente nomi e valori dei parametri2 viene detta A#er, string. 8#ando la pagina prodotto.php viene richiamata in A#esto modo2 essa avrB a disposizione2 al s#o interno2 le variabili 21N.@L#cod#M Fcon valore 'a"'G e 21N.@L#cat#M Fcon valore '('G. %n0atti i valori conten#ti nella A#er, string vengono memorizzati da PHP nell'arra, X@/. 2 che #n arra, s#perglobale in A#anto disponibile anche all'interno delle 0#nzioni. 8#indi2 per tornare all'esempio del catalogo2 possiamo immaginare di avere #na pagina nella A#ale mostriamo #na tabella con il nome di ogni prodotto s# #na riga2 e2 di 0ianco2 il lin7 che ci permette di vis#alizzare le caratteristiche di A#el prodotto. %n ogni riga2 A#indi2 A#esto lin7 richiamerB sempre la pagina prodotto.php2 valorizzando ogni volta i diversi valori di 'cod' e 'cat'.
.l %etodo P2S+
%l metodo P-* viene #tilizzato con i mod#li: A#ando #na pagina H !L contiene #n tag <'orm>2 #no dei s#oi attrib#ti method2 che p#D valere /. o P-* . *e il metodo /. 2 i dati vengono passati nella A#er, string2 come abbiamo visto prima. *e il metodo P-* 2 i dati vengono invece inviati in maniera da non essere direttamente visibili per l'#tente2 attraverso la richiesta H P che il browser invia al server. % dati che vengono passati attraverso il metodo P-* sono memorizzati nell'arra, X@P-* . +nche A#esto arra,2 come X@/. 2 #n arra, s#perglobale. 8#indi2 per 0are #n esempio attraverso #n piccolo mod#lo: S0orm actionYIelabora.phpI methodYIpostIT Sinp#t t,peYIteLtI nameYInomeIT Sinp#t t,peYIchec7boLI nameYIn#ovoI val#eYIsiIT Sinp#t t,peYIs#bmitI nameYIs#bmitI val#eYIinviaIT SH0ormT 8#esto mod#lo contiene semplicemente #na casella di testo che si chiama 'nome' e #na chec7boL che si chiama 'n#ovo'2 il c#i valore de0inito come 'sE'. Poi c' il tasto che invia i dati2 attraverso il metodo P-* 2 alla pagina elabora.php. 8#esta pagina si troverB a disposizione la variabile 21P?\@L#nome#M2 contenente il valore che l'#tente ha digitato nel campo di testoP inoltre2 se stata selezionata la chec7boL2 riceverB la variabile 21P?\@L#nuovo#M con valore 'si'. +ttenzione perD: se la chec7boL non viene selezionata dall'#tente2 la variabile corrispondente ris#lterB non de0inita. +bbiamo visto A#indi2 brevemente2 in che modo rec#perare i dati che gli #tenti ci possono trasmettere. C' da dire che2 modi0icando l'impostazione register1globals s# php.ini2 sarebbe possibile anche rec#perare i dati in maniera piJ semplice. %n0atti2 se register1globals attiva F'on'G2 oltre agli arra, visti sopra avremo anche delle variabili globali che contengono direttamente i valori corrispondenti. +d esempio2 nel primo esempio avremmo a disposizione la variabile 2cod e la variabile 2cat2 nel secondo avremmo la variabile 2nome e la variabile Fevent#aleG 2nuovo. 3ino a A#alche tempo 0a2 erano in molti a lavorare in A#esto modo2 perch il valore di register1globals2 di de0a#lt2 era attivo2 e A#indi b#ona parte dei programmatori PHP2 sopratt#tto agli inizi2 trovavano piJ nat#rale #tilizzare il sistema piJ immediato. 1 partire dalla ersione 4!*!" di PHP2 0ort#natamente2 il valore di de0a#lt di register@globals stato cambiato in o002 e gli svil#ppatori di PHP sconsigliano di rimetterlo ad on per gravi problemi di sic#rezza. 8#esto perch2 #tilizzando gli arra, s#perglobali 21N.@ e 21P?\@2 si rende il codice piJ chiaro e anche piJ sic#ro. *e vi dovesse capitare di #tilizzare degli script giB 0atti e doveste 45
notare dei mal0#nzionamenti2 potrebbe dipendere dal 0atto che tali script #tilizzano le variabili globali invece degli arra, s#perglobali2 ed il vostro register1globals a o00. 6n'#ltima annotazione: gli arra, 21N.@ e 21P?\@ sono stati introdotti nella versione 4.&.' di PHP. %n precedenza2 gli stessi valori venivano memorizzati negli arra, corrispondenti 2H@@P1N.@1UGW\ e 2H@@P1P?\@1UGW\2 che perD non erano s#perglobali. 8#esti arra, sono disponibili anche nelle versioni att#ali di PHP2 ma il loro #so sconsigliato2 ed pres#mibile che in 0#t#ro scompariranno. Le variabili s#perglobali de0inite a#tomaticamente da PHP non permettono solamente di accedere ai parametri passati alla pagina2 ma esistono variabili che permettono di accedere ad altri valori molto importanti. La variabile 21\.WU.W contiene in0ormazioni s#l server corrente2 rec#perate attraverso +pache o estratte dagli header della pagina valorizzati dal browser dell'#tente che sta navigando. *pesso i valori conten#ti in A#esto arra, associativo vengono #tilizzati per comprendere da dove proviene #na richiesta2 rilevare l'indirizzo %P che identi0ica il PC da c#i l'#tente acced#to alla nostra pagina opp#re conoscere il path di base dell'applicativo. Le variabili 21+??^7. e 21\.\\7?> Fche verranno analizzate s#ccessivamente in modo piJ appro0onditoG contengono rispettivamente i valori dei coo7ie e delle sessioni valide per #na determinata pagina. % valori vengono acced#ti #tilizzando come chiave il nome del coo7ieHsessione che si decide interrogare. La variabile 21X7V.\ molto importante perch contiene in0ormazioni s# t#tti i 0ile inviati alla pagina attraverso #n 0orm. L'arra, 21X7V.\ ha #na str#tt#ra che permette di rec#perare Fsempre attraverso il nome del parametro2 come per le variabili 21P?\@ e 21N.@G il nome del 0ile caricato2 le s#e dimensioni ed il nome del 0ile temporaneo salvato s# disco s#l A#ale possibile operare.
6n parametro boolean che indica se trasmettere il coo7ie solamente attraverso #na connessione sic#ra H P* % coo7ie creati sono disponibili solamente dalla pagina s#ccessiva alla loro creazione. <ato che la 0#nzione setcooCie89 genera esplicitamente #n header H P2 necessario che prima del s#o #tilizzo non sia stato stampato F#sando echo2 print o A#al#nA#e altro metodo di o#tp#tG alc#n valore2 altrimenti verrB generato #n errore. +nche #na riga v#ota all'inizio del 0ile prima del tag di apert#ra PHP porterB alla generazione di A#esto errore. +lc#ni esempio di creazione di #n coo7ie: setcoo7ieF'prova@coo7ie'2 'valore coo7ie'2 HR d#ra per #n'ora RH timeFG Q 16''GP setcoo7ieF'prova@('2 'ciao'GP HHcoo7ie che d#ra 0ino a che l'#tente non chi#de il browser Per cancellare #n coo7ie necessario #tilizzare la stessa 0#nzione speci0icando gli stessi parametri #tilizzati in 0ase di creazione ma #tilizzando #na data di scadenza precedente a A#ella att#ale. setcoo7ieF'prova@coo7ie'2 ''2 timeFG 9 16''GP 6na volta creato #n coo7ie il s#o valore sarB accessibile attraverso 21+??^7.L2nome1cooCieM nelle pagine s#ccessive a A#ella att#ale2 pres#pponendo che la data di scadenza non sia trascorsa e che siano rispettate le restrizioni di dominio e cartella. O b#ona norma non creare troppi coo7ie2 dato che i browser hanno #n limite sia relativo ad #no speci0ico dominio che ad #na speci0ica cartella. %n caso 0osse necessario mantenere molti valori2 pre0eribile salvarli s# database o 0ile e salvare nel coo7ie #na chiave che ne permetta l'accesso nella pagine s#ccessive. % coo7ie sono 0acilmente rec#perabili e leggibili2 A#indi importante non salvare mai in0ormazioni private o vitali2 salvo previa criptazione.
speci0ico per l'#tente che ha appena eseg#ito la pagina che contiene il codice. Con mi addentro nel dettaglio2 e vi lascio alla lett#ra degli articoli di H !L.it2 dedicati sia alle sessioni Fhttp:HHphp.html.itHarticoliHleggiH4"5Hsessioni9alternative9in9phpHG sia ai coo7ie Fhttp:HHphp.html.itHarticoliHleggiH45'Ht#tto9s#i9coo7ieHG2 che trattano l'argomento in modo molto appro0ondito. Le sessioni sono #n argomento a prima vista molto semplice2 ma spesso ci si trova in sit#azioni nelle A#ali necessario controllare completamente il comportamento dei processi di salvataggio2 lett#ra2 creazione e distr#zione delle sessioni. + A#esto scopo ci vengono in ai#to #na serie di con0ig#razioni del 0ile php.ini ed #na serie di 0#nzioni aggi#ntive che2 anche se non tratterD in A#esta g#ida base2 consiglio caldamente di st#diare ed analizzare.
1ccedere ai ,ile
6no degli aspetti 0ondamentali della programmazione A#ello di poter accedere a ,onti di dato esterne al 0ine di rec#perare o salvare delle in0ormazioni #tili ai 0ini della nostra applicazione. PHP2 come t#tti i ling#aggi di programmazione2 0ornisce #na ricca libreria per l'accesso ai 0ile ed alle risorse presenti s#l server. Con l'avvento di PHP 52 stato aggi#nto anche il s#pporto a particolari tipi di risorse2 chiamate stream2 in modo che sia possibile accedere a A#al#nA#e tipo di 0onte come se si stesse accedendo ad #n 0ile F#n po' come accade in Lin#L2 dove la maggior parte dei sistemi di inp#tHo#tp#t hardware possono essere letti e scritti come se 0ossero 0ileG. Le operazioni principali s#i 0ile sono essenzialmente A#elle di lettura5 scrittura e posi&iona%ento FPHP 0ornisce moltissime operazioni a#siliarie per gestire completamente i 0ile2 come operazioni per l'eliminazione e la prova d'esistenza2 che analizzeremo in modo piJ appro0ondito in seg#itoG. La maggior parte delle operazioni e00ett#ate s#i 0ile avvengono applicando delle 0#nzioni che accettano come parametro #na risorsa che rappresenta il 0ile. La risorsa Frec#perata con 0open2 come vedremo in seg#itoG #n tipo di dato speciale gestito internamente da PHP2 che serve al motore del ling#aggio di programmazione come indicativo per delle in0ormazioni a basso livello richieste per il corretto 0#nzionamento della libreria #tilizzata. )ediamo #n piccolo esempio: SNphp HHPres#ppongo che la director, corrente abbia i permessi corretti X0p Y 0openF'prova.tLt'2 'wQ'GP HH+pro il 0ile prova.tLt in lett#ra2 lo creo se non esiste 0writeFX0p2 ciao a t#tti2 come vaNGP HH*crivo #na stringa s#l 0ile 0closeFX0pGP HHChi#do il 0ile aperto precedentemente NT %l programma precedente molto semplice: crea #n 0ile prova.tOt2 vi scrive dentro Iciao a t#tti2 come vaNI e lo chi#de. L'operazione di apert#ra di #n 0ile avviene attraverso la 0#nzione 'open che accetta2 nella s#a 0orma base2 d#e parametri: il primo rappresenta il percorso FpathG del 0ile s#l A#ale vorremmo operare. %l secondo #na stringa che indica alla 0#nzione A#ali sono le operazioni che si desiderano svolgere s#l 0ile. Per #na lista dettagliata di A#este rimando alla doc#mentazione #00iciale2 ma le piJ importanti sono:
44
'r' +pre in sola lett#ra. Posiziona il p#ntatore all'inizio del 0ile. 'r?' +pre in lett#ra e scritt#ra. Posiziona il p#ntatore all'inizio del 0ile. ''' +pre il 0ile in sola scritt#ra. Posiziona il p#ntatore all'inizio del 0ile e tronca il 0ile alla l#nghezza zero. *e il 0ile non esiste2 tenta di crearlo. ''?' +pre in lett#ra e scritt#ra. Posiziona il p#ntatore all'inizio del 0ile e tronca il 0ile alla l#nghezza zero. *e il 0ile non esiste2 tenta di crearlo. 'a' +pre in sola scritt#ra. Posiziona il p#ntatore alla 0ine del 0ile. *e il 0ile non esiste2 tenta di crearlo. 'a?' +pre in lett#ra e scritt#ra. Posiziona il p#ntatore alla 0ine del 0ile. *e il 0ile non esiste2 tenta di crearlo. Come possibile notare dalla descrizione dei parametri elencati precedentemente2 si 0a ri0erimento al p#ntatore di #n 0ile. %l p#ntatore non altro che #n indicatore n#merico che speci0ica la posizione att#ale all'interno del 0ile dalla A#ale verranno eseg#ite le operazioni richieste. %l posizionamento del p#ntatore avviene tramite la 0#nzione 'seeC2 che accetta come parametri la risorsa del 0ile2 #n n#mero di b,te2 ed #na costante che indica se il n#mero di b,te assol#to F*..>@*. G2 se deve essere aggi#nto alla posizione corrente F*..>@C6?G opp#re se deve essere aggi#nto alla 0ine del 0ile F*..>@.C<G. 6n semplice esempio per chiarire: SNphp HH +pro il 0ile prova.tLt in scritt#ra e lo riempio con &' righe di testo X0p Y 0openFprova.tLt2 wQGP 0orFXi Y 'P Xi S &'P QQXiG \ 0writeFX0p2 *tringa di prova n#mero .Xi.WnGP ] 0closeFX0pGP HH -ra apro il 0ile in lett#ra2 mi m#ovo al s#o interno2 e stampo parti di conten#to X0p Y 0openFprova.tLt2 rGP 0see7FX0p2 &'2 *..>@*. GP HH!i posiziono al &'` carattere Xprova Y 0readFX0p2 ('GP HHLeggo (' caratteri partendo dalla posizione corrente echo XprovaP echo ISbr HTIP echo ILa posizione del p#ntatore all'interno del 0ile : I.0tellFX0pGP 0closeFX0pGP NT Cel codice precedente ho aperto in scritt#ra prova.tOt e l'ho riempito #n 0ile con &' righe di testo. Poi2 dopo averlo chi#so2 l'ho n#ovamente aperto in lett#ra2 ho spostato il p#ntatore di &' posizioni2 ho letto (' caratteri con la 0#nzione 0read ed ho stampato la stringa letta seg#ita dalla n#ova posizione del p#ntatore F&' Q (' Y 1'G. La 0#nzione 0tell accetta solamente la risorsa rappresentante il 0ile e restit#isce la posizione del p#ntatore al s#o interno2 mentre la 0#nzione 0read accetta come secondo parametro il n#mero di b,te da leggere. <opo la lett#ra il p#ntatore verrB spostato del n#mero di b,te speci0icato. /iocate #n po' con A#este 0#nzioni per capirne il corretto 0#nzionamento.
4$
8tili&&are S@$ite
Per molti anni PHP stato a00iancato al database MyS@$. Possiamo A#asi dire che la loro crescita stata parallela ed ha portato grossi miglioramenti nel campo delle applicazioni web openso#rce. Per molto tempo A#indi con PHP stato 0ornito nativamente il s#pporto alle librerie per l'accesso a !,*8L. P#rtroppo il cambio di licenza di A#est'#ltimo ha obbligato gli svil#ppatori a rim#overe il s#pporto nativo per !,*8L Fanche se la libreria sempre in evol#zione e distrib#itaG. +l 0ine di ai#tare com#nA#e coloro che necessitano di #n database ma hanno solamente accesso alla con0ig#razione minima di PHP2 gli svil#ppatori hanno deciso di implementare nativamente il s#pporto ad un altro siste%a di database: *8Lite. 8#esto sistema2 c#i abbiamo dedicato #n ampio appro0ondimento Fhttp:HHdatabase.html.itHarticoliHleggiH4$5HsAlite9minig#ida9all#soHG2 si di00erenzia molto da !,*8L dato che non si basa s# #n'architett#ra client server ed stato svil#ppato appositamente per permettere l'accesso molto veloce ai dati. % database creati sono conten#ti in #n #nico 0ile binario Fpossono anche essere creati database temporanei salvati in memoriaG che p#D essere acced#to tramite le 0#nzioni 0ornite dalla libreria per eseg#irvi A#er, *8L. La libreria *8Lite 0ornisce un'inter,accia sia ad oggetti sia procedurale. <ato che il compito di A#esta g#ida introd#ttiva non comprende la trattazione delle programmazione ad oggetti2 ci occ#peremo dell'inter0accia a 0#nzioni. Per chi 0osse interessato a !,*8L rimandiamo alla g#ida Per operare s# #n database necessario rec#perare #na risorsa F#n po' come abbiamo visto precedentemente per i 0ileG e lavorare s# A#esta con delle 0#nzioni apposite. La risorsa connessa ad #n database p#D essere rec#perata #tilizzando sAlite@open: XsA Y [email protected] '6662 XsAlite@errorGP %l primo parametro il nome del 0ile che conterrB i nostri dati Fse non esiste verrB creatoG2 il secondo indica i permessi da associare al database Fatt#almente il parametro viene ignorato da *8Lite anche se l'impostazione consigliata '666G mentre il terzo conterrB event#almente #na stringa con il messaggio di errore event#almente riscontrato d#rante l'apert#ra della 0onte di dati. %n caso sia andato t#tto per il verso gi#sto2 2s/ conterrB la risorsa che ci permetterB di accedere al database miodb.db2 altrimenti ass#merB #n valore n#llo. Per A#esto motivo sempre b#ona prassi controllare il valore restit#ito da s/lite1open prima di proseg#ire. Per e00ett#are #na A#er, s#l database possiamo #tilizzare la 0#nzione s/lite1/uer 2 ed analizzare il ris#ltato event#almente otten#to Fper esempio in caso di operazioni di selezioneG attraverso s/lite1'etch1arra . 6n semplice esempio: XsA Y [email protected] '6662 XsAlite@errorGP i0FMXsAG \ dieFI.rrore *Alite: I.XsAlite@errorGP ] sAlite@A#er,FXsA2 IC?.+ . +;L. prova@tbl Fcampo varcharF&'GGIGP 0orFXi Y 'P Xi S &'P QQXiG \ sAlite@A#er,FXsA2 I%C*.? %C - prova@tbl )+L6.* F'Prova I.Xi.I'GIGP ] Xres#lt Y sAlite@A#er,FXsA2 I*.L.C R 3?-! prova@tblIGP 5'
whileFXdata Y sAlite@0etch@arra,FXres#ltGG \ echo XdataZ'campo'[.ISbr HTIP ] sAlite@closeFXsAGP Cel codice precedente ci siamo connessi al database2 abbiamo controllato che non ci 0ossero errori ed abbiamo eseg#ito delle A#er, s#lla risorsa rec#perata. La prima A#er, ha creato #na tabella di nome prova1tbl con #n campo di nome IcampoIP la seconda2 eseg#ita all'interno di #n ciclo2 si occ#pata di inserire dieci valori nella tabella mentre la terza ha rec#perato t#tti A#esti valori. +ll'interno del ciclo while abbiamo rec#perato #na dopo l'altra le singole righe selezionate ed abbiamo stampato i valori del campo IcampoI. Come possiamo notare la 0#nzione sAlite@0etch@arra, restit#isce la prossima riga selezionata opp#re 3+L*. nel caso in c#i A#ella precedente 0osse l'#ltima. Come stato possibile notare da A#esta breve introd#zione2 *8Lite si comporta in modo molto simile ad #n database relazionale2 con la di00erenza che non opera in #n'architett#ra client H server e permette l'esec#zione di A#er, molto semplici e compatte. 6na 0#nzionalitB molto interessante della libreria2 che mi sento di dover trattare prima di chi#dere2 A#ella che permette di registrare delle 0#nzioni PHP da richiamare all'interno delle proprie A#er, *8L. )ediamo #n semplice esempio: 0#nction trim@#pperFXstringG \ ret#rn strto#pperFtrimFXstringGGP ] XsA Y [email protected] '6662 XsAlite@errorGP i0FMXsAG \ dieFI.rrore *Alite: I.XsAlite@errorGP ] sAlite@create@0#nctionFXsA2 Itrim#pI2 Itrim@#pperI2 &GP Xres#lt Y sAlite@A#er,FXsA2 I*.L.C trim#pFcampoG +* campo 3?-! prova@tblIGP whileFXdata Y sAlite@0etch@arra,FXres#ltGG \ echo XdataZ'campo'[.ISbr HTIP ] sAlite@closeFXsAGP %l codice accede al database che abbiamo creato precedentemente e rec#pera t#tte le righe applicando direttamente da *8L la 0#nzione trim1upper Fche elimina gli spazi all'inizio ed alla 0ine e rende la stringa mai#scolaG al campo selezionato. La 0#nzione viene registrata attraverso s/lite1create1'unction che accetta come parametri la risorsa rappresentante il database2 il nome da #tilizzare all'interno dell'*8L per richiamare la 0#nzione passata come terzo argomento ed in0ine il n#mero di parametri accettati. /razie a A#esta interessante 0#nzionalitB si p#D estendere il ling#aggio *8L #tilizzato da *8Lite con #n insieme di 0#nzioni adatte a compiere le operazioni piJ ripetitive s#i dati2 al 0ine di rendere il codice piJ ordinato e p#lito.
5&
5(
whileFXrow Y Xres#lt9T0etch@assocFGG \ print0FISh1TbsSHh1TSpTbsSHpTShr HTI2 XrowZ'title'[2 XrowZ'content'[GP ] Xres#lt9TcloseFGP HH .... NT % metodi #tilizzati nell'esempio precedente sono i seg#enti: oid autoco%%it9bool:: permette di impostare l'oggetto in modo che richiami a#tomaticamente il metodo commitFG dopo aver e00ett#ato #na A#er,. %n caso sia impostato a 0alse e si stia operando s# tabelle che s#pportano le transizioni2 necessario richiamare commit man#almente per applicare le modi0iche apportate dalle A#er,P %iAed query9string;5 int<:: eseg#e #na A#er, *8L s#l database #tilizzato. %l ris#ltato restit#ito dipende dalla tipologia di A#er, eseg#ita: nel caso la A#er, \.V.+@$ \H?_$ .SPVG7> o K.\+W7!. viene restit#ito #n oggetto Fdi c#i analizzeremo le proprietB s#ccessivamenteG altrimenti viene restit#ito tr#e in caso di A#er, eseg#ita correttamente2 0alse in caso contrario. %l secondo parametro passato al metodo p#D essere la costante P`\0V71Y\.1W.\YV@ o P`\0V71\@?W.1W.\YV@: la seconda A#ella impostata di de0a#lt e viene #tilizzata per e00ett#are il b#00ering dei dati rec#perati attraverso la A#er,P invece nel caso si #tilizzi la prima costante i dati non sono b#00erizzatiP Come accennato le chiamate al metodo A#er, possono restit#ire #n oggetto nel caso in c#i la A#er, eseg#ita preveda #n ris#ltato diverso dalle in0ormazioni s#lla s#a corretta esec#zione. 8#esto oggetto #n'istanza della classe m,sAli@res#lt2 ed espone metodi per iterare s#i ris#ltati. )ediamo i piJ interessanti: propriet- nu%Bro's: restit#isce il n#mero delle righe conten#te nel b#00er o nel ris#ltato *8LP array ,etchBassoc9:: restit#isce il s#ccessivo ris#ltato sotto 0orma di #n arra, avente come chiavi i nomi dei campi rec#perati e come valori i rispettivi valori. %n caso l'iterazione sia terminata viene restit#ito C6LLP array ,etchBro'9:: opera come 0etch@assoc ma #tilizza indici n#merici per identi0icare i ris#ltatiP array ,etchBarray9:: restit#isce #n arra, che contiene sia indici n#merici che stringhe per rec#perare i valoriP ob>ect ,etchB,ield9:: restit#isce #n oggetto che contiene le in0ormazioni s#i campi rec#perati dalla A#er,P Cel caso si #tilizzi 0etch@0ield l'oggetto restit#ito espone le seg#enti proprietB: na%e: il nome della colonnaP orgna%e: il nome originale della colonna nel caso sia stato speci0icato #n aliasP table: il nome della tabella a c#i appartiene il campo2 a meno che A#esto non sia calcolato Fcome nel caso di I*.L.C F&Q&G +* testI per esempioGP orgtable: il nome originale della tabella nel caso in c#i sia stato speci0icato #n aliasP de0: il valore di de0a#lt di A#esto campo2 rappresentato come #na stringaP %aABlength: la l#nghezza massima del campoP 51
,lags: #n intero che rappresenta i 0lag associati al campoP type: il tipo di dato #tilizzato per il campoP deci%als: il n#mero di decimali #tilizzati Fsolo nel caso di campi n#mericiGP
Prepared state%ent
<opo A#esta introd#zione2 possiamo passare ad analizzare #no degli aspetti piJ interessanti della libreria m,sAli2 i prepared state%ent. Cormalmente A#ando il database eseg#e #na A#er,2 e00ett#a prima #na compilazione di A#est'#ltima e poi eseg#e il codice compilato. 8#esta operazione viene normalmente e00ett#ata ogni volta che #na A#er, viene eseg#ita2 anche nel caso di chiamate s#ccessive a A#er, molto simili. % prepared statement permettono di precompilare #na A#er, lasciando dei campi variabili: A#ando la A#er, dovrB essere eseg#ita potranno essere assegnati solo A#esti campi e non si dovrB procedere con l'intera compilazione2 g#adagnando molto in per0ormance. )ediamo come si prepara ed #tilizza #n prepared statement: SNphp HH ... connessione Xsearch Y ''P Xstmt Y Xm,sAli9TprepareFI*.L.C id2 title 3?-! test 5H.?. title L%>. NIGP Xstmt9Tbind@paramF's'2 XsearchGP 0orFXi Y 'P Xi S 5P QQXiG \ Xsearch Y 'b'.Xi.'b'P Xstmt9TeLec#teFGP Xstmt9Tbind@res#ltFXid2 XtitleGP echo ISh1TI2Xi2ISHh1TIP whileFXstmt9T0etchFGG \ print0FISstrongTbdSHstrongTSspanTbsSHspanTSbr HTI2 Xid2 XtitleGP ] Xstmt9T0ree@res#ltFGP ] Xstmt9TcloseFG HH ... NT 6tilizzando il metodo prepare dell'oggetto m,sAli possiamo creare #n prepared statement2 rappresentato da #n'istanza della classe m,sAli@stmt. La A#er, passata come argomento p#D contenere #na serie di p#nti di domanda nei posti in c#i s#ccessivamente inseriremo i valori. % p#nti di domanda possono essere inseriti solamente nelle posizioni in c#i la A#er, *8L si aspetterebbe dei 54
valori Fcome A#elli degli 7>\.W@2 gli assegnamenti di YPKG@. o i valori delle condizioni della cla#sola _H.W.G. 6na volta preparato l'oggetto possiamo operarvi #tilizzando i s#oi metodi: oid bindBpara%9string5 !!!:: associa #na o piJ variabili ai singoli placeholder speci0icati nella A#er, precompilata. %l primo argomento #na stringa di c#i ogni singolo carattere rappresenta il tipo di dato in c#i convertire i valori conten#ti nelle variabili connesse. % caratteri #tilizzabili sono i per gli interi2 d per i do#ble2 s per le stringhe e b per i blob. % restanti parametri sono i nomi delle variabili che vogliamo connettere. bool eAecute9:: eseg#e #n prepared statement salvando gli event#ali ris#ltati rec#perati in #n b#00er interno ed estraendo i valori dei placeholder dalle variabili connesseP oid bindBresult9!!!:: associa i singoli campi rec#perati dalla A#er, a delle variabili. % valori di A#este variabili saranno aggiornati ad ogni chiamata e00ett#ata al metodo 0etchP bool ,etch9:: passa al record s#ccessivo assegnando i valori dei campi rec#perati alle variabili connesse. *e non c' alc#n record restit#isce 0alseP
$a con,igura&ione di PHP
Come molti altri str#menti di svil#ppo PHP p#D essere con0ig#rato attraverso #n 0ile di con0ig#razione che de0inisce e g#ida il comportamento delle zend engine e delle s#e estensioni. Le proprietB di con0ig#razione possono essere assegnate e modi0icate in vari modi2 che analizziamo brevementeP va anticipato che alc#ne proprietB possono essere modi0icate solamente in alc#ni contesti2 solitamente per motivi di sic#rezza. La prima sol#zione apportare man#almente le %odi,iche al ,ile php!ini presente nella director, di con0ig#razione di PHP. -gni volta che si apportano modi0iche a A#esto 0ile necessario riavviare l'interprete Fsolitamente riavviando il webserver di s#pportoG e spesso il 0ile2 per motivi di sic#rezza2 ris#lta protetto da modi0iche da parte degli #tenti che #s#0r#iscono di servizi hosting. %l 0ormato del 0ile di con0ig#razione di PHP molto semplice e seg#e gli standard #tilizzati da altri str#menti openso#rce: )engono saltate t#tte le righe v#ote o preced#te da #n p#nto e virgolaP Le proprietB sono de0inite da #na serie di caratteri senza spaziP -gni riga de0inisce #n'operazione di assegnamento F#tilizzando l'operatore #g#aleGP % valori possono essere n#meri2 costanti interne2 stringhe o altre espressioni valide interpretate dal motoreP
La seconda sol#zione possibile2 optabile solamente nel caso in c#i PHP giri come mod#lo del webserver +pache2 s,ruttare gli stru%enti di con,igura&ione del 'ebser er stesso per modi0icare il comportamento di PHP. +ttraverso la direttiva php1'lag possiamo impostare ad -n o -00 i valori di #na variabile di con0ig#razione di PHPP in caso i valori di #na variabile siano valori di00erenti dal booleano possibile #tilizzare php@val#e: php@val#e error@reporting .@+LL php@0lag register@globals -00 *e il webserver e PHP sono precon0ig#rati correttamente2 le direttive possono essere speci0icate 55
sia in un ,ile !htaccess che all'interno del 0ile http.con02 magari s0r#ttando la possibilitB di de0inire comandi in base alla director,. L'#ltima opzione possibile A#ella di modi0icare i valori direttamente all'interno del proprio codice PHP s0r#ttando la 0#nzione ini1set Fcon ini1get possiamo rec#perare i valori assegnati o speci0icati con i parametri di con0ig#razioneG: SNphp ini@setF'incl#de@path'2 ini@getF'incl#de@path'G.':..Hincl#des:'GP NT -vviamente alc#ne direttive non ha senso siano impostate all'interno del codice2 come ad esempio A#elle che operano s#i dati in ingresso. )ediamo ora alc#ni parametri di con0ig#razione che controllano il comportamento del motore di PHP: allo'BcallBti%eBpassBre,erence9boolean:: +bilita o meno la possibilitB di 0orzare gli argomenti delle 0#nzioni ad essere passati per ri0erimento. 8#esto parametro deprecato e potrebbe non essere piJ s#pportato nelle versioni 0#t#re di PHPHKend. *i incoraggia il metodo di speci0icare A#ale parametro debba essere passato per ri0erimento al momento della dichiarazione della 0#nzione. *i s#ggerisce di impostare l'opzione a o00 per essere certi che lo script 0#nzioni correttamente con A#esta impostazione2 in modo da predisporsi ad event#ali modi0iche 0#t#re del ling#aggio Fsi riceverB #n warning ogni volta che si #tilizza A#esta opzione e i valori saranno passati per valore anzich per ri0erimentoG. Passare i valori per ri0erimento al momento della chiamata della 0#nzione viene sconsigliato per motivi di chiarezza del codice. La 0#nzione p#D modi0icare il parametro in modo non previsto se non indica A#esto come passato per ri0erimento. Per evitare e00etti secondari inattesi2 meglio indicare soltanto al momento della dichiarazione della 0#nzione A#ali parametri saranno passati per ri0erimento. shortBopenBtag9boolean:: %ndica se abilitare o meno la 0orma abbreviata dei tag di apert#ra del PHP F<? ?>G. *e si desidera #tilizzare il PHP in combinazione con l'^!L2 occorre disabilitare A#esta opzione per potere abilitare la riga <?Oml ?>. %n alternativa occorre stampare il testo con il PHP2 ad esempio: SNphp echo 'SNLml versionYI&.'I'P NT. %noltre2 se disabilitato2 occorre #tilizzare la versione l#nga dei tag di apert#ra del PHP F<?php ?>G. 8#esto parametro in0l#isce anche s# <?)2 la A#ale identica a <? echo. L'#so di A#esta abbreviazione richiede l'abilitazione di short1open1tag. O ormai b#ona norma disabilitare la 0orma abbreviata ed #tilizzare A#ella estesa2 A#indi consigliabile impostare a -00 A#esto valore. C %e%oryBli%it9integer:: 8#esto parametro imposta la dimensione massima in b,te di memoria occ#pabile dallo script. 8#esto ai#ta a impedire che script scritti male #tilizzino t#tta la memoria del server. Per potere #tilizzare A#esto parametro occorre abilitarlo al momento della compilazione. Pertanto occorrerB incl#dere nella con0ig#razione la linea: 99enable9memor,9limit. *i noti che occorre impostare il parametro a 9& se non si desidera impostare limiti di memoria. postB%aABsi&e9integer:: %mposta la dimensione massima dei dati post. 8#esta impostazione in0l#enza anche gli #pload dei 0ile. Per permettere #pload di 0ile di grandi dimensioni2 il valore impostato deve essere maggiore di #pload@maL@0ilesize. +nche il limite di memoria2 memor,@limit2 se abilitato2 p#D limitare gli #pload di 0ile. %n termini generali memor,@limit dovrebbe essere maggiore di post@maL@size. %l valore assegnabile soggetto alle regole 56
sintattiche del 0ile PHP.ini2 A#indi possibile #tilizzare delle abbreviazioni per speci0icare megab,te o gigab,te di dati: ('! o &/. *e la dimensione dei dati post maggiore di post@maL@size2 le variabili s#perglobale X@P-* e X@3%L.* sono v#ote. 8#esto p#D essere rilevato in diversi modi2 ad esempio passando #na variabile X@/. allo script che processa i dati2 tipo S0orm actionYIedit.phpNprocessedY&IT2 e veri0icare se X@/. Z'processed'[ impostata. includeBpath9string:: .lenco di director, in c#i le 0#nzioni reA#ireFG2 incl#deFG e 0open@with@pathFG cercheranno i 0iles. %l 0ormato tipo la variabile d'ambiente P+ H: #na lista di director, separate da d#e p#nti in 6niL2 p#nto e virgola in 5idnows. L'#so di . nel percorso di incl#de indica2 negli incl#de relativi2 la director, corrente. eAtensionBdir9string:: <irector, in c#i il PHP cerca i mod#li caricabili dinamicamente. eAtension9string:: *peci0ica A#ale mod#lo dinamico caricare A#ando viene avviato l'interprete PHPP uploadBt%pBdir9string:: <irector, temporanea #tilizzata per il transito dei 0ile d#rante l'#pload. <eve avere i permessi di scritt#ra per gli #tenti #tilizzati dal PHP per girare. *e non indicata il PHP #tilizzerB il de0a#lt di sistema. uploadB%aAB,ilesi&e9integer:: La dimensione massima di #n 0ile inviato. %l valore assegnabile soggetto alle regole sintattiche del 0ile PHP.ini2 A#indi possibile #tilizzare delle abbreviazioni per speci0icare megab,te o gigab,te di dati: ('! o &/. +lc#ne volte potrebbe capitare di dover speci0icare opzioni relative alle singole estensioni #tilizzate all'interno dell'interprete PHP. 8#ando #na proprietB speci0ica di #n determinato contesto A#esta viene preced#ta dal nome che identi0ica A#esto contesto seg#ito da #n p#nto. )ediamo alc#ne delle direttive contest#ali #tili: outputBbu,,ering9boolean:: possibile abilitare il b#00ering a#tomatico dell'o#tp#t per t#tti i 0ile settando la direttiva ad -n. O possibile anche limitare le dimensioni del b#00er ad #na dimensione prede0inita2 impostando la proprietB ad #n interoP outputBhandler9string:: possibile inviare t#tto l'o#tp#t b#00erizzato ad #na 0#nzione che si occ#pi di e00ett#arne delle tras0ormazioni. La direttiva o#tp#t@handler permette di speci0icare il nome della 0#nzione da #tilizzare di de0a#lt prima di restit#ire l'o#tp#t. Per esempio possibile impostare il valore a ob@gzhandler per comprimere l'o#tp#t2 opp#re a mb@o#tp#t@handler per modi0icare a#tomaticamente la codi0ica dei dati in #scitaP SM+P9string:: 6sato solo sotto 5indows: Come <C* o indirizzo %P del server *! P che PHP deve #sare per spedire posta elettronica con la 0#nzione mailFGP s%tpBport9int:: 6sato solo sotto 5indows: C#mero della porta del server speci0icato da *! P al A#ale connettersi A#ando si inviano email #sando mailFGP il valore prede0inito (5. send%ailB,ro%9string:: 8#ale campo I3rom:I devono avere i messaggi inviati da PHP sotto 5indows. send%ailBpath9string:: <ove trovare il programma sendmail2 solitamente H#srHsbinHsendmail opp#re H#srHlibHsendmail. con0ig#re cerca di trovare il 0ile e lo imposta di de0a#lt2 ma se non riesce 5"
a localizzarlo2 lo si p#D impostare A#i. % sistemi che non #sano sendmail devono impostare A#esta direttiva al wrapper che i rispettivi sistemi di posta o00rono2 se esistenti. Per esempio2 gli #tenti di 8mail possono normalmente impostarla a HvarHAmailHbinHsendmail o HvarHAmailHbinHAmail9in:ect. Amail9in:ect non necessita di ness#na opzione al 0ine di processare correttamente la mail. 8#esti parametri 0#nzionano anche s# 5indows. *e si impostate smtp2 smtp@port e sendmail@0rom saranno ignorate e verrB eseg#ito il comando indicato. )i sono moltissime altre proprietB con le A#ali possibile ottenere #n ottimo controllo del comportamento del motore di PHP2 A#indi sempre b#ona norma cons#ltare la doc#mentazione #00iciale per comprendere come controllare le tecnologie che si intende #tilizzare
54
$e ariabili
Come per t#tti i ling#aggi di programmazione anche con il PHP possibile #tilizzare le variabili2 che sono rappresentate dal simbolo del dollaro FXG seg#ito dal nome della variabile. Xvariabile Y &P X)ariabile Y I8#esta #na variabileIP 8#este sono variabili2 e sono di00erenti non tanto per il valore loro assegnato A#anto per il loro nome: in0atti2 in PHP le variabili sono case9sensitive. -gni variabile in PHP p#D ass#mere #n nome che inizia con #na lettera dell'al0abeto o #n #nderscore F@G e seg#e con #na combinazione A#alsiasi di lettere2 n#meri o #nderscore. O bene ricordarsi che PHP2 d#rante il processo di inizializzazione2 crea delle variabili speciali Fchiamate ariabili superglobaliG che contengono diversi tipi di in0ormazione e che mi appresterD a trattare tra poco. 8#este variabili sono accessibili da A#al#nA#e posizione dello script ed hanno dei nomi riservati che non andrebbero sovrascritti se non in casi particolari. Le variabili in A#estione sono: DBG3+: #n arra, contenente t#tti i parametri passati alla pagina tramite metodo /. Faccodando all'6?L2 dopo #n p#nto di domanda FNG #na serie di assegnazioni di valori separate da _GP DBP2S+: #n arra, contenente t#tti i parametri passati alla pagina tramite il metodo P-* Fsolitamente attraverso #n 3orm opp#re attraverso delle chiamate create man#almenteGP DBC22E.3: #n arra, contenente t#tti i coo7ie validi nella pagina corrente con il rispettivo valoreP 5$
DBF3@83S+: #n arra, che contiene i valori delle variabili precedenti2 t#tti insieme. %n caso di omonimia delle variabili2 A#este sono soprascritte dando precedenza in base al valore della direttiva variables@order impostata nel 0ile di con0ig#razione di PHP Fsolitamente php.iniGP DG$2G1$S: #n arra, contenente t#tte le variabili che ris#ltano globali nello scope correnteP DBS3F/3F: #n arra, contenente delle variabili impostate dal 5eb *erver opp#re direttamente legate all'ambiente di esec#zione dello script corrente Fcome ad esempio il browser dell'#tente o il s#o indirizzo %PG. )i sono molte variabili associate a A#esto arra,2 pienamente descritte nella doc#mentazione #00iciale di PHP. Le piJ #tili sono: PHP@*.L3: il nome del 0ile dello script correntemente in esec#zioneP <-C6!.C @?-- : la root da c#i viene eseg#ito lo script correnteP ?.!- .@+<<?: l'indirizzo %P dell'#tente che sta eseg#endo lo script. 8#esto valore viene impostato in base ad #n header impostato dal browser2 A#indi non andrebbe #tilizzato come discriminante in sit#azioni di sic#rezza criticheP DB6.$3S: #n arra, contenente in0ormazioni s#i 0ile inviati alla pagina tramite P-* . +d ogni chiave dell'arra, corrisponde #n altro arra, contenente i dettagli s#l 0ile. 8#esti dettagli sono: name: il nome del 0ile caricatoP tmp@name: il path della cache temporanea del 0ileP size: le dimensioni in b,te del 0ileP t,pe: il mime t,pe del 0ile2 se rec#perabileP error: #n n#mero indicante lo stato dell'#pload del 0ile2 che p#D essere #tilizzato per controllare che l'#pload sia avven#to correttamenteP DB3H/: #n arra, contenente t#tte le variabili d'ambiente accessibili da PHPP DBS3SS.2H: #n arra, contenente t#tte le variabili di sessione accessibili dalla pagina correnteP + 0ronte di t#tto A#esto importante ricordarsi di non sovrascrivere A#esti valori2 dato che sono spesso 0ondamentali per la corretta esec#zione dello script.
$e costanti
Le costanti sono dei contenitori imm#tabili per dei valori semplici Fstringhe e n#meriG2 che possono essere acced#te attraverso il loro nome senza che A#esti sia preced#to dal classico simbolo del dollaro FXG. Le costanti in PHP possono essere de0inite man#almente opp#re essere impostate a#tomaticamente da PHP in base al contesto ed alle librerie caricate. Le costanti vengono impostate man#almente #sando l'istr#zione de'ine89:
de'ine8#P7G1+?\@G>@.#$ 19; de'ine8#\.+?>KG1+?\@G>@.#$ prova9;
O convenzione speci0icare dei nomi composti solamente da caratteri mai#scoli o #nderscore. Le costanti possono essere acced#te in A#esto modo:
echo P7G1+?\@G>@.; echo "<br />; echo \.+?>KG1+?\@G>@.;
6'
Per controllare che #na costante sia de0inita e00ettivamente necessario #tilizzare la 0#nzione de'ined2 che accetta come argomento la stringa che identi0ica il nome della costante da controllare. HR %l codice che seg#e avrB #n comportamento di00erente da A#ello che ci aspettiamo. C-C@<.3%C% + viene tras0ormata in #na stringa C-C@<.3%C% +2 viene restit#ito #n notice da PHP e l'espressione viene val#tata vera2 eseg#endo A#indi il codice tra gra00e che invece vorremmo saltare. RH %0FC-C@<.3%C% +G \ HH .... ] HH 8#esto corretto i0Fde0inedF'C-C@<.3%C% +'GG \ HH ... ] PHP de0inisce a#tomaticamente moltissime costanti2 molte delle A#ali speci0iche per le librerie importate. Le piJ importanti2 indipendenti dalle librerie2 e che spesso ris#ltano #tili sono le seg#enti: BB6.$3BB: il path del 0ile in c#i ci troviamo. %n caso il 0ile sia incl#so da #n altro in esec#zione @@3%L.@@ avrB com#nA#e il nome del 0ile incl#soP BBC$1SSBB: il nome della classe in c#i ci troviamo att#almenteP BB68HC+.2HBB: il nome della 0#nzione in esec#zioneP BBM3+H24BB: il nome del metodo in esec#zioneP BB$.H3BB: il n#mero di linea correnteP
. tipi di dato C .
%l PHP s#pporta diversi tipi di dati2 che non devono essere impostate dal programmatore ma sono a#tomaticamente ass#nte dal motore a meno che il programmatore stesso ne 0orzi il tipo attraverso apposite 0#nzioni A#ali sett pe Fpratica com#nA#e sconsigliata2 conviene modi0icare il valore pi#ttosto che il tipo di dato di #na variabileG. % dati possono essere: %nteger 3loat *tring +rra, -b:ect ?eso#rce
.nteger
/li %ntegers2 o interi2 possono ass#mere diversi valori n#merici esprimibili in di00erenti notazioni. Xa Y &4P c decimale Xa Y 9&4P c decimale negativo Xa Y '((P c notazione ottaleP eA#ivalente a &4 decimale Xa Y 'L&(P c notazione esadecimale2 eA#ivalente a &4 decimale Probabilmente2 almeno per iniziare2 #tilizzerete sopratt#tto i n#meri decimali2 ma sappiate che il ling#aggio accetta anche altre notazioni rispetto a A#ella decimale.
6loat
8#esto tipo di dati sono semplicemente i n#meri in virgola mobile2 ad esempio $.4"6P la sintassi per #tilizzarli anche A#i alA#anto semplice: Xa Y $.4"6P Xa Y $.4"e6P Come vedete PHP accetta anche la notazione esponenziale.
Strings
*#lle stringhe c' molto piJ da dire rispetto ai tipi di dati precedenti. La sintassi di base per le stringhe : Xstring Y I%o sono #na stringaIP *e vengono #tilizzate le virgolette FIIG2 il conten#to della stringa viene espanso Fo2 tecnicamente2 IinterpolatoIG 2 come nell'esempio s#ccessivo: Xn#m Y &'P Xstring Y I%l n#mero Xn#mIP che vis#alizzerB I%l n#mero &'I. Come in t#tti i ling#aggi2 com#nA#e2 anche con il PHP ci sono i caratteri speciali che vanno 0atti precedere da #n simbolo di escapeP ad esempio2 provate il seg#ente esempio: Xn#m Y &'P Xstring Y I%l n#mero IXn#mIIP Chi pensa che l'o#tp#t di tale codice sia '%l n#mero I&'I' si sbaglia: a parte il 0atto che2 cosE come scritto2 lo script darebbe #n errore di compilazione2 le virgolette sono caratteri speciali2 ma non per A#esto non permesso #tilizzarleP la sintassi corretta per il comando riportato sopra : Xn#m Y &'P Xstring Y I%l n#mero WIXn#mWIIP +ltri caratteri speciali sono: Wn 9T newline Wr 9T carriage ret#rn Wt 9T tab#lazione WW 9T bac7slash WX 9T simbolo del dollaro L'alternativa ai caratteri di escape2 A#ando non ci siano conten#ti da espandere2 sono gli apici F''GP ad esempio: 6(
Xstring Y 'X il simbolo del dollaro'P vis#alizzerB proprio ciD che conten#to 0ra gli apici. +ttenzione a non cadere nel piJ cons#eto degli errori: Xn#m Y &'P Xstring Y '%l n#mero Xn#m'P che non vis#alizzerB I%l n#mero &'I bensE I%l n#mero Xn#mI. 8#indi possiamo a00ermare che2 con gli apici2 il conten#to della stringa viene riportato letteralmente2 ossia com' e00ettivamente scritto al s#o interno. 6na sintassi alternativa per la de0inizione delle stringhe ormai A#asi cad#ta in dis#so la sintassi H.W.K?+: Xstring Y SSS.8#esta #na stringa m#ltilinea e 0atta #tilizzando la sintassi H.?.<-C .- P 8#esta sintassi pres#ppone l'#tilizzo di #n separatore di inizio e 0ine stringa. Preced#to da III e chi#so #tilizzando il p#nto e virgola. P#D essere #tilizzato #n separatore A#alsiasi 0ormato da caratteri2 ma convenzione #tilizzare .?@.
. tipi di dato C ..
1rray
%l PHP s#pporta sia gli arra, scalari sia gli arra, associativi. %n PHP2 #n arra, di valori p#D essere esplicitamente creato de0inendone gli elementi opp#re la s#a creazione p#D avvenire inserendo valori all'interno dell'arra,2 ad esempio: Xa Y arra, FIabcI2 Ide0I2 IghiIGP crea l'arra, de0inendo esplicitamente gli elementi dell'arra,2 al contrario dell'esempio che seg#e: XaZ'[ Y IabcIP XaZ&[ Y Ide0IP XaZ([ Y IghiIP %n A#esto caso2 l'arra, viene creato con tre elementiP ricordiamo che il primo elemento di #n arra, viene identi0icato dal n#mero I'I: se ad esempio la l#nghezza di #n arra, I5I2 esso conterrB sei elementiP l'elemento contrassegnato dall'indice I'I2 in0atti2 il primo dell'arra,. *e invece2 per aggi#ngere elementi ad #n arra, Fs#pponiamo che sia A#ello precedentemente creatoG si #tilizzano le parentesi A#adre v#ote2 i dati vengono accodati all'arra,P ad esempio: XaZ[ Y IlmnIP XaZ[ Y IopAIP %n A#esto caso2 l'arra, si all#nga di ( elementi e ris#lta: XaZ'[ Y IabcIP XaZ&[ Y Ide0IP 61
XaZ([ Y IghiIP XaZ1[ Y IlmnIP XaZ4[ Y IopAIP 8#esto esempio molto #tile A#ando si vogliano accodare degli elementi all'arra, senza ricorrere a speci0iche 0#nzioni e senza dover andare a leggere il n#mero di elementi conten#ti nell'arra,: t#tto sarB accodato a#tomaticamente e correttamente. /li arra, associativi si basano invece s# coppie Iname9val#eIP #n esempio potrebbe essere: Xa Y arra,F InomeI YT I!arioI2 IcognomeI YT I?ossiI2 IemailI YT Imariodrossi.comI2 GP O interessante la possibilitB della 0#nziona arra, di annidare le entries2 come nell'esempio che seg#e: Xa Y arra,F IprimoI YT arra,F InomeI YT I!arioI2 IcognomeI YT I?ossiI2 IemailI YT Imariodrossi.comI2 G2 IsecondoI YT arra,F InomeI YT I!arcoI2 IcognomeI YT I)erdiI2 IemailI YT Imariodverdi.comI2 G GP .seg#ire s# A#esto arra, #n comando del tipo: SN echo XaZIsecondoI[ZIemailI[P NT vis#alizzerB Imariodverdi.comI.
2b>ects
%n PHP si possono #tilizzare anche gli oggetti. <ato che PHP 5 ha ampliato enormemente il s#pporto alla programmazione ad oggetti A#esta verrB trattata s#ccessivamente in modo appro0ondito. )ediamo com#nA#e #n esempio: class vis#alizza \ p#blic 0#nction eseg#i@vis#alizza FG \ echo I)is#alizza #n messaggioIP ] ] Xob: Y new vis#alizzaFGP Xob:9Teseg#i@vis#alizzaFGP %niziamo de0inendo la classe Ivis#alizzaI2 che contiene la 0#nzione Ieseg#i@vis#alizzaI che non 0a altro che vis#alizzare #n semplice messaggio a video. Con lo statement InewI inizializziamo l'oggetto IXob:I e richiamiamo la 0#nzione vis#alizza con l'operatore 9T s# Xob:. PiJ dettagli2 come detto2 in seg#ito. 64
2peratori di base
/li operatori #tilizzabili con PHP sono simili a A#elli #tilizzati con gli altri ling#aggi di programmazioneP per comoditB2 li divideremo in di00erenti I0amiglieI: gli operatori aritmetici2 gli operatori di assegnazione a2 in generale2 t#tti gli altri operatori.
1ssegna&ione
*pesso2 p#rtroppo2 gli operatori di assegnazione vengono con0#si con l'operatore di #g#aglianzaP l'operatore IYI ha #n s#o signi0icato2 che non va con0#so con A#ello di IYYI. L'operatore di assegnazione il simbolo dell'#g#ale FYG che attrib#isce ad #na variabile #n valoreP ad esempio Xa Y (P imposta per IXaI il valore I(I. L'errore che si 0a piJ spesso scrivere A#alcosa del tipo: i0 FXaY(G \ 65
HH istr#zioniP ] che2 letto da occhi inesperti2 potrebbe sembrare #n'espressione per a00ermare che2 se Xa 6/6+L. a ( deve venire eseg#ito il codice 0ra parentesi gra00e. .bbene2 non assol#tamente cosE: se avessimo vol#to scrivere ciD che appena stato detto2 avremo dov#to #tilizzare: i0 FXa YY (G \ HH istr#zioniP ]
1ltri operatori
/li operatori che il PHP ci mette a disposizione sono molti2 e vedremo in A#esta pagina i piJ importanti che non abbiamo ancora av#to modo di esaminare2 in particolari gli operatori booleani2 A#elli matematici e A#elli di incremento9decremento. +d ogni operatore 0aremo seg#ire #na breve descrizione. Xa _ Xb operatore I+ndI FXa e XbGP Xa __ Xb come sopra2 ma con #na precedenza piJ altaP Xa e Xb operatore I-rI FXa opp#re XbGP Xa ee Xb come sopra2 ma con #na precedenza piJ altaP Xa f Xb operatore I^orI FXa opp#re Xb ma non entrambiGP MXa operatore ICotI Fvero se Xa non veraGP Xa YY Xb operatore di #g#aglianza2 vero se Xa ha lo stesso valore di XbP Xa MY Xb l'opposto di A#anto sopraP Xa S XbP Xa minore di XbP Xa SY Xb Xa minore o #g#ale a XbP Xa T Xb Xa maggiore di XbP Xa TY Xb
66
Xa maggiore o #g#ale a XbP Xa N Xb : Xc A#esto2 da #tilizzarsi piJ con le espressioni che con le variabili2 val#ta Xb se Xa vera2 e val#ta Xc se Xa 0alsaP QQXa incrementa di #no Xa e la restit#isceP XaQQ restit#isce Xa e la incrementa di #no 99Xa Xa99 come i d#e precedenti2 ma il valore decrementato.
3lse
.lse viene in IcompletamentoI di i': con i'2 in0atti2 stabiliamo che s#cceda A#alcosa all'avverarsi di #na condizioneP con else possiamo stabilire cosa accade nel caso A#esta non si 6"
avveri. 6n esempio potrebbe essere: Xa Y (P Xb Y 1P i0 FXa YY XbG \ echo IWXa #g#ale a WXb e valgono Xa.WnIP ] else \ echo IWXa diversa da WXb.WnWXa vale WIXaWI mentre WXb vale WIXbWI.WnIP ]
3lsei,
.lsei' permette di speci0icare cas#alitB non de0inite da i'P #n esempio potrebbe essere: I*e Xa #g#ale a Xb vis#alizza Xa2 se Xa diversa da Xb vis#alizza #n messaggio d'errore2 avvisa se Xa non esiste2 avvisa se Xb non esisteI. Con i soli i' ed else non si potrebbe 0are2 ma con elsei' diventa semplice: i0 FXa YY XbG \ echo IWXa #g#ale a WXb.WnIP ] elsei0 FXa MY XbG \ echo IWXa diversa da WXb.WnIP ] elsei0 FMXaG \ echo IWXa non esiste.WnIP ] elsei0 FMXbG \ echo IWXb non esiste.WnIP ] Cotate d#e cose: possono esserci2 in #n blocco2 t#tti gli elsei0 di c#i avete bisogno e2 per chi conosca il Perl2 attenzione a non scrivere elsi' al posto di elsei': il signi0icato lo stesso ma Ielsi0I non viene riconosci#to dal PHP cosE come elsei0 non viene riconosci#to dal PerlM
Xa Y &P while FXa SY 5G print XaQQP endwhileP radotte2 A#este espressioni 0anno in modo che2 0inch FwhileG Xa minore o #g#ale a I5I2 Xa viene incrementato di #n'#nitB e vis#alizzato.
6or
+nche 'or si comporta esattamente come avviene in C o in PerlP dopo il 'or2 devono essere inserite tre espressioni che2 0inch restit#iscono I ?6.I permettono l'esec#zione dello statement che seg#e: considerate A#esto esempio: 0or FXa Y ' P Xa SY&' P XaQQG \ print XaP ] che vis#alizzerB i n#meri da I'I a I&'I. Celle tre espressioni 0ra parentesi abbiamo de0inito che: Xa ha valore 'P Xa minore o #g#ale a &'P Xa incrementata di #na #nitBP 8#indi2 per ogni valore di Xa a partire da I'I 0ino a I&'I Xa viene vis#alizzato. O possibile omettere alc#ne operazioni Fricordandosi com#nA#e di speci0icare sempre il p#nto e virgola come separatoreG nel caso in c#i l'inizializzazione2 il controllo o la post esec#zione siano e00ett#ate in altri l#oghi opp#re non debbano essere e00ett#ate.
S'itch
\witch permette di sostit#ire #na serie di i' s#lla stessa espressione e2 ovviamente2 di agire dipendentemente dal valore di A#esta: switch FXiG \ case ': echo IWXi vale 'IP brea7P case &: echo IWXi vale &IP brea7P ] +bbiamo A#i introdotto l'istr#zione breaC che permette di #scire da #n blocco nel caso si avveri #na determinata condizione. %l costr#tto switch spiegato ampiamente nella g#ida base2 A#indi rimando al paragra0o relativo per #lteriori spiegazioni.
modo s#per0iciale. Per A#esto motivo ho deciso di dare #na rapida occhiata ad alc#ne di A#este2 lasciandovi il compito di seg#ire la g#ida #00iciale per i dettagli o per lo st#dio delle altre 0#nzioni. Celle altre g#ide2 A#ella base e A#ella pratica2 sono trattate le 0#nzioni per l'inter0acciamento ai database *8Lite Fhttp:HHdatabase.html.itHarticoliHleggiH4$5HsAlite9minig#ida9all#soHG e !,*8L Fhttp:HHdatabase.html.itHg#ideHleggiH4"Hg#ida9m,sAlHG. Consiglio caldamente di leggerle per avere #na panoramica piJ completa. Le 0#nzioni sono #na delle parti piJ importanti di #n ling#aggio di programmazione2 perch permettono di eseg#ire determinate operazioni all'interno di #no script. Le 0#nzioni messe a disposizione dal PHP sono moltissime2 e vederle t#tte sarebbe in#tileP ci so00ermeremo invece s# A#elle piJ importanti ordinate al0abeticamente. abs: restit#isce il valore assol#to di #n n#mero:
2a) D<.5; 2aa ) abs82a9; echo 2aa$ "n";
restit#irB '. array: si veda la precedente spiegazione rig#ardo i tipi di datiP asin: restit#isce l'arcoseno dell'argomentoP atan: restit#isce l'arcotangente dell'argomentoP
Xbase Y basenameFXpathGP echo IXbaseWnIP restit#irB IindeL.phpIP bcadd: somma d#e n#meriP Xn#m Y bcaddF&.1142 4.445542 (GP echo IXn#mWnIP restit#irB 5.""P la 0#nzione IbcaddI prende come primi d#e argomenti d#e n#meri e2 come terzi argomento opzionale2 il n#mero di ci0re da vis#alizzare dopo la virgolaP bcco%p: compara d#e n#meri: la 0#nzione prende come argomento d#e n#meri e2 opzionalmente2 #n #lteriore n#mero che determina il n#mero di decimali da considerare dopo la virgola per considerare i d#e n#meri #g#aliP restit#isce I'I nel caso i d#e n#meri siano #g#ali2 IQ&I se il n#mero di sinistra maggiore di A#ello di destra e I9&I nel caso opposto. Considerate il seg#ente esempio: Xcomp Y bccompF'.1142 '.1'&2 (GP echo XcompP che restit#irB I&IP ma se2 al posto del I(I avessimo inserito #no opp#re non avessimo inserito niente2 il ris#ltato sarebbe stato I'I. bcdi : divide d#e n#meri2 con le stesse modalitB descritte per IbcaddI e IbccompIP bc%ult: moltiplica d#e n#meri2 ed possibile aggi#ngere #n #lteriore parametro per limitare il n#mero di ci0re dopo la virgola: Xmolt Y bcm#lF(.1&2 1.(&2 (GP echo IXmoltWnIP restit#irB ".4&P bcpo': eleva a potenza d#e n#meri2 con la possibilitB di speci0icare il n#mero di ci0re dopo la virgola: Xpot Y bcpowF(.12 12 (GP echo IXpotWnIP eleverB (.1 alla terza potenza2 approssimando il ris#ltato alla seconda ci0ra decimaleP bcsqrt: calcola la radice A#adrata di #n n#mero2 con la possibilitB di approssimare il n#mero di ci0re dopo la virgola aggi#ngendo #n secondo elemento alla 0#nzione Fcome avveniva per altre 0#nzioni matematiche viste sopraP bcsub: sottrae #n n#mero da #n altro2 anche A#i con la possibilitB di approssimare le ci0re dopo la virgola: Xn#m Y bcs#bF(2 5GP echo IXn#mWnIP restit#irB I91IP bin*heA: converte #na stringa di dati dal 0ormato binario a 0ormato esadecimaleP
"&
restit#isce ?6. se l'operazione ha s#ccesso2 3+L*- in caso contrario2 ad esempio nel caso la director, non sia leggibileP chec0date: controlla che #na data sia validaP per considerarsi valida2 #na data deve avere: l'anno compreso 0ra I'I e I1("6"IP il mese compreso 0ra I&I e I&(IP il giorno compreso 0ra I'I ed il n#mero relativo al n#mero di giorni del mese a c#i si 0a ri0erimentoP chgrp: tenta di cambiare il gr#ppo di #n 0ile a Igr#ppoIP la 0#nzione accetta come argomenti il nome del 0ile a c#i si vogliono cambiare i permessi ed il n#ovo gr#ppo di appartenenza:
chgrp8'ilename$ gruppo9;
Cei sistemi 5indows non 0#nziona ma restit#isce sempre vero. ch%od: eA#ivalente al comando di sistema 6niL IchmodI ed ha la stessa sintassi di chgrpP chop: #n alias per rtrim e cancella #no spazio v#oto o altri caratteri speciali dalla 0ine della stringa Fla parte piJ a destraGP spesso #tilizzato per eliminare i caratteri IWnI A#ando si riceve #n argomento dallo standard inp#tP il carattere eliminato p#D essere letto con:
2carattere ) chop82string9; echo "2carattere%n";
cho'n: cambia il proprietario di #n 0ile2 come l'analogo comando di sistema 6niL. +ccetta come argomento il nome del 0ile ed il nome del n#ovo proprietario:
2'ile ) "prova.tOt"; chown82'ile$ 2user9;
Cei sistemi 5indows2 non 0a niente e restit#isce sempre vero Fed peraltro in#tile inserire A#esta 0#nzione all'interno di #no script che non s#pporta il comando IchownIGP chr: restit#isce il carattere +*C%% speci0icato dal rispettivo n#meroP immagino sappiate2 ad esempio2 che la combinazione I+lt Q '&(6I restit#isce la tilde FgGP lo si p#D vedere con il seg#ente codice:
2ascii) "B12="; 2char ) chr82ascii9;
"(
echo "2char%n";
chun0Bsplit: divide #na stringa in parti di InI caratteriP il n#mero passabile alla 0#nzione dopo la stringa da dividere. *e non impostato2 di de0a#lt ass#nto come "6P l'esempio
2string ) "0uesto : un corso per imparare il linguaggio php"; 2split ) chunC1split82string$ 39;
restit#irB:
0uest o : u n cor so pe r imp arare il l ingua ggio php
La 0#nzione #tile per l'encoding !%!. base64 visto precedentemente con la 0#nzione base=51encodeP closedir: chi#de #na director, precedentemente aperta con la 0#nzione opendir89 9 vediP copy: crea la copia di #n 0ile:
2'ile ) "prova.tOt"; cop 82'ile$ "2'ile.baC"9;
cos: restit#isce il valore del coseno dell'argomentoP count: conta gli elementi in #na variabileP ad esempio:
2arrLBM ) "abc"; 2arrL1M ) "de'"; 2arrL2M ) "ghi"; 2count ) count82arr9; echo 2count;
restit#irB I1I2 visto che all'interno dell'arra, IXarrI sono presenti 1 elementi FXarrZ'[2 XarrZ&[2 XarrZ([GP crypt: critta #na stringaP la sintassi della 0#nzione cr pt89 :
cr pt8string$ salt9;
%n pratica2 dovremo passare alla 0#nzione la stringa che dovrB essere crittata e2 opzionalmente2 il seme con s#i crittarlaP se A#esto non passato alla 0#nzione2 sarB generato in maniera random dal PHP stesso. 6n esempio di crittazione di #na stringa potrebbe essere il seg#ente:
2var ) "0uesta : una variabile"; 2cr pt ) cr pt82var$ "aa"9; echo 2cr pt;
"1
vis#alizzerB IabcIP
decibin: converte #n n#mero da decimale a binarioP ad esempio2 il n#mero I&'I decimale I&'&'I in 0ormato binario2 e con del semplice codice PHP potremo scrivere: Xbin Y decbinF&'GP echo Xbin2 IWnIP che restit#irB app#nto I&'&'IP decheA: converte #n n#mero da decimale a esadecimaleP la sintassi identica a A#ella #tilizzata per decbin89P decoct: converte #n n#mero da 0ormato decimale a 0ormato ottaleP la sintassi la stessa #tilizzata per decbin89P de,ine: de0inisce #na costanteP come abbiamo visto nel capitolo s#lle costanti2 A#este sono simili alle variabili solamente che non hanno il simbolo del dollaro davantiP per de0inire #na costante si #tilizza la seg#ente sintassi: de0ineFIC-* +C .I2 I8#esta #na costanteIGP echo C-* +C .P L'esempio riportato sopra vis#alizzerB I8#esta #na costanteIP de,ined: controlla che #na certa costante esista: #n esempio potrebbe essere: de0ineFIC-* +C .I2 I8#esta #na costanteIGP i0 Fde0inedFIC-* +C .IGG \ echo ILa costante de0initaWnIP ] else \ echo ILa costante non de0initaWnIP ] che vis#alizza #n messaggio a seconda che la costante sia o meno de0initaP die: vis#alizza #n messaggio ed esce dal programma: i0 Fde0inedFXn#mGG \ echo IWXn#m de0initoWnIP ] else \ die FIWXn#m non de0initoP impossibile proseg#ireWnIGP ] dirna%e: A#ando si speci0ica #n path2 riporta il path senza il nome del 0ile 0inale: se ad esempio il path IHhomeH,o#rnameHp#[email protected] la 0#nzione restit#irB solamente IHhomeH,o#rnameHp#blic@htmlI: Xpath Y IHhomeH,o#rnameHp#blic@htmlIP echoFdirnameFXpathGGP +vrete notato che A#esta 0#nzione 0a l'esatto contrario della 0#nzione basename89P combinando le d#e 0#nzioni2 si p#D avere il path completo di #n 0ile2 compreso il s#o nomeP dis0,reespace: restit#isce lo spazio di disco liberoP se volessimo ad esempio vedere A#anto spazio rimane nella director, root della macchina2 potremo scrivere: echoFdis70reespaceFIHIGGP "5
echo I%nvalid date 0ormat: XdateIP ] #tto A#esto ciclo 0atto per controllare che #na data sia in 0ormato corretto. )ediamo il signi0icato di IZ'9$[\4]G9FZ'9$[\&2(]G9FZ'9$[\&2(]I. Per chi conosca le espressioni regolari2 non sarB di00icile trad#rre A#anto sopra con I#n n#mero da ' a $ ripet#to A#attro volte seg#ito da #n '9'2 da #n n#mero da ' a $ ripet#to #na o d#e volte2 da #n '9' e da #n n#mero da ' a $ ripet#to #na o d#e volteI. Come spesso accade2 leggere #n'espressione regolare molto piJ semplice che trad#rla nel ling#aggio parlato. eregiBreplace: 0#nziona esattamente come ereg1replace892 solamente che in A#esto caso l'espressione regolare sostit#ita in maniera Icase insensitiveI2 ossia ignorando i caratteri mai#scoli e min#scoliP eregi: 0#nziona esattamente come ereg892 solamente che in A#esto caso l'espressione regolare sostit#ita in maniera Icase insensitiveIP errorBlog: invia #n messaggio di errore al 0ile di log del 5eb *erver2 direttamente alla porta CP dalla A#ale arrivata la richiesta o in #n 0ile. La sintassi : error@logFmessage2 mesage@t,pe2 destinationGP !essage@t,pe #n n#mero che speci0ica dove deve arrivare il messaggio. P#D essere:
': il messaggio inviato al logger del PHP o nel 0ile speci0icato da Ierror@logIP &: il messaggio inviato per email al parametro Fprobabilmente #n valido indirizzo emailG speci0icato in IdestinationIP (: il messaggio inviato al deb#ggerP 1: il messaggio inserito in append al parametro speci0icato in destinationIP escapeshellc%d: se si richiama #n comando esterno da #na shell2 con A#esto comando si 0a in modo che i metacaratteri della shell vengano 0atti precedere da #n carattere di escape per evitare che il comando prod#ca degli erroriP eAec: eseg#e #n programma esternoP eAit: esce da #no scriptP il comando eOit89 #tile nei casi si voglia 0ermare #no script in caso A#alcosa non soddis0i determinate condizioni2 ad esempio: i0 FcondizioneG \ eseg#i il bloccoP ] else \ eLitP ] ?icordate che eOit89 non riporta #n messaggio di errore come 0a die89: se vi interessa dare IspiegazioniI s#l perch lo script termina2 #tilizzate die892 ma ricordate che non possibile scrivere: eLit I.sco dal programmaWnIP o meglio2 possibile ma non ha alc#n e00etto se non A#ello di #scireP eAp: eleva IeI F(."&4(4.....G alla potenza riportata come argomento della 0#nzione:
""
echo eLpF1GP restit#irB: ('.'45516$... eAplode: divide #na stringa secondo #n determinato pattern. +d esempio2 volendo dividere #na stringa contenente tre nomi separati da virgole possiamo scrivere: Xnomi Y I izio2Caio2*empronioIP list FXnome&2 Xnome(2 Xnome1G Y eLplode FI2I2 XnomiGP echo IXnome&WnXnome(WnXnome1WnIP che restit#irB: izio Caio *empronio .Oplode89 #na versione sempli0icata di split892 che vedremo in seg#ito. .ntrambe le 0#nzioni2 inoltre2 sono molto #tili nel caso ci sia la necessitB di leggere determinati 0ile contenenti delle listeP
,ilesi&e: restit#isce la grandezza di #n 0ile: X0ilename Y IHtmpHptova.tLtIP Xsize Y 0ilesizeFX0ilenameGP echo IX0ilename 9T XsizeWnIP ,iletype: determina il tipo di 0ileP i valori possibili sono: 0i0o2 char2 dir2 bloc72 lin72 0ile e #n7nownP ,loc0: applica il loc7ing ad #n 0ileP speci0icamente2 'locC89 opera s# #n p#ntatore ad #n 0ile precedentemente aperto e le operazioni possibili sono: &: per il loc7 in lett#raP (: per il loc7 in scritt#raP 1: per rim#overe il loc72 di A#alsiasi tipo siaP 4: per impedire che 'locC89 blocchi #n 0ile mentre applica il loc7P +d esempio2 per applicare 'locC89 ad #n p#ntatore IX0ileI precedenemente de0inito occorrerB scrivere: HR Per impedire che il 0ile sia lettoRH 0loc7FX0ile2 (GP HR Codice per lavorare s#l 0ile RH ..... HR Per rim#overe il 0loc7 RH 0loc7FX0ile2 1GP ,open: apre #n 0ile opp#re #n'6?L. La sintassi : 0openF0ilename2 modeGP -vviamente a I0ilenameI corrisponde il nome del 0ile o l'6?L dello stesso2 ed a ImodeI la modalitB con il A#ale A#esto deve essere aperto: si ha A#i la possibilitB di scegliere 0ra:
r: apre il 0ile in sola lett#raP rQ: apre il 0ile in lett#ra ed in scritt#raP w: apre il 0ile in sola scritt#raP wQ: apre il 0ile in lett#ra e scritt#raP a: apre il 0ile in sola scritt#ra e inserisce il p#ntatore alla 0ine del 0ile FIwI lo inserisce alla 0ineG aQ: apre il 0ile in lett#ra e scritt#ra inserendo il p#ntatore alla 0ine del 0ileP
+d esempio2 per aprire #n 0ile locale in sola lett#ra scriveremo: X0ile Y 0openFIHtmpHprova.tLtI2 IrIGP Per #n 6?L2 invece: X0ile Y 0openFIhttp:HHwww.m,host.comHindeL.htmlI2 rIGP Per t#tte le s#ccessive operazioni s#l 0ile2 poi2 dovremo agire direttamente s#l p#ntatore "$
echo issetFXaG2 IWnIP echo issetFXbG2 IWnIP che restit#irB & e 'P ricordiamo che & considerato valore di s#ccesso F ?6.G2 ' di ins#ccesso F3+L*.GP >oin: #nisce gli elementi di #n arra, con #na determinata stringaP l'#so identico a A#ello di implode89P 0ey: prende #na chiave da #n arra, associativoP #n semplice esempio potrebbe essere: Xarra, Y arra,FI&I YT I#noIGP Xchiave Y 7e,FXarra,GP echo IXchiaveWnIP che restit#irB I&I. 8#esta 0#nzione #tile per estrarre t#tte le chiavi di arra, associativi complessiP lin0: crea #n hard lin7P la sintassi : lin7Ftarget2 lin7GP Le in0ormazioni s#i lin7 Fa proposito dell'esistenza del 0ile a c#i p#nta il lin7 stessoG possono essere vis#alizzate con linCin'o89P list: assegna delle variabili come se 0ossero parti di #n arra,P riprendiamo l'esempio 0atto con each: Xarra, Y arra, FInomeI YT IvaloreI2 Inome(I YT Ivalore(IGP while FlistFX7e,2 XvalG Y each FXarra,GG \ echo IX7e, YT XvalWnIP ] %n A#esto caso2 list89 #tilizzato per IstilareI #na lista di variabili che verranno estratte dall'arra,2 senza ovviamente dare loro #n valore ma lasciando alle parti s#ccessive del codice l'assegnazione dei loro valori. O inoltre #tile notare che le variabili create da list89 non ass#mono #n solo valore2 ma per ogni chiamata ass#mono #n diverso valore2 a seconda degli elementi presenti nell'arra,.
locazione di sendmail Fo analogo programma per l'invio delle emailGP %aA: restit#isce il valore piJ alto di #na serie di variabili2 ad esempio: Xn#m Y &P Xn#m( Y (1P Xn#m1 Y '.1P XmaL Y maLFXn#m2 Xn#m(2 Xn#m1GP echo XmaL2 IWnIP restit#irB I(1I. -pposto a maO89 %in9:2 che adotta la stessa sintassi di maO89P %0dir: crea #na director,2 di c#i si deve speci0icare il percorso ed i permessi: m7dirFIHtmpHprovaI2 '"""GP creerB la director, IHtmpHprovaI con permessi impostati a '"""P opendir: apre #na director,2 della A#ale sarB possibile leggere gli elementi con readdir89 e2 s#ccessivamente2 chi#derla con closedir89P phpin,o: la 0#nzione piJ IrappresentativaI del PHP2 in A#anto vis#alizza moltissime in0ormazioni s#l PHP stesso: l'#so dovrebbe essere noto: phpin0oFGP php ersion: vis#alizza la versione di PHP che si sta #tilizzandoP popen: apre #n p#ntatore ad #n processo che deve essere chi#so con pclose89P print: vis#alizza #na stringa a video come echo89P rand: genera #n valore n#merico in maniera cas#aleP se si volesse #n valore compreso 0ra &' e ('2 si potrebbe scrivere: Xrandom Y randF&'2 ('GP range: crea #n arra, contenente #n range di valori interi speci0icatoP ad esempio2 per creare #n arra, con valori da & a &' sarB necessario scrivere: Xarra, Y rangeF&2 &'GP rena%e: rinomina #n 0ile: ad esempio2 si #sa: renameFIoldnameI2 InewnameIGP per rinominare IoldnameI come InewnameIP r%dir: come l'analogo somando #niL2 rim#ove #na director,P A#esto p#D essere 0atto solo se: la director, v#otaP i permessi s#lla director, lo consentono. round: arrotonda #n n#mero: Xn#mero Y ro#ndF(21GP HR restit#isce ( RH Xn#mero Y ro#ndF(.5GP HR restit#isce 1 RH Xn#mero Y ro#ndF(.6GP HR restit#isce 1 RH
4(
Come avrete notato2 i decimali da ' a 4 sono approssimati all'intero precedente2 da 5 a $ all'intero s#ccessivo
ordina in modo cas#ale gli elementi di #n arra,P ad esempio2 per poter vis#alizzare gli elementi di #n arra, in maniera cas#ale si potrebbe scrivere:
2num ) range8B$1B9; shu''le82num9; while 8list8$2numero9 ) each82num99 H echo "2numero "; I
sin si&eo,
restit#isce il seno dell'espressioneP calcola il n#mero di elementi presenti in #n arra,. *e ad esempio si volesse calcolare il n#mero di elementi in #n arra, ed agire di conseg#enza2 si potrebbe scrivere:
2arra ) arra 8"1"$ "2"$ "<"$ "5"$ "3"9; 2si(e ) si(eo'82arra 9; i' 82si(e <) 1B9 H echo "V#arra contiene meno di 1B elementi%n"; I else H echo "V#arra contiene pia di 1B elementi%n"; I
sleep
mette lo script in pa#sa per #n determinato n#mero di secondi2 speci0icato come argomento della 0#nzioneP ad esempio2 sleep81B9 0arB in modo che lo script venga sospeso per &' secondi2 per poi contin#are normalmenteP split divide #na stringa a seconda di #n determinato patternP ad esempio:
2linea ) "ti(ioQQcaioQQsempronio"; list 82uno$ 2due$ 2tre9 ) split8"%Q%Q"$ 2linea$ <9; print "1 )> 2uno%n2 )> 2due%n< )> 2tre%n";
<a notare il 0atto che stato necessario inserire #n carattere di escape FWG prima di ogni IeI nell'espressione da #tilizzare per dividere la rigaP sqrt ?estit#isce la radice A#adrata dell'argomento.
41
strc%p
?estit#isce IVa seconda riga : pia lunga della primaI. La 0#nzione2 in0atti2 restit#isce I'I se le stringhe sono #g#ali2 #n valore minore di zero se la seconda piJ l#nga della prima e maggiore di zero se la prima piJ l#nga della seconda. syste% tan unset usleep .seg#e #n programma di sistema2 ne restit#isce l'o#tp#t e ritorna allo script. ?estir#isce la tangente dell'argomento. .limina il valore di #na variabile. Come sleep892 ma A#esta 0#nziona blocca lo script per C microsecondi. -vviamente2 la lista delle 0#nzioni non termina A#i ma2 essendocene altrettante meno #tili almeno per chi inizia a programmare con A#esto ling#aggio2 abbiamo pre0erito 0ermarci a A#esto p#nto. +ltre speci0iche le tratteremo nelle lezioni s#ccessive.
?C6 %<.+ Per 0#nzionare con tale libreria2 il PHP deve essere stato compilato con l'opzione DDwithD mcr pt. % comandi 0ondamentali sono A#attro2 t#tti con la medesima sintassi: %cryptBc,b9:: cipher 0eedbac7P codi0ica b,te per b,teP %cryptBcbc9:: cipher bloc7 chaining: #tile per l'encoding dei 0ile con #n grande margine di sic#rezzaP %cryptBecb9:: electronic codeboo7: #tilizzata per dati random2 dove il livello di sic#rezza non altissimoP %cryptBo,b9:: o#tp#t 0eedbac7: simile a c0b2 ma data maggiore attenzione agli errori. La sintassi in generale : Xencr,pted Y mcr,pt@^^^Falgoritmo2 chiave2 inp#t2 encodeHdecodeG dove: KKK il metodo che si intende #tilizzare Fc0b2 cbc2 c0b o o0bGP algorit%o l'algoritmo che si intende #tilizzare2 con la sintassi: !C?aP @+L/-?% !+d esempio2 si potrebbe #tilizzare !C?aP @;L-53%*H opp#re !C?aP %<.+ chia e altro non che la chiave con c#i si andranno a crittare i datiP input sono i dati da crittareP encodeLdecode indica alla 0#nzione se si devono crittare o decrittare i datiP per A#esto2 si #sano rispettivamente: !C?aP @.CC?aP e !C?aP @<.C?aP )ediamo ora #n esempio: volendo crittare #na semplice stringa di testo con chiave di crittat#ra ILa mia chiaveI #tilizzando C3; con l'algoritmo %<.+2 dovremo scrivere: Xstringa Y I6na semplice stringa di testoIP Xchiave Y ILa mia chiaveIP Xencr,pted Y mcr,pt@c0bF!C?aP @%<.+2 Xchiave2 Xstringa2 !C?aP @.CC?aP GP Chi#nA#e voglia poi leggere i nostri dati crittati FXencr,ptedG dovrB ovviamente conoscere la chiave2 il metodo e l'algoritmo #tilizzatiP A#indi potrebbe scrivere A#alcosa del tipo: Xchiave Y ILa mia chiaveIP Xstringa Y mcr,pt@c0bF!C?aP @%<.+2 Xchiave2 Xencr,pted2 !C?aP @<.C?aP GP 45
,tpBconnect
8#esta la 0#nzione IprincipaleI nel senso che ci permette di stabilire #na connessione 3 P 0ra la nostra macchina ed il server 3 P remoto. La s#a sintassi : Xstream Y 0tp@connectFhost2 portGP dove host il nome del server a c#i intendiamo connetterci e port FopzionaleG la porta alternativa alla A#ale ci si v#ole connettereP se A#esta non speci0icata2 viene #tilizzata la porta di de0a#lt per il protocollo 3 P2 ossia la (&. Cella variabile Xstream2 inoltre2 viene immagazzinato app#nto lo stream di dati che il client Fin A#esto caso il PHPG riceve dal server2 ossia i messaggi di connessione accettata Fcon i vari dettagliG o di connessione ri0i#tata. +d esempio2 per connetterci alla porta di de0a#lt del server 3 P I0tp:HH0tp.host.comI #tilizzeremo: Xstream Y 0tp@connectFI0tp:HH0tp.host.comIGP
,tpBlogin
<opo la connessione2 abbiamo bisogno di identi0icarci in modo che il server ci permetta lo scambio dei dati. molti saranno abit#ati a non vedere tale 0ase visto che2 con i piJ di00#si client 3 P gra0ici essa svolta in a#tomatico #tilizzando le in0ormazioni di login F#sername e passwordG inseriti come opzioni per il collegamento2 ma sappiate che A#esta #na 0ase di vitale importanza per la connessione. La sintassi della 0#nzione : Xlogin Y 0tp@loginFstream2 #sername2 passwordGP *e ad esempio in precedenza ci eravamo collegati all'host I0tp.host.comI2 #tilizzando la variabile IXstreamI2 adesso potremo procedere al login vero e proprio con: Xlogin Y 0tp@loginFXstream2 I#tenteI2 IpasswordIGP La variabile Xlogin ci servirB per capire se il login andato o meno a b#on 0ine e conterrB il valore I&I per il s#ccesso2 I'I altrimenti. +d esempio2 per vedere se contin#are lo scambio di dati in seg#ito all'a#torizzazione potremo #tilizzare il valore assegnato a tale variabile e scrivere: i0 FXlogin YY I&IG \ ... c 3ai il resto delle operazioni ] else \ echo I+#torizzazione non ri#scitaWnIP ] 6na volta connessi2 potremo sapere s# che macchina stiamo lavorando con la 0#nzione 'tp1s st pe89 che ha sintassi: Xs,stem Y 0tp@s,st,peFXstreamGP 46
,tpBp'd
8#esta 0#nzione invoca il comando IpwdI2 ovvero IPrint wor7 director,I2 che potremo trad#rre come I)is#alizza la director, correnteI. Per vedere a che director, veniamo connessi dopo il login2 potremo scrivere: Xdirector, Y 0tp@pwdFXstreamGP dove Xstream sempre la variabile che abbiamo #tilizzato per la connessione con 'tp1connect89.
,tpB%0dir e ,tpBr%dir
8#este d#e 0#nzioni invocano il comando Im7dir IFcrea #na director,G e IrmdirI Frim#ovi #na director,G. La prima restit#isce il nome della n#ova director,2 la seconda solamente i valori tr#e o 0alse. Potremo creare #n piccolo loop e scrivere: c Posizioniamoci in IHvarHwwwdataI. Xm,dir Y 0tp@chdirFXstream2 IHvarHwwwdataHIGP c Creiamo la director, IprovaI come sottodirector, di IHvarHwwwdataI Xnewdir Y 0tp@m7dirFXstream2 IprovaIG c Cancelliamo la director, appena creataM Xdeleted@dir Y 0tp@rmdirFXstream2 XnewdirGP c Possiamo ora controllare il t#tto con: i0 FXdeleted@dir YY I&IG \ print I-perazione completata con s#ccesso.WnIP ] else \ print I8#alcosa non andato per il verso gi#sto.WnIP ] -vviamente l'esempio non ha molto senso in #na vera connessione Fperch creare #na director, e s#bito cancellarlaNG2 ma stato proposto per comprendere come #tilizzare al meglio A#este d#e 0#nzioni. 4"
,tpBnlist
8#esta 0#nzione analoga al comando IdirI2 ossia il comando #tilizzato per vedere i nomi dei 0ile presenti in #na director,. La s#a sintassi : Xlist Y 0tp@nlistFXstream2 director,GP +d esempio2 possiamo portarci nella director, IHvarHwwwdataI e leggerne i 0ile con: Xnewdir Y IHvarHwwwdataIP Xlist Y 0tp@nlistFXstream2 XnewdirGP % ris#ltati sono conten#ti in #n arra,2 A#indi #n 'echo IXlistI' non avrebbe alc#n senso.
,tpBget
3#nzione che richiama il comando /. 2 per scaricare #n 0ile dal server remoto. <obbiamo speci0icare per la 0#nzione2 oltre al solito stream2 il nome del 0ile locale2 il nome del 0ile remoto e la modalitB di tras0erimento F3 P@+*C%% o 3 P@;%C+?aGP la sintassi completa : X0ile Y 0tp@getFXstream2 local@0ilename2 remote@0ilename2 modeGP +d esempio2 volendo scaricare dal server il 0ile Idata.tLtI Fs#pponiamo di essere giB all'interno della director, che lo contieneG inserendolo nella director, IHtmpI con nome I0ile.tLtI in +*C%% mode2 scriveremo: X0ile Y 0tp@getFXstream2 IHtmpH0ile.tLtI2 Idata.tLtI2 3 P@+*C%%GP Per vedere se l'operazione ha av#to o meno s#ccesso2 possiamo operare in d#e modi: controllare se e00ettivamente il 0ile c' nel nostro disco opp#re controllare il valore della variabile X0ile: se ha valore I&I allora l'operazione stata completata2 se ha valore I'I ness#n 0ile sarB stato scaricato s#l nostro disco.
,tpBput
8#esta 0#nzione 0a esattamente il contrario di 'tp1put892 ossia carica #n 0ile s#l server. La s#a sintassi : X0ile Y 0tp@p#tFXstream2 remote@0ilename2 local@0ilename2 modeGP Le opzioni sono identiche alle precedenti2 A#indi possiamo 0are l'esempio contrario del precedente: carichiamo il 0ile locale IHtmpH0ile.tLtI nella director, remota Fsiamo giB in A#esta director,G con il nome Idata.tLtI. #tto in +*C%% mode2 ovviamente: X0ile Y 0tp@p#t FXstream2 Idata.tLtI2 IHtmpH0ile.tLtI2 3 P@+*C%%GP +nche A#i2 possiamo controllare in d#e modi: val#tando il valore di X0ile opp#re invocando la 0#nzione 'tp1nlist89 per vedere se 0ra i 0ile c' anche Idata.tLtI.
44
,tpB%dt%
?estit#isce la data di #ltima modi0ica di #n 0ile2 restit#endola come 6niL timestamp. La sintassi : Xdate Y 0tp@mdtmFXstream2 remote@0ilenameGP +d esempio2 volendo sapere la data di #ltima modi0ica del 0ile Idata.tLtI possiamo scrivere: Xdate Y 0tp@mdtmFXstream2 Idata.tLtIGP +nche in A#esto caso2 la variabile IXdataI conterrB la data di #ltima modi0ica del 0ile opp#re il valore I9&I in caso di ins#ccesso F0ile inesistente o casi del genereG.
,tpBrena%e e ,tpBdelete
Come apparirB chiaro dai nomi2 A#este d#e 0#nzioni servono per rinominare #n 0ile e per cancellarlo. La prima ha sintassi: Xname Y 0tp@renameFXstream2 oldname2 newnameGP dove IoldnameI il nome originario del 0ile e InewnameI il n#ovo nome che vogliamo assegnare al 0ile. +d esempio2 per rinominare il 0ile Idata.tLtI in Idati.datI possiamo scrivere: Xname Y 0tp@renameFXstream2 Idata.tLtI2 Idati.datIGP La variabile Xname conterrB I&I se l'operazione ha av#to s#ccesso2 I'I altrimenti F0ile inesistente o casi similiG. La 0#nzione 'tp1delete892 invece2 si #tilizza con sintassi: Xdelete Y 0tp@deleteFXstream2 0ileGP +d esempio2 per eliminare il 0ile Idati.datI presente nella Ic#rrent9director,I possiamo scrivere: Xdelete Y 0tp@delete FXstream2 Idati.datIGP +nche in A#esto caso la variabile p#D contenere valore I&I Fil 0ile stato eliminatoG o I'I FA#alcosa non andato per il verso gi#stoG.
,tpBquit
+ A#esto p#nto2 il nostro lavoro s#l server terminato e possiamo disconnetterci #tilizzando la 4$
0#nzione 'tp1/uit89 che ha la semplice sintassi: XA#it Y 0tp@A#itFXstreamG. O sempre consigliato invocare A#esta 0#nzione invece di chi#dere il programma in esec#zione2 piJ che altro per #na A#estione di rispetto verso il server.
$e estensioni
Cei precedenti capitoli abbiamo visto le principali 0#nzioni legate al ling#aggio per la creazione delle nostre pagine dinamiche. La di00erenza 0ra A#elle 0#nzioni e la 0amiglia di A#elle che andremo a vedere sostanziale: le prime sono presenti direttamente all'interno del motore Fb#ilt9inG2 le seconde sono presenti in librerie aggi#ntive che devono essere installate s#l sistema e richiamate in maniera particolare. Prima di t#tto2 vediamo di capire il meccanismo di caricamento dinamico di A#este librerie: aprendo il 0ile php.ini vedremo #n paragra0o dedicato alle I.LtensionI2 ossia estensioni nel ling#aggio stesso: per spiegarci meglio2 potremo dire che A#este sono #n insieme di librerie che vengono richiamate al momento dell'esec#zione di #no script come avviene2 in maniera analoga2 per il caricamento dei mod#li con #n webserver. La sintassi per il caricamento di A#este estensioni di ling#aggio molto semplice: #na volta che avremo installato la libreria s#l sistema2 non ci resta che aggi#ngere nel 0ile php.ini la riga: eLtensionYlibreria O A#i necessario #n discorso mirato per i sistemi 6niL ed i sistemi 5indows: per entrambi la sintassi identica2 ma ovviamente il nome delle librerie e la loro estensione no. Cei sistemi 5indows2 #na libreria si riconosce dall'estensione I.dllI2 mentre per 6niL A#esta I.soI: A#indi2 a seconda del sistema2 dovremo #tilizzare il corretto nome per la libreria e2 sopratt#tto2 la corretta estensione. -vviamente2 per chi abbia entrambi i sistemi installati e riesca da #no dei sistemi a vedere l'altro chiaro che le dll non possono essere caricate s# #n sistema 6niL e viceversa. Cello scrivere il nome della libreria che ci interessa caricare2 non dobbiamo so00ermarci s#l percorso completo2 ma necessario solamente il nome della stessa2 ad esempio pgs/l.so per i database Postgres. 8#esto perch2 nello stesso 0ile2 presente #n'altra linea di con0ig#razione che de0inisce in A#ale director, sono presenti A#este librerie: leggendo il 0ile php.ini potrete trovare la riga eOtension1dir ) director che istr#irB il motore s#lla locazione standard delle librerie. 8#indi2 A#ando speci0ichiamo con eOtension #na libreria che vogliamo sia caricata per l'esec#zione di #no script2 vengono di 0atto #niti eOtension1dir ed eOtension: se ad esempio eOtension1dir /usr/lib/php e abbiamo impostato eOtension)pgs/l.so2 il PHP saprB che per caricare la libreria pgs/l.so dovrB cercarla in /usr/lib/php/pgs/l.so. %noltre2 con l'istr#zione eOtension) .... possibile speci0icare non solo #na libreria ma t#tta la seri di librerie che ci possono 0are comodo: ad esempio possiamo avere A#alcosa del tipo: eLtensionYpgsAl.so eLtensionYm,sAl.so eLtensionYgd.so eLtensionYimap.so $'
eLtensionYldap.do eLtensionYLml.so e via dicendoP come noterete dalla seconda riga2 poi2 possibile speci0icare anche d#e o piJ librerie per #no stesso IcampoI in A#esto caso2 ci sono d#e librerie per d#e database FPostgres e !,*8LG che2 oltre a non entrare in con0litto l'#na con l'altra2 potrebbero teoricamente anche essere #tilizzate contemporaneamente2 a patto che A#esto abbia #n'#tilitB. Cel caso si cerchi di richiamare #na 0#nzione non b#ilt9in all'interno di #no script2 lo script vis#alizza #na messaggio d'errore che ci avverte che stiamo cercando di #tilizzare #na 0#nzione non riconosci#ta: ad esempio2 per i database2 devono essere caricate le estensioni come detto prima e2 solo dopo aver compi#to A#esto passo2 sarB possibile #tilizzare le 0#nzioni ad essi relativi senza incorrere in messaggi d'errore2 sempre che A#este siano #tilizzate in maniera corretta2 ovviamente.
$a progra%%a&ione ad oggetti
Con l'avvento di PHP 5 il modo di concepire la programmazione ad oggetti in PHP cambiato radicalmente. %l modello ad oggetti sempli0icato che era presente 0ino alla versione 4 non che #n'ombra scialba di A#ello att#ale. Prima gli oggetti erano solamente #na 0#nzionalitB di s#pporto poco #tilizzata e veramente troppo poco 0lessibile. -ra gli svil#ppatori possono p#ntare s# #n s#pporto alla programmazione ad oggetti che avvicina il ling#aggio ai concorrenti piJ blasonati. %n PHP 5 la de0inizione di #na classe rispecchia molto piJ da vicino le esigenze degli svil#ppatori entrerprise. )ediamo di analizzare la sintassi #tilizzata con dei brevi esempi. La de,ini&ione di una classe avviene #tilizzando #na sintassi simile a A#ella precedente2 anche se $&
possiamo notare grosse di00erenze. %n primo l#ogo il costr#ttore della classe ora non deve avere lo stesso nome della classe stessa ma deve chiamarsi 11constructP in secondo l#ogo abbiamo la possibilitB di de0inire dei distr#ttori Fimplementati nel metodo 11destructG che verranno chiamati ogni A#alvolta il garbage collector di PHP distr#ggerB l'oggetto. -ltre a A#este piccole di00erenze2 0inalmente possibile speci0icare la visibilitB di metodi ed attrib#ti attraverso le parole chiave p#blic2 protected e private. )ediamo #n semplice esempio di classe: SNphp class Prova \ p#blic Xattr@p#blicP private Xattr@privateP protected Xattr@protectedP p#blic 0#nction @@constr#ctFG \ HH operazioni di inizializzazione ] p#blic 0#nction @@destr#ctFG \ HH operazioni eseg#ite prima della distr#zione ] p#blic 0#nction p#blic!ethodFG \ ] protected 0#nction protected!ethodFG \ ] private 0#nction private!ethodFG \ ] ] NT -ltre A#este di00erenze ora possibile Fe necessarioG speci0icare esplicitamente A#ali metodi o proprietB dovranno essere statiche. *olo le proprietB o i metodi statici possono essere acced#ti #tilizzando l'operatore ;;2 mentre prima PHP permetteva l'#tilizzo di A#ell'operatore per A#al#nA#e metodo. 8#indi la de0inizione di #n metodo proprietB statica pres#ppone l'anteposizione della parola chiave static prima della de0inizione. -vviamente l'ereditariet- ancora s#pportata2 ma grazie alle aggi#nte notevolmente migliorata. <i0atti possiamo s0r#ttare la possibilitB di de0inire la visibilitB di metodi e proprietB per 0acilitare il design dell'applicazione. SNphp $(
class .LtProva eLtends Prova \ p#blic 0#nction @@constr#ctFG \ parent::@@constr#ctFGP ] private 0#nction provaProtectedFG \ Xthis9T protected!ethodFGP ] ] NT
$e classi astratte
-ltre a A#esto2 PHP ha ampliato notevolmente le s#e potenzialitB introd#cendo le inter0acce e le classi astratte. 6n'inter,accia #na classe speciale che de0inisce solamente la str#tt#ra che dovranno obbligatoriamente avere le classi che la implementano. Con p#D essere istanziata. SNphp inter0ace Prova%nter0accia \ p#blic 0#nction m#st;e%mplementedFGP ] class Prova implements Prova%nter0accia \ p#blic 0#nction m#st;e%mplementedFG \ HH implementazione ] ] NT *e #na classe non dovesse implementare t#tti i metodi de0initi nell'inter0accia2 PHP restit#irebbe #n errore. Le classi astratte invece sono #n sistema che permette di de0inire classi parzialmente completate che lasciano l'implementazione di alc#ni metodi alle sottoclassi. 6na classe astratta deve essere de0inita #tilizzando la parola chiave abstractP lo stesso vale per A#ei metodi astratti della classe. )ediamo #n esempio: SNphp abstract class Prova+bs \ $1
p#blic 0#nction provaFG \ Xthis9Tabstract!ethodFGP ] abstract protected 0#nction abstract!ethodFGP ] class Prova eLtends Prova+bs \ protected 0#nction abstract!ethodFG \ HH metodo richiamato da Prova+bs::provaFG ] ] NT /razie alle inter0acce ed alle classi astratte2 PHP ha ra00orzato notevolmente il s#o s#pporto ai tipi di dato2 permettendo l'introd#zione del t,pe hinting per i tipi di dato complessi. Possiamo speci0icare il tipo di oggetto che ci aspettiamo per #n parametro di #n metodoH0#nzione demandando a PHP il compito di e00ett#are il controllo: SNphp 0#nction provaFProva+bs XargG \ Xarg9TprovaFGP ] NT %n A#esto modo possiamo assic#rarci #n'integritB delle chiamate che prima era A#asi impossibile se non con particolari controlli e00ett#ati a r#ntime.
$e costanti di classe e altre ,un&ionalit6n'altra aggi#nta interessante che ora possibile de0inire costanti di classe2 accedendovi #tilizzando l'operatore #sato per le proprietB o i metodi statici: SNphp class Prova \ const !%+@C-* +C . Y 'valore'P ] echo Prova::!%+@C-* +C .P NT
$4
6n'altra 0#nzionalitB molto interessante2 che prima era #tilizzabile solamente attraverso l'estensione overload ma ora b#ilt9in2 la possibilitB di de0inire dei metodi particolari per catt#rare t#tte le richieste in letturaLscrittura alle proprietB e le chiamate ai metodi2 nel caso non 0ossero trovati nell'albero dei simboli di #na classe. )ediamo #n semplice esempio: SNphp class Prova \ p#blic XprovaP private XdataP p#blic 0#nction @@constr#ctFG \ Xthis9Tdata Y arra,FGP ] p#blic 0#nction @@setFXname2 Xval#eG \ echo *critta la proprietB .Xname.SbrHTP Xthis9TdataZXname[ Y Xval#eP ] p#blic 0#nction @@getFXnameG \ echo ?ichiesta la proprietB .Xname.SbrHTP ret#rn Xthis9TdataZXname[P ] p#blic 0#nction testFG \ echo test methodP ] p#blic 0#nction @@callFXname2 XargsG \ echo ?ichiamato il metodo .Xname. con .co#ntFXargsG. argomentiP ] ] Xprova Y new ProvaP Xprova9Tprova Y &'P echo Xprova9TprovaP Xprova9Tciao Y ciaoP echo Xprova9TciaoP Xprova9Tmetodo%nesistenteF&2 (2 12 42 arra,FGGP NT Prima di terminare A#esta breve trattazione della programmazione ad oggetti2 vorrei parlare di #n $5
aggi#nta 0atta a PHP che permette di caricare a#tomaticamente i 0ile contenenti le de0inizioni delle classi nel momento in c#i non vengano trovate in 0ase di esec#zione. PHP richiama a#tomaticamente la 0#nzione BBautoload A#ando non trova #na classe: SNphp 0#nction @@a#toloadFXclassnameG \ echo Classe richiesta: .XclassnameP reA#ire@once Xclassname..phpP ] Xprova Y new ProvaFGP NT -vviamente #tilizzare direttamente il nome della classe non #n sistema corretto. ?icordiamoci sempre di controllare che il path ris#ltante o richiesto sia realmente accessibile e sia corretta la s#a richiesta.
\ Xthis9Tvalid Y F3+L*. MYY resetFXthis9Tarra,GGP ] p#blic 0#nction c#rrentFG \ ret#rn c#rrentFXthis9Tarra,GP ] p#blic 0#nction 7e,FG \ ret#rn 7e,FXthis9Tarra,GP ] p#blic 0#nction validFG \ ret#rn Xthis9TvalidP ] p#blic 0#nction neLtFG \ Xthis9Tvalid Y F3+L*. MYY neLtFXthis9Tarra,GGP ] ] class !iaLista implements %terator+ggregate \ private XrangeP p#blic 0#nction @@constr#ctFXmaLG \ Xthis9Trange Y rangeF'2 XmaLGP ] p#blic 0#nction get%teratorFG \ ret#rn new !iaLista%teratorFXthis9TrangeGP ] ] Xprova Y new !iaListaF5''GP 0oreachFXprova as XitemG \ echo Xitem.Sbr HTP ] NT Come potete notare dal codice intervengono le inter0accee 7terator ed 7teratorGggregate. La prima serve per permettere a PHP di assic#rarsi che l'iteratore rec#perato seg#a #na str#tt#ra precisa che permette di operare s#ll'elemento come se 0osse #n arra, $"
Frec#perando la chiave corrente2 il prossimo elemento2 l'elemento corrente2 o riavvolgendoG2 mentre la seconda serve per assic#rarsi che ogni oggetto #tilizzato da 0oreach come #n'arra, possa restit#ire #n iteratore in modo corretto2 tramite get%terator. L'esempio in realtB non molto signi0icativo perch lo stesso comportamento potrebbe essere otten#to #tilizzando #n normale arra,. !a pensiamo al rec#pero di memoria che potrebbe avvenire in A#esto caso: SNphp class !iaLista%terator implements %terator \ private XmaLP private XvalidP private Xc#rrentP p#blic 0#nction @@constr#ctFXmaLG \ Xthis9TmaL Y XmaLP Xthis9Tc#rrent Y 'P Xthis9Tvalid Y tr#eP ] p#blic 0#nction rewindFG \ Xthis9Tc#rrent Y 'P Xthis9Tvalid Y tr#eP ] p#blic 0#nction c#rrentFG \ ret#rn Xthis9Tc#rrentP ] p#blic 0#nction 7e,FG \ ret#rn Xthis9Tc#rrentP ] p#blic 0#nction validFG \ ret#rn Xthis9TvalidP ] p#blic 0#nction neLtFG \ Xthis9Tvalid Y QQXthis9Tc#rrent T Xthis9TmaLP ] ] class !iaLista implements %terator+ggregate $4
\ private XrangeP p#blic 0#nction @@constr#ctFXmaLG \ Xthis9Trange Y XmaLP ] p#blic 0#nction get%teratorFG \ ret#rn new !iaLista%teratorFXthis9TrangeGP ] ] Xprova Y new !iaListaF5'''''''''GP 0oreachFXprova as XitemG \ echo Xitem.Sbr HTP ] NT Con A#esto codice iteriamo s# #n n#mero molto elevato di elementi senza cons#mare eccessiva memoria. *arebbe stato molto d#ro ottenere lo stesso ris#ltato #tilizzando #n arra, di cinA#e miliardi di elementi. La *PL implementa iteratori per molte tipologie di dato e str#tt#re Farra,2 director, e molto altroG2 A#indi consiglio di st#diarla Fhttp:HHdatabase.html.itHg#ideHleggiH4"Hg#ida9 m,sAlHG per evitare di ripetere le operazioni giB 0atte nativamente da altri. 6n'altra classe che ritengo molto interessante 1rray2b>ect5 che permette ad #n oggetto di ass#mere il comportamento di #n normale arra,2 con la possibilitB di accedere ai s#oi elementi #tilizzando le parentesi A#adre. SNphp class 6sers eLtends +rra,-b:ect \ private XdbP p#blic 0#nction @@constr#ctFXdbG \ Xthis9Tdb Y XdbP ] p#blic 0#nction o00set/etFXindeLG \ Xres#lt Y Xthis9Tdb9TA#er,FI*.L.C R 3?-! #sers 5H.?. name Y 'I.XindeL.I'IGP ret#rn Xres#lt9T0etch@assocFGP ] p#blic 0#nction o00set*etFXindeL2 Xval#eG \ Xthis9Tdb9TA#er,FI6P<+ . #sers *. s#rname Y 'I.Xval#e.I' 5H.?. name Y 'I.XindeL.I'IGP $$
] p#blic 0#nction o00set.ListsFXindeLG \ Xres#lt Y Xthis9Tdb9TA#er,FI*.L.C R 3?-! #sers 5H.?. name Y 'I.XindeL.I'IGP ret#rn Xres#lt9Tn#m@rows T 'P ] p#blic 0#nction o00set6nsetFXindeLG \ Xthis9Tdb9TA#er,FI<.L. . 3?-! #sers 5H.?. name Y 'I.XindeL.I'IGP ] ] X#tenti Y new 6sersP echo X#tentiZ'/abriele'[P X#tentiZ'Paolo'[ Y '?ossi'P #nsetFX#tentiZ'3ederico'[GP NT 8#esto esempio vi 0a comprendere il 0#nzionamento di Grra ?b[ect: #na volta implementati i metodi sopra elencati2 possiamo tranA#illamente operare s#ll'istanza dell'oggetto come se 0osse #n'arra,. -vviamente sconsiglio di #tilizzare #n sistema simile per gestire gli #tenti2 ma Grra ?b[ect p#D ris#ltare molto #tile in molte sit#azioni di programmazione avanzata.
&''
.ntrodu&ione
La g#ida che vi state apprestando a leggere ill#strerB con degli ese%pi pratici il mondo della programmazione con PHP 5. Per chi non l'avesse ancora 0atto2 consiglio la lett#ra della g#ida base e della g#ida avanzata in modo che si abbia completa padronanza dei concetti che A#i andremo a mostrare. La g#ida si articola in #na serie di esempi molto semplici ma #tili al 0ine di analizzare le sit#azioni pratiche piJ com#ni che vengono a00rontate normalmente dall'#tente alle prime armi. Per provare gli esempi sarB necessario aver con0ig#rato correttamente il proprio PC Fsia esso eA#ipaggiato con Lin#L o 5indowsG con PHP 5.&.(2 !,*8L 4.& o s#periore ed +pache. *# A#esto sito potete trovare d#e g#ide esa#stive F#na per Lin#L Fhttp:HHphp.html.itHg#ideHleggiH$(Hg#ida9php9 s#9lin#LHG e #na per 5indows Fhttp:HHphp.html.itHg#ideHleggiH$4Hg#ida9php9s#9windowsHGG che ill#strano il processo di installazione e con0ig#razione di #n ambiente di svil#ppo adatto. Cei seg#enti paragra0i parleremo di operazioni #tili s#i 0ile2 invio mail2 gestione di database e sistema di ricerca. O 0ondamentale ricordare che la programmazione ha regole sintattiche 0erree2 ma s# alc#ne scelte logiche e 0#nzionali ris#lta molto soggettiva. %o cercherD di scrivere gli esempi nel modo piJ semplice e standard possibile2 ma vi avverto che d#rante l'analisi di event#ali altri script potreste incorrere in scelte progett#ali o organizzative molto diverse. Per #n'introd#zione piJ completa a PHP rimando alla g#ida base Fhttp:HHphp.html.itHg#ideHleggiH$$Hg#ida9php9di9baseHG.
SheadT StitleTProvaSHtitleT SHheadT Sbod,T Sh1T% miei gr#ppi pre0eritiSHh1T S#lT SNphp Xin0o Y new %n0o!anagerP 0oreachFXbands as Xband@nameG \ Xband@in0o Y Xin0o9T0ind%n0osFXbandGP echo ISliTI.Xband@nameP i0FMis@n#llFXband@in0oGG \ echo ' FSa hre0YI'.Xband@in0o9Tsite.'IT'.Xband@in0o9Tsite.'SHaTG'P ] echo ISHliTIP ] NT SH#lT SHbod,T SHhtmlT Premetto che A#esto2 a mio parare2 non #no dei modi migliori per organizzare conten#ti complessi o applicazioni alle A#ali lavoreranno piJ persone2 ma ritengo premat#ro trattare il discorso template in A#esta sede. )i lascio alla lett#ra degli articoli presenti s# H !L.it relativi a smart, ed agli altri template engine Fhttp:HHphp.html.itHarticoliHleggiH$'$Htemplate9engine9separare9programmazione9e9 designHG. ornando a noi il codice2 che ovviamente non 0#nzionerB se eseg#ito s#lla vostra macchina ca#sa la mancanza dei 0ile con0ig.php e in0o.php2 si occ#pa di incl#dere #n 0ile di con0ig#razione com#ne2 #na libreria e vis#alizzare #na lista di band m#sicali con event#almente il loro sito internet tra parentesi. L'incl#sione di 0ile esterni #n processo molto importante nella programmazione e viene e00ett#ato #tilizzando i costr#tti reA#ire2 incl#de o le loro varianti. Cel nostro caso abbiamo deciso di salvare dentro include/con'ig.php alc#ne variabili di con0ig#razione com#ni per t#tte le pagine2 dentro lib/in'o.php la de0inizione della classe %n0o!anager e di richiedere l'incl#sione di A#esti 0ile nel momento in c#i la nostra pagina 0osse richiamata da apache. La di00erenza tra reA#ire ed incl#de sottile ma molto signi0icativa: con il primo richiediamo obbligatoriamente l'incl#sione di #n 0ile. *e A#esti non esiste2 PHP genererB #n errore 0atale e terminerB l'esec#zione. Con il secondo invece richiediamo #n 0ile che non riteniamo 0ondamentale per il corretto 0#nzionamento del sistema. %n A#esto caso PHP restit#irB solamente #n warning in caso di mal0#nzionamento e procederB con l'esec#zione dello script. %l s#00isso I@onceI permette di assic#rarsi che il 0ile richiesto sia incl#so #na sola volta. 6n'altra in0ormazione che mi sento di 0ornirvi prima di contin#are A#ella che rig#arda la gestione dell'o#tp#t in PHP. *olitamente b#ona norma Fnel caso in c#i non si #tilizzino sistemi di templateG costr#ire all'interno di variabili stringa i blocchi di codice H !L che dovremmo mandare in o#tp#t2 e poi #tilizzare #na sola istr#zione echo alla 0ine del codice. 8#esto perchh le operazioni di o#tp#t sono molto dispendiose in termini di risorse2 e risparmiare s#lla chiamate ad echo Fo agli altri sistemi di o#tp#tG velocizza l'esec#zione delle pagine.
&'(
] p#blic 0#nction @@destr#ctFG \ 0closeFXthis9T0pGP ] ] class *impleCo#nter \ private XproviderP p#blic XvisitsP p#blic 0#nction @@constr#ctF<ataProvider XproviderG \ Xthis9Tprovider Y XproviderP Xthis9Tvisits Y Xthis9Tprovider9Tread)isitsFGP i0FXthis9Tis)alidFGG \ Xthis9Tprovider9Tstore)isitsFQQXthis9TvisitsGP ] ] protected 0#nction is)alidFG \ ret#rn tr#eP ] ] NT %l codice molto semplice: de0inisce #n'inter0accia che si occ#pa di rappresentare la str#tt#ra base di delle classi che potranno occ#parsi di rec#perare e salvare in0ormazioni s#lle visiteP implementa l'inter0accia con #n sistema che salva le in0ormazioni s# discoP de0inisce #na classe che2 A#ando costr#ita2 rec#pera le in0ormazioni da #n <ataProvider2 controlla la validitB dell'#tente corrente ed event#almente incrementa le visite. %s)alid stata messa per permettere alle classi che estenderanno *impleCo#nter di speci0icare sistemi di validazione personalizzati Fcome il controllo dell'%PG per creare co#nter piJ completi. L'#tilizzo della classe Fche salveremo dentro lib/counter.phpG il seg#ente: SNphp reA#ire@once 'libHco#nter.php'P Xco#nter Y new *impleCo#nterFnew 3ile<ataProviderGP echo I8#esta pagina _egraveP stata visitata I.Xco#nter9Tvisits.I volteIP NT +d ogni aggiornamento della pagina verrB incrementato il n#mero delle visite. Prima di testare lo &'4
script molto importante assic#rarsi che la director, corrente abbia i permessi impostati correttamente2 altrimenti il 0ile non potrB essere creato o scritto. *e volessimo impostare lo script in modo che l'aggiornamento delle visite non avvenga ad ogni reload della pagina da parte dello stesso #tente ma che2 #na volta e00ett#ata la prima visita2 non venga aggiornato il n#mero per #n determinato lasso di tempo2 possiamo #tilizzare vari sistemi. %l piJ semplice sic#ramente l'utili&&o di un coo0ie: SNphp class Coo7ieCo#nter eLtends *impleCo#nter \ p#blic 0#nction @@constr#ctF<ataProvider XproviderG \ parent::@@constr#ctFXproviderGP ] p#blic 0#nction is)alidFG \ i0FMissetFX@C-->%.Z'co#nter@coo7ie'[GG \ setcoo7ieF'co#nter@coo7ie'2 '&'2 timeFG Q 16''GP ret#rn tr#eP ] ret#rn 0alseP ] ] NT *alviamo A#esto 0ile in lib/cooCiecounter.php e modi0ichiamo leggermente il 0ile indeO.php: SNphp reA#ire@once 'libHco#nter.php'P reA#ire@once 'libHcoo7ieco#nter.php'P Xco#nter Y new Coo7ieCo#nterFnew 3ile<ataProviderGP echo I8#esta pagina _egraveP stata visitata I.Xco#nter9Tvisits.I volteIP NT .cco 0atto: #n gioco da ragazzi. -vviamente se non avete abilitati i coo7ie lo script non 0#nzionerB.
&'5
\ move@#ploaded@0ileFX0ileZ'tmp@name'[2 6PL-+<@<%?.X0ileZ'name'[GP ] ] ] NT 8#este poche righe di codice si occ#pano di controllare che i dati provenienti dalla pagina precedente siano corretti2 controllano la validitB del 0ile caricato ed e00ett#ano praticamente l'#pload salvando i dati ove necessario. L'arra, 21X7V.\ permette di accedere ai seg#enti valor: na%e: il nome del 0ile caricato originariamente dall'#tenteP t%pBna%e: il nome temporaneo del 0ile salvato da PHP in #na cartella localeP type: il mime t,pe del 0ile Fnel caso in c#i il browser 0ornisca A#esta in0ormazioneGP si&e: le dimensioni in b,te del 0ileP error: #n codice n#merico che indica l'event#ale errore d#rante il caricamento del 0ile. +d ogni n#mero possibile associata #na delle seg#enti costanti: 6PL-+<@.??@-> F'G: Con vi sono errori2 l'#pload stato eseg#ito con s#ccessoP 6PL-+<@.??@%C%@*%K. F&G: %l 0ile inviato eccede le dimensioni speci0icate nel parametro #pload@maL@0ilesize di php.iniP 6PL-+<@.??@3-?!@*%K. F(G: %l 0ile inviato eccede le dimensioni speci0icate nel parametro !+^@3%L.@*%K. del 0ormP 6PL-+<@.??@P+? %+L F1G: 6pload eseg#ito parzialmenteP 6PL-+<@.??@C-@3%L. F4G: Cess#n 0ile stato inviatoP 6PL-+<@.??@C-@ !P@<%? F6G: !ancanza della cartella temporaneaP
Con t#tte A#este in0ormazioni ris#lta molto semplice analizzare #n'operazione di #pload e comportarsi di conseg#enza. La 0#nzione is1uploaded1'ile controlla che #n 0ile sia e00ettivamente #no di A#elli caricati dall'#tente2 mentre move1uploaded1'ile e00ett#a 0isicamente lo spostamento del 0ile temporaneo nel 0iel di destinazione speci0icato. +ggi#ngendo alc#ni accorgimenti s#lle dimensioni ed impacchettando t#tto in #na libreria possibile gestire in modo molto completo il caricamento di 0ile online senza rischiare di incorrere in problemi o mal0#nzionamenti. Come sempre importante ricordarsi che il path di destinazione di move1uploaded1'ile deve essere #n path valido.
La 0#nzione mail ha #na str#tt#ra molto semplice che descriverD tra breve. P#rtroppo perD #na 0#nzione a basso livello2 che necessita di #na conoscenza completa dello standard !%!. per essere #tilizzata correttamente. Lo standard !%!. permette di de0inire messaggi 0ormati da parti aventi tipologie di conten#to di00erente2 A#ali2 nel nostro caso2 porzioni test#ali2 porzioni in H !L e 0ile allegati. La 0#nzione mail accetta A#attro parametri: il primo parametro indica l'indirizzo di posta del destinatarioP il secondo l'oggetto della mailP il terzo il testo del messaggioP il A#arto opzionale ma A#ello piJ potente: permette di speci0icare man#almente gli header del messaggio al 0ine di con0ig#rarlo correttamente per le nostre esigenze.
Cormalmente l'invio di #na mail test#ale nel A#ale si desidera speci0icare anche il destinatario viene e00ett#ato con A#esta breve riga di codice: mailFIg.0arinadhtml.it Fmailto:g.0arinadhtml.itGI2 Imesaggio di provaI2 I8#esto #n messaggio di prova test#aleI2 I3rom: testdhtml.it Fmailto:testdhtml.itGIGP 8#esta chiamata a 0#nzione restit#irB #n valore booleano rappresentante l'esito della chiamata a 0#nzione2 stamperB event#ali errori riscontrati d#rante l'invio F sempre #na b#ona idea 0ar precedere la chiamata da #na d per evitare A#esto comportamento e non rovinare il la,o#t della pagina in caso di erroriG e2 se t#tto sarB andato per il verso gi#sto2 invierB la mail. La 0#nzione mail non e00ett#a alc#na validazione dei dati inseriti2 A#indi sarB opport#no che vengano speci0icati dei valori corretti o accettabili. ;#ona norma A#ella di val#tare la validitB dell'indirizzo email di destinazione nel caso in c#i sia speci0icato da #n #tente esterno attraverso #n'espressione regolare: Xmail Y X@P-* Z'email'[P i0FeregiFIfZ@a9z'9$9[QFW.Z@a9z'9$9[QGRdZa9z'9$9[QFW.Za9z'9$9[QGRFW.Za9z[\(21]GXI2 XmailGG \ HH%nvio la mail ]else \ HHrestit#isco #n errore ] P#rtroppo A#esto sistema valida il 0ormato della mail ma non la reale validitB dell'indirizzo. Cel caso 0osse necessario attestare la validitB di A#esto2 esistono sistemi che si connettono ai server *! P della mail per sapere se l'indirizzo esiste o 0as#llo. 6tilizzando la 0#nzione mail89 possibile inviare email anche in 0ormato H !L: mailFIg.0arinadhtml.it Fmailto:g.0arinadhtml.itGI2 Imesaggio di provaI2 I8#esto #n SbTmessaggioSHbT di prova test#aleI2 IP7P.DUersion; 1.B%r%n+ontentDt pe; teOt/html; charset)isoDEE34D1%r%nXrom: testdhtml.it Fmailto:testdhtml.itGIGP -gni riga dell'intestazione deve essere separata da %r%n rispetto alla precedente. <obbiamo anche assic#rarci che nel messaggio siano conten#ti solo %n2 in modo da evitare spiacevoli inconvenienti. L'aggiunta di allegati al %essaggio #n processo leggermente piJ complesso che necessita della comprensione delle speci0iche !%!.. <ato che il discorso rischierebbe di diventare pesante e noioso2 consiglio a t#tti di iniziare #tilizzando A#alc#na delle centinaia di librerie presenti s# internet che svolgono A#esti compiti2 e di lasciarsi A#alche ora libera per st#diarsi la re0erence delle speci0iche mime ed implementare #na propria versione del sistema. &'4
snello ed oltret#tto non si basa s# #n'architett#ra clientHserver ma solamente #na libreria per interrogare 0ile relazionaliG2 c' da dire che nella maggior parte delle sit#azioni reali si #tilizzerB #n database relazionale per lavorare. Ho deciso di trattare !,*8L sopratt#to per il 0atto che con l'#scita di PHP 5 stata rilasciata la libreria m s/li che 0ornisce #n accesso ad oggetti al database e ris#lta molto piJ comoda e potente da #tilizzare. <opo esserci assic#rati che la libreria m s/li sia disponibile s#l nostro sistema2 possiamo iniziare ad #tilizzarla. La prima operazione da e00ett#are ovviamente A#ella della connessione al server. %n A#esti esempi pres#ppongo che ci sia #n server !,*8L in esec#zione s#lla macchina locale2 che sia presente #n database di prova chiamato Itest@html@itI e che l'#tente #tilizzato FrootG non abbia impostata alc#na password. La connessione p#D avvenire utili&&ando due di ersi %etodi. %l primo il piJ classico ma anche A#ello sconsigliato2 e prevede l'#tilizzo di #na 0#nzione Fm s/li1connectG avente lo stesso comportamento di m s/l1connect con la piccola di00erenza che possiamo speci0icare come parametro aggi#ntivo il nome del database al A#ale connetterci: Xm,sAl Y m,sAli@connectF'localhost'2 'root'2 ''2 'test@html@it'GP %l secondo metodo invece piJ interessante e prevede la creazione di #n oggetto #tilizzando la classe m,sAli: Xm,sAl Y new m,sAliF'localhost'2 'root'2 ''2 'test@html@it'GP % metodi potrebbero sembra simili2 ma il primo restit#isce #na risorsa che dovrB essere gestita esplicitamente con chiamate a 0#nzioni m,sAli@R2 mentre il secondo metodo restit#isce l'istanza di #n oggetto 'm,sAli' che potrB essere interrogato direttamente. %l metodo ad oggetti seg#e meglio la 0iloso0ia di PHP 5 Fanche se #na migliore gestione delle eccezioni non avrebbe 0atto sic#ramente male a ness#noG e A#indi A#ello che appro0ondiremo. 6na volta aperta la connessione saremo liberi di lavorarci e di chi#derla alla 0ine delle nostre operazioni #tilizzando il metodo closeFG: Xm,sAl9TcloseFGP
QQXiP ] Cel codice precedente inseriamo #n record nella pres#nta tabella Ia#toriI2 rec#periamo t#tti A#elli che hanno il nome che inizia per IgabI2 stampiamo il totale e la loro lista. Come possiamo notare nel caso in c#i si e00ett#i #n'operazione di selezione viene restit#ito #n oggetto Fm s/li1resultG che contiene metodi per iterare s#lle righe rec#perate2 per conoscerne il totale e molto altro. La proprietB num1rows di A#esto oggetto de0inisce il n#mero di righe rec#perateP invece attraverso 'etch1assocFG viene restit#ito sotto 0orma di arra, associativo il prossimo record trovato. .sistono altri metodi 0etch@R che permettono di rec#perare i dati in 0ormati di00erenti. 6na delle cose piJ interessanti dell'estensione MyS@$ .%pro ed il s#pporto per i prepared statement Fhttp:HHphp.html.itHarticoliHleggiH&"4'Haccesso9ai9database9in9php9con9lo9zend9 0ramewor7H(HG. 6n prepared statement #na A#er, *8L di A#al#nA#e tipo che viene parzialmente compilata dall'engine !,*8L e che p#D essere eseg#ita #n n#mero m#ltiplo di volte con parametri di00erenti e con alte prestazioni. %l metodo prepare89 permette di creare #n prepared statement: SNphp Xm,sAl Y new m,sAliF'localhost'2 'root'2 ''2 'test@html@it'GP Xstmt@& Y Xm,sAl9TprepareFI*.L.C R 3?-! n#meri 5H.?. valore Y NIGP Xstmt@( Y Xm,sAl9TprepareFI%C*.? %C - n#meri )+L6.* FNGIGP 0orFXi Y 'P Xi S &''P QQXiG \ Xstmt@(9TeLec#teFXiGP ] 0orFXi Y 'P Xi S &''P Xi QY "G \ Xres#lts Y Xstmt@&9TeLec#teFXiGP Xres#lt Y Xres#lts9T0etch@assocFGP echo I)alore rec#perato: I.Xres#ltZ'val#e'[.ISbr HTIP ] Xm,sAl9TcloseFGP N Cel codice precedente abbiamo preparato d#e A#er, compilate2 #na di selezione ed #na di inserzione. Poi abbiamo popolato #na tabella con cento n#meri ed abbiamo rec#perato i m#ltipli di sette. L'esempio completamente in#tile2 ma 0a comprendere il 0#nzionamento dei prepared statement. %l p#nto di domanda rappresenta #n parametro alla A#er,: in base al n#mero di p#nti di domanda dovranno essere passati #n eg#al n#mero di parametri al metodo eOecute89 dell'oggetto restit#ito da prepare89. O importante ricordare che i p#nti di domanda non vengono sostit#iti all'interno di stringhe2 e che sono a#tomaticamente A#otati se necessario. /razie ai prepared statement possiamo e00ett#are centinaia di A#er, simili ottenendo dei netti miglioramenti nelle per0ormance ed #na migliore organizzazione del codice. &&&
Xm,sAl Y new m,sAliF'localhost'2 'root'2 ''2 'html@it@articles'GP i0FMXm,sAlG \ dieFI.rrore di connessione al database2 impossibile procedereIGP ] Xres#lt Y Xm,sAl9TA#er,FI*.L.C C-6C FRG +* tot 3?-! articlesIG9T0etch@assocFGP Xpage Y issetFX@/. Z'p'[G N X@/. Z'p'[ : &P Xtotals Y Xres#ltZ'tot'[P Xtotals@pages Y ceilFXtotals H XlimitGP Xarticles Y Xm,sAl9TA#er,FI *.L.C +?.id +* id2 +?.title +* title2 C-CC+ F*6;* ?F+?.article2 &2 (''G2 ' ...'G +* content2 C-CC+ F+6.s#rname2 ' '2 +6.nameG +* a#thor 3?-! articles +?2 a#thors +6 5H.?. +?.a#thor@id Y +6.id -?<.? ;a id <.*C L%!% I.FFXpage 9 &G R XlimitG.I2I.XlimitGP NT ShtmlT SheadT StitleT+rticoliSHtitleT SHheadT Sbod,T S#lT SliTSa hre0YIindeL.phpITLista articoliSHaTSHliT SliTSa hre0YIinsert.phpIT%nserisci #n articoloSHaTSHliT SH#lT SpT+rticoli totali: SNphp echo XtotalsP NTSHpT Stable widthYI5''pLIT SNphp whileFXarticle Y Xarticles9T0etch@assocFGG \ print0F'StrT StdTbd. Sa hre0YIshow.phpNidYbdITbsSHaT FbsG SHtdT SHtrT StrT StdTSpTbsSHpTSHtdT SHtrT StrT StdTShr HTSHtdT SHtrT'2 &&1
XarticleZ'id'[2 XarticleZ'id'[2 XarticleZ'title'[2 XarticleZ'a#thor'[2 XarticleZ'content'[ GP ] NT SHtableT SpTPagina SNphp echo XpageP NT di SNphp echo Xtotals@pagesP NT Sbr HT SNphp i0FXpage 9 & T 'G \ echo 'Sa hre0YINpY'.FXpage 9 &G.'IT_ltP prevSHaT e 'P ]else \ echo '_ltP prev e 'P ] i0FXpage Q & SY Xtotals@pagesG \ echo 'Sa hre0YINpY'.FXpage Q &G.'ITneLt _gtPSHaT'P ]else \ echo 'neLt _gtP'P ] NT SHpT SHbod,T SHhtmlT %l codice vol#tamente semplice e lineare: per prima cosa ci connettiamo al database m,sAl e ci assic#riamo che la connessione sia andata a b#on 0ine. Poi rec#periamo il n#mero totale degli articoli presenti nel database e calcoliamo il n#mero di pagine da vis#alizzare in base al limite impostato all'inizio dello script. *#ccessivamente rec#periamo la lista di articoli che devono essere vis#alizzati nella pagina corrente2 limitando la selezione in base alla pagina nella A#ale si sta navigando. 6na volta e00ett#ata la selezione procediamo con la prod#zione di codice H !L: per prima cosa stampiamo il totale degli articoli trovati2 poi iteriamo s#i ris#ltati al 0ine di poter stampare le righe della tabella contenenti le in0ormazioni richieste. %n0ine2 a tabella terminata2 costr#iamo #na semplicissima barra di navigazione che permette di m#overci tra le pagine.
Xm,sAl Y new m,sAliF'localhost'2 'root'2 ''2 'html@it@articles'GP i0FMXm,sAlG \ dieFI.rrore di connessione al database2 impossibile procedereIGP ] i0FMissetFX@/. Z'id'[GG \ headerF'Location: indeL.php'GP ] Xarticle Y Xm,sAl9TA#er,FI *.L.C +?.id +* id2 +?.title +* title2 +?.article +* content2 C-CC+ F+6.s#rname2 ' '2 +6.nameG +* a#thor 3?-! articles +?2 a#thors +6 5H.?. +?.a#thor@id Y +6.id +C< +?.id Y I.X@/. Z'id'[G9T0etch@assocFGP NT ShtmlT SheadT StitleT+rticolo FSNphp echo XarticleZ'id'[P NTGSHtitleT SHheadT Sbod,T S#lT SliTSa hre0YIindeL.phpITLista articoliSHaTSHliT SliTSa hre0YIinsert.phpIT%nserisci #n articoloSHaTSHliT SH#lT Sh1TSNphp echo XarticleZ'title'[P NTSHh1T SiTSNphp echo XarticleZ'a#thor'[P NTSHiT SpT SNphp echo XarticleZ'content'[P NT SHpT SHbod,T SHhtmlT +nche processo di inserimento di #n articolo molto semplice: lasceremo selezionare all'#tente l'a#tore2 speci0icare #n titolo ed #n testo e salveremo t#tto nella tabella creata in precedenza rindirizzando la navigazione alla pagina principale. .cco il codice necessario: SNphp Xm,sAl Y new m,sAliF'localhost'2 'root'2 ''2 'html@it@articles'GP i0FMXm,sAlG &&5
\ dieFI.rrore di connessione al database2 impossibile procedereIGP ] i0FissetFX@P-* Z'action'[G and X@P-* Z'action'[ YY 'insert'G \ Xm,sAl9TA#er,FI%C*.? %C - articles )+L6.* F''2 'I.X@P-* Z'a#thor'[.I'2 'I.addslashesFX@P-* Z'title'[G.I'2 'I.addslashesFX@P-* Z'article'[G.I'GIGP headerF'Location: indeL.php'GP ] Xa#thors Y Xm,sAl9TA#er,FI*.L.C id2 C-CC+ Fs#rname2 ' '2 nameG +* 0#llname 3?-! a#thors -?<.? ;a s#rname +*CIGP NT ShtmlT SheadT StitleT%nserimento articoloSHtitleT SHheadT Sbod,T S#lT SliTSa hre0YIindeL.phpITLista articoliSHaTSHliT SliTSa hre0YIinsert.phpIT%nserisci #n articoloSHaTSHliT SH#lT Sh1T%nserisci #n articoloSHh1T S0orm actionYII methodYIpostIT Sinp#t t,peYIhiddenI nameYIactionI val#eYIinsertI HT SlabelT+#tore:SHlabelT Sselect nameYIa#thorIT SNphp whileFXa#thor Y Xa#thors9T0etch@assocFGG \ echo ISoption val#eYI.Xa#thorZ'id'[.ITI.Xa#thorZ'0#llname'[.ISHoptionTIP ] NT SHselectTSbr HT SlabelT itolo:SHlabelT Sinp#t t,peYIteLtI nameYItitleI sizeYI55IHTSbr HT SlabelT eLt:SHlabelTSbr HT SteLtarea nameYIarticleI rowsYI6I colsYI6'ITSHteLtareaTSbr HT Sinp#t t,peYIs#bmitI val#eYI*alvaI HT SH0ormT SHbod,T SHhtmlT L'#nica cosa s# c#i 0are attenzione il 0atto che il 0orm rimanda alla stessa pagina Fnon avendo speci0icato alc#na actionG e che A#indi dobbiamo scrivere del codice che ci permetta di sapere se sono stati inviati dei dati in post ed in caso a00ermativo salvi i dati s# database. ?icordatevi che 0ondamentale controllare i dati che arrivano in inp#t in modo da non rischiare di incorrere in attacchi di in:ection o problemi di vis#alizzazione dov#ti ad inp#t scorretto. Cel mio esempio non ho 0atto alc#n controllo del genere2 ma molto importate nelle applicazioni reali se si vogliono evitare problemi.
&&6
( !ario ?ossi )ia ?oma mariorossids#amail.it Come possibile osservare2 le colonne della tabella sono contrassegnate da delle voci che sono anche i nomi dei campi2 ogn#na di A#este voci contiene le in0ormazioni relative alle caratteristiche dei dati conten#ti nelle righe e al tipo di dato ad essi associatoP nello speci0ico del caso proposto in esempio2 il campo denominato Iid@clientiI associato ad #n tipo di dato n#merico intero positivo2 mentre t#tti gli altri campi sono associati ad #n tipo di dato stringa. %l campo id@clienti svolge la 0#nzione di chia e pri%aria2 ad esso in0atti associato #n valore che #nivoco per ogni record all'interno della tabella2 si tratta di #n campo 0ondamentale in A#anto consente di possedere #n elemento grazie al A#ale disting#ere i diversi record archiviatiP associare man#almente #n identi0icatore per ogni record non sarebbe possibile in presenza di grandi A#antitB di in0ormazioni2 diventa A#indi necessario ricorrere ad #n'applicazione che sia in grado di svolgere A#esta operazione al posto dell'#tilizzatore Come anticipato2 le proced#re per la manipolazione dei dati2 cio operazioni come il loro inserimento2 il loro aggiornamento2 la loro ricerca e la loro rimozione2 sono possibili grazie ad appositi programmi detti <;!* F<atabase !anager *,stemG che consentono di avere #na rappresentazione dei dati sotto 0orma di concetti. 6n database p#D essere composto da piJ tabelle2 A#este hanno la 0#nzione di separare argomenti diversi che perD possono avere tra loro delle relazioniP si introd#ce cosE nella descrizione dei database il cosiddetto %odello rela&ionale2 #n modello che si 0onda s#ll'ass#nto che le in0ormazioni siano rappresentate da valori compresi all'interno di relazioni chiamate tabelle2 per c#i #n database di tipo relazionale viene visto come #n insieme di relazioni tra valori e il ris#ltato di A#al#nA#e manipolazione dei dati p#D essere restit#ito sotto 0orma di tabelle. Per chiarire A#anto appena esposto2 si pensi per esempio che nello stesso database che contiene la tabella IClientiI proposta in precedenza sia presente anche #na seconda tabella chiamata IProdottiI2 destinata a contenere le in0ormazioni relative ai prodotti in vendita presso l'attivitB commerciale: idBprodotto prodotto %arca pre&&o & stampante *#perprint 6$2'' ( mo#se !o#seb#rger "2'' -ra si immagini di avere #na terza tabella2 chiamata per esempio I+cA#istiI e conten#ta sempre nello stesso database2 all'interno della A#ale memorizzare i dati relativi ai prodotti acA#istati e ai clienti che li hanno comprati: idBacquisto idBprodotto idBcliente data & ( ( ((9'(9'$ ( & & '&9'&9'$ !ettendo in relazione gli identi0icatori delle d#e tabelle proposte in precedenza2 si ha A#indi la possibilitB di relazionare ogni singolo acA#isto con il cliente che lo ha e00ett#ato e con il relativo prodotto2 il t#tto possibile senza dover speci0icare ogni volta t#tti i dati relativi ai prodotti disponibili o ai diversi nominativi escl#dendo A#alsiasi ambig#itB. !a nello stesso tempo la terza tabella mostra come s#ssistano delle relazioni all'interno di essa2 interrogandola attraverso #n <;!* sarB in0atti possibile estrarre soltanto i record relativi ad #n determinato cliente2 ad #n determinato cliente in #na determinata data2 alle vendite di #no speci0ico prodotto in #n intervallo di date e molto altro. Le basi di dati per le applicazioni 5eb based sono generalmente impostate s#lla base dello stesso principio 0ondato s#lle relazioni2 ad esempio: in #n blog vi saranno delle relazioni tra #tenti e post p#bblicati2 tra commenti e relativi post2 tra i commenti e gli #tenti che li hanno scritti e cosE via. &&4
Per la gestione di database relazionali sono necessarie particolari applicazioni dette ?<;!* F?elational <atabase !anager *,stemG2 !,*8L l'?<;!* -pen *o#rce piJ #tilizzato per la creazione di applicazioni 5eb based realizzate in PHP2 A#indi d#rante i s#ccessivi capitoli di A#esta trattazione !,*8L sarB l'applicazione di ri0erimento per l'archiviazione dei dati nei database e per la loro manipolazione.
$a connessione a MyS@$
Gre i segnala&ioni pri%a di procedere nel corso di A#esta trattazione2 le 0#nzioni PHP non verranno preced#te dall'operatore di silence FbG2 per permettere la vis#alizzazione di event#ali errori in sede di svil#ppoP si raccomanda invece di #tilizzare sempre l'operatore di silence in 0ase di prod#zioneP t#tto il codice #tilizzato per A#esta g#ida p#D essere scaricato Fhttp:HHwww.html.itHg#ideHdownloadHphp@m,sAlHblog.zipG ed #tilizzato liberamenteP le versioni dei server #tilizzate nella g#ida sono le seg#enti: PHP versione 5.(.&'2 !,*8L versione 4.&.((9standard2 +pache versione (.(.&& FLin#LG. Perchh #n'applicazione realizzata in PHP possa #tilizzare le in0ormazioni conten#te all'interno di #n database A#esta deve poter avere accesso ad esse2 a A#esto scopo l'applicazione dovrB poter com#nicare con l'?<;!* che gestisce la base di dati2 ciD possibile attraverso #n proced#ra iniziale e necessaria chiamata IconnessioneIP per evitare ambig#itB bene chiarire che la proced#ra di connessione avviene tra lo script e il programma che gestisce la base di dati e non tra lo script e la base di dati stessaP #na volta terminata la proced#ra necessaria per la connessione all'?<;!*2 sarB possibile avviarne #na seconda chiamata di IselezioneI del database da #tilizzare. Per aprire #na connessione da #n'applicazione in PHP al database manager !,*8L2 si #tilizza #na 0#nzione nativa del ling#aggio chiamata m s/l1connect892 essa restit#isce #n identi0icativo di connessione !,*8L in caso di s#ccesso2 diversamente restit#isce FALSEP A#esta 0#nzione richiede il passaggio di tre parametri che sono argomenti della 0#nzione: &. hostna%e: il nome dell'host Fo macchina ospitanteG relativa al database manager !,*8L a c#i si desidera e00ett#are #na connessione2 esso identi0ica #nivocamente #na postazione in ?ete e p#D essere espresso sotto 0orma di indirizzo %P o stringa event#almente seg#ita dal n#mero della porta attraverso c#i l'?<!* attende le chiamate da parte dei client Fi comp#ter degli #tenti che intendono interrogare i databaseG2 nel caso di #n'installazione locale l'hostname generalmente chimato IlocalhostIP (. userna%e: il nome dell'#tente abilitato alla connessione e alla manipolazione di #no o piJ databaseP !,*8L prevede #n #tente iniziale che A#ello di root a c#i sono associati i privilegi per la manipolazione delle basi di dati gestite2 l'#tilizzatore potrB poi creare altri #tenti a c#i associare #n #sername e privilegi comparabili o in0eriori a A#elli previsti per il rootP 1. pass'ord: per A#estioni di sic#rezza b#ona norma associare #na password ad ogni n#ovo #tente !,*8L creato2 A#esta permetterB di a#tenticarlo al momento della connessione con il <atabase manager. % tre parametri da passare a m s/l1connect89 possono essere espressi sia sotto 0orma di variabili che sotto 0orma di valori p#ri2 l'ordine da rispettare A#ello proposto in elenco2 per c#i sarB possibile #tilizzare sia #na 0orma del genere:
// hostname 2nomehost ) "localhost";
&&$
// utente per la connessione a P \0V 2nomeuser ) "username"; // password per l#autentica(ione dell#utente 2password ) "password"; // connessione tramite m s/l1connect89 2connessione ) m s/l1connect82host$2user$2pass9;
6n b#on metodo per permettere ad #n'applicazione realizzata in PHP di connettersi a !,*8L A#ello di #tilizzare #na classe:
<?php class P s/l+lass H // parametri per la private 2nomehost ) private 2nomeuser ) private 2password )
// controllo sulle connessioni attive private 2attiva ) 'alse; // 'un(ione per la connessione a P \0V public 'unction connetti89 H i'8"2thisD>attiva9 H 2connessione ) m s/l1connect82thisD>nomehost$2thisD>nomeuser$2thisD >password9; IelseH return true; I I I ?>
Per A#anto la programmazione per oggetti possa presentare A#alche complessitB in piJ rispetto a A#ella che seg#e il paradigma proced#rale2 il meccanismo #tilizzato dalla classe appena proposta ris#lta abbastanza semplice: i parametri per la connessione al <;!* vengono associati al modi0icatore IprivateI che li renderB disponibili soltanto all'interno della classe di appartenenza2 secondo le regole di visibilitB introdotte dal paradigma --P nelle #ltime versioni di PHPP viene e00ett#ato #n controllo s#ll'event#ale esistenza di connessioni attiveP viene de0inita #na 0#nzione personalizzata Fdenominata connetti89G che potrB essere richiamata nel caso si voglia stabilire #na connessione a !,*8LP in A#esto caso alla 0#nzione viene associato il modi0icatore public2 ciD v#ol dire che gli attrib#ti e i metodi di c#i sono dotati gli oggetti ad essa relativi saranno accessibili anche esternamente alla classeP nel caso in c#i non sia giB attiva alc#na connessione2 i parametri necessari ad essa verranno passati alla 0#nzione primitiva m s/l1connect89 che si occ#perB di stabilirla2 diversamente la richiesta di accesso al <;!* non verrB inviata. 8#esta classe2 che verrB implementata con n#ove 0#nzionalitB nel corso della trattazione2 potrB &('
essere salvata in #n 0ile chiamato ad esempio funzioni_mysql.php Fo se si pre0erisce il classico config.phpGP essa potrB essere richiamata in A#alsiasi momento da A#alsiasi 0ile con #na semplice incl#sioneP perchh la classe possa essere #tilizzata dovrB essere istanziata2 nello stesso modo sarB possibile #tilizzare la 0#nzione per la connessione a !,*8L tramite #na semplice chiamata:
// inclusione del 'ile contenente la classe include "'un(ioni1m s/l.php" // istan(a della classe 2data ) new P s/l+lass89; // chiamata alla 'un(ione di connessione 2dataD>connetti89;
*i analizzino le diverse componenti della 0#nzione proposta: viene de0inita #na 0#nzione chiamata disconnetti89 il c#i compito sarB A#ello di chi#dere event#ali connessioni attiveP la 0#nzione e00ett#a #n controllo s#lla base del A#ale stabilirB se portare avanti o meno la proced#ra di chi#s#ra2 in0atti A#esta sarB att#ata soltanto nel caso in c#i sia presente #na connessione attivaP nel caso in c#i sia stata aperta #na connessione verrB allora richiamata la 0#nzione nativa m s/l1close89 per la s#a chi#s#raP &(&
la 0#nzione prevede ?6. come valore di ritorno nel caso in c#i la connessione sia stata chi#sa con s#ccesso2 3+L*. in caso contrario. La 0#nzione per la disconnessione va #tilizzata soltanto A#ando non piJ necessario che l'applicazione mantenga #n contatto aperto con !,*8L2 A#indi2 se s#ccessivamente a A#ella di connessione sono presenti istr#zioni per interrogare o manipolare i dati2 la 0#nzione di chi#s#ra andrB richiamata soltanto dopo di esseP anche in A#esto caso la chiamata alla 0#nzione avverrB per istanza:
// chiamata alla 'un(ione di disconnessione 2dataD>disconnetti89;
O ovvio che A#esta chiamata potrB avvenire non prima dell'incl#sione del 0ile in c#i presente la classe che contiene la 0#nzione.
$'estensione MyS@$i
L'estensione MyS@$i F!,*8L improvededG stata messa a disposizione di PHP per s0r#ttare alc#ne n#ove 0#nzionalitB messe a disposizione dalle versioni di !,*8L 4.&.1 e s#ccessive ed disponibile per PHP 5 e release s#periori. !,*8Li 0ornisce n#ovi str#mento per lo svil#ppatore che desidera realizzare applicazioni in grado di inter0acciarci con A#esto ?<;!*: introd#ce la possibilitB di s0r#ttare #n approccio basato s#l paradigma ob:ect orientedP permette l'#tilizzo di #n protocollo binario per la com#nicazione che assic#ra prestazioni piJ elevateP 0ornisce il s#pporto per le prepared statements cio istr#zioni *8L precedentemente #tilizzate e manten#te in cache per s#ccessive chiamate2 con innegabili vantaggi a carico di ottimizzazione e prestazioniP mette a disposizione 0#nzionalitB avanzate per il deb#ggingP permette di #tilizzare stored proced#res2 A#er, m#ltiple e transazioni. Le 0#nzionalitB messe a disposizione da !,*8Li possono essere #tilizzate sia all'interno di #n contesto proced#rale che in #n'applicazione svil#ppata #tilizzando l'approccio per oggettiP in0atti2 per la maggior parte delle 0#nzioni disponibili tramite A#esta estensione esiste #n metodo corrispondente2 ad esempio: la 0#nzione m s/li1'etch1arra 89 Fmolto simile alla 0#nzione m s/l1'etch1arra 899 messa a disposizione dall'estensione !,*8LG corrisponde al metodo m s/li1result;;'etch1arra . Per gli esempi di A#esta trattazione verrB privilegiato l'approccio --P. 6tilizzando il paradigma per oggetti in !,*8Li2 la connessione al <;!* avviene per istanza2 come nell'esempio seg#ente:
// connessione a P \0V con l#estensione P \0Vi 2 m s/li ) new m s/li8"localhost"$ "username"$ "password"$ "nome1database"9;
Cel codice proposto viene e00ett#ata #n'istanza dell'oggetto 2m s/li appartenente alla classe Im,sAliI2 si noti come al costr#ttore non venga passato lo stesso n#mero di parametri necessari per la 0#nzione m s/l1connect892 cio nome di host2 nome #tente2 password #tente2 ad essi si aggi#nge in0atti il parametro relativo al nome del database prede0inito per l'applicazione2 non ci sarB A#indi bisogno di #na 0#nzione come m s/l1select1db89. &((
m s/li1connect1errno89 #na 0#nzione che restit#isce il n#mero identi0icativo di #n event#ale errore prodotto d#rante #n tentativo di connessione2 nell'esempio proposto2 se la 0#nzione restit#isce #n valore signi0ica che l'#ltima connessione tentata andata 0allita2 sarB A#indi necessario bloccare l'esec#zione del codice seg#ente tramite la 0#nzione eOit892 nello stesso modo la 0#nzione m s/li1connect1error89 permetterB di vis#alizzare l'errore prodotto in connessioneP diversamente2 stabilita la connessione2 A#esta potrB essere chi#sa #tilizzando il metodo close892 A#est'#ltimo non da #tilizzare obbligatoriamente ma ne consigliabile l'impiego per le stesse motivazioni espresse in precedenza a proposito della 0#nzione m s/l1close89. Per e00ett#are #n'interrogazione tramite l'estensione !,*8Li possibile #tilizzare #n metodo apposito denominato A#er,FG2 il metodo accetta come argomento la A#er, *8L che si desidera lanciare al <atabase server. *i veda il seg#ente esempio:
- estrarre risultati con il metodo m s/li1result;;'etch1arra // /uer argomento del metodo /uer 89 2/uer ) " \.V.+@ titolo1post XW?P post ?WK.W !` data1post K.\+ "; // esecu(ione della /uer 2result ) 2m s/liD>/uer 82/uer 9; // conteggio dei record restituiti dalla /uer i'82resultD>num1rows >B9 H // genera(ione di un arra numerico while82row ) 2resultD>'etch1arra 8P`\0V71>YP99 H echo 2rowLBM; echo "<br />%n"; I I // libera(ione delle risorse occupate dal risultato 2resultD>close89;
passato come argomento al metodo /uer 892 A#esto arra, potrB essere di tre tipi: n#merico2 associativo o di entrambi i tipi precedentiP nell'esempio appena esposto il metodo prod#ce #n arra, di tipo n#merico grazie all'argomento !a*8L%@C6!2 A#indi verranno associati degli indici n#merici ai diversi valori dei record ris#ltanti dalla A#er,. L'esempio s#ccessivo2 mostra come ottenere lo stesso ris#ltato del codice precedente generando #n arra, associativo grazie al A#ale i diversi record avranno come indice il nome dei campi2 il t#tto possibile #tilizzando l'argomento !a*8L%@+**-C in l#ogo di !a*8L%@C6!:
- genera(ione di un arra associativo while82row2 ) 2resultD>'etch1arra 8P`\0V71G\\?+99 H echo 2rowL#titolo1post#M; echo "<br />%n"; I
!,*8L@;- H permette invece di #tilizzare sia gli indici n#merici che A#elli associativiP si noti l'#tilizzo del metodo m s/li1result;;num1row che restit#isce il n#mero di record restit#iti da #na A#er,. !,*8Li si presenta come #na valida alternativa all'estensione !,*8L2 sopratt#tto per A#anto rig#arda le applicazioni che dovranno essere 0r#ite da #n alto n#mero di #tenti2 si tratta perD di #n'estensione ancora incompleta che al momento non dato sapere se verrB s#pportata s#00icientemente in 0#t#ro2 per c#i conoscere le 0#nzioni disponibili grazie all'estensione !,*8L rimane 0ondamentale.
La 0#nzione proposta 0#nziona secondo #na logica abbastanza semplice ma possono essere #tili alc#ni appro0ondimenti: prima di eseg#ire l'operazione prevista2 la 0#nzione controlla sempre che sia presente #na connessione attivaP nel caso in c#i l'applicazione sia in com#nicazione con il <;!* allora verrB eseg#ita la A#er, passando alla 0#nzione nativa m,sAl@A#er,FG l'istr#zione rappresenta dalla variabile XsAlP nel caso in c#i la A#er, non dovesse avere s#ccesso a ca#sa di #n errore2 allora la 0#nzione m,sAl@errorFG si occ#perB di intercettare l'eccezione e di in0ormare l'#tilizzatore relativamente alla tipologia del mal0#nzionamento in corsoP se per esempio si tentasse di creare #n database chiamato mioblog e A#esto dovesse essere giB presente tra A#elli gestiti da !,*8L2 si riceverebbe #na noti0ica simile alla seg#ente: I%mpossibile creare il database 'mioblog'P il database esisteI2 in0atti2 per evitare ambig#itB il <;!* non permette la creazione di d#e basi di dati aventi lo stesso nome. nel caso in c#i non sia attiva alc#na connessione la 0#nzione restit#irB semplicemente 3+L*.. La 0#nzione m,sAl@errorFG p#D essere #tilizzata per intercettare gli errori prodotti dall'esec#zione di A#alsiasi 0#nzione PHP per l'interazione con !,*8L2 A#indi anche la parte relativa alla connessione al <;!* della 0#nzione connettiFG p#D essere modi0icata in A#esto modo: Xconnessione Y m,sAl@connectFXthis9Tnomehost2Xthis9Tnome#ser2Xthis9TpasswordG or die Fm,sAl@errorFGGP L'istr#zione necessaria per la creazione di #n database chiamato ImioblogI molto semplice e si basa s#l comando *8L C?.+ . <+ +;+*.2 per c#i all'interno dell'applicazione proposta il codice da eseg#ire sarB il seg#ente: HH incl#sione del 0ile contenente la classe incl#de I0#nzioni@m,sAl.phpI HH istanza della classe Xdata Y new !,sAlClassFGP HH connessione a !,*8L Xdata9TconnettiFGP HH chiamata alla 0#nzione per la creazione del database Xdata9TA#er,FIC?.+ . <+ +;+*. mioblogIGP HH disconnessione Xdata9TdisconnettiFGP
0are A#esto sarB bene perD creare #n n#ovo parametro2 chiamato per esempio Xnomedb2 da aggi#ngere alla lista degli elementi gestiti dalla classe !,sAlClass2 per c#i dopo i dati necessari per la connessione a !,*8L si dovrB elencare anche: HH nome del database da selezionare private Xnomedb Y ImioblogIP +nche in A#esto caso2 l'argomento stato associato al modi0icatore private in modo che sia visibile soltanto all'interno della classe di appartenenza. + A#esto p#nto sarB possibile implementare la 0#nzione connettiFG in A#esto modo: HH 0#nzione per la connessione a !,*8L p#blic 0#nction connettiFG \ i0FMXthis9TattivaG \ i0FXconnessione Y m,sAl@connectFXthis9Tnomehost2Xthis9Tnome#ser2Xthis9TpasswordG or die Fm,sAl@errorFGGG \ HH selezione del database Xselezione Y m,sAl@select@dbFXthis9Tnomedb2XconnessioneG or die Fm,sAl@errorFGGP ] ]else\ ret#rn tr#eP ] ] +nche in A#esto caso viene prima e00ett#ato #n controllo per rilevare la presenza di #na connessione giB attiva2 nel caso in c#i A#esta non dovesse essere presente si procederB con la 0ase relativa alla connessione al <;!* a c#i2 posto che la connessione venga e00ettivamente aperta2 seg#irB la selezione del database il c#i nome conten#to come in0ormazione all'interno del parametro Xnomedb. *i noti come sia nell'istr#zione per la connessione a !,*8L che in A#ella per la selezione della base di dati da #tilizzare sia stata introdotta la 0#nzione m,sAl@errorFGP come anticipato2 essa permetterB di ricevere event#ali noti0iche nel caso in c#i dovessero rilevarsi dei mal0#nzionamenti in #na o entrambe le d#e proced#re. %n0ine2 bene ricordare che a parte l'#tente di root2 t#tti gli altri #tenti creati tramite il <;!* potrebbero avere dei privilegi limitati o addiritt#ra potrebbero non aver accesso ad #n determinato databaseP prima di selezionare #no speci0ico database A#indi b#ona norma accertarsi che lo #sername #tilizzato in connessione sia associato ad #n #tente che abbia i privilegi necessari per interagire con esso.
&(6
&("
HH disconnessione Xdata9TdisconnettiFGP %l codice anche disponibile in 0ormato *Al 0acendo clic s#l lin7 )is#alizza il codice sorgente A#i in basso. 99 *tr#tt#ra della tabella icommentii C?.+ . +;L. icommentii F iid@commentoi intF6G C- C6LL a#to@increment2 iid@posti varcharF5G C- C6LL de0a#lt ''2 ia#tore@commentoi varcharF1'G C- C6LL de0a#lt ''2 itesto@commentoi teLt C- C6LL2 idata@commentoi date C- C6LL de0a#lt '''''9''9'''2 iapprovatoi en#mF'''2'&'G C- C6LL de0a#lt '''2 P?%!+?a >.a Fiid@commentoiG G .C/%C.Y!,%*+! <.3+6L CH+?*. Ylatin& +6 -@%CC?.!.C Y& P 99 *tr#tt#ra della tabella ilogini C?.+ . +;L. ilogini F iid@logini intF&G C- C6LL a#to@increment2 i#sername@logini varcharF&'G C- C6LL de0a#lt ''2 ipassword@logini varcharF4'G C- C6LL de0a#lt ''2 P?%!+?a >.a Fiid@loginiG G .C/%C.Y!,%*+! <.3+6L CH+?*. Ylatin& +6 -@%CC?.!.C Y(& P 99 *tr#tt#ra della tabella iposti C?.+ . +;L. iposti F iid@posti intF5G C- C6LL a#to@increment2 ititolo@posti varcharF(55G C- C6LL de0a#lt ''2 itesto@posti teLt C- C6LL2 ia#tore@posti varcharF1'G C- C6LL de0a#lt ''2 idata@posti date C- C6LL de0a#lt '''''9''9'''2 P?%!+?a >.a Fiid@postiG G .C/%C.Y!,%*+! <.3+6L CH+?*. Ylatin& +6 -@%CC?.!.C Y& P Celle tabelle create sono stati inseriti n#merosi campi che permettono di porre in relazione i dati all'interno delle tabelle stesse e tra i campi delle varie tabelleP #n'idea piJ chiara delle relazioni create si otterrB con #n'analisi attenta della str#tt#ra delle tabelle che vedremo nella prossima lezione.
&(4
abella IloginI: id@login: campo n#merico intero della l#nghezza di massimo & ci0ra FI%C F & GIGP non p#D essere v#oto FIC- C6LLIG2 verrB incrementato a#tomaticamente ad ogni inserimento di #n n#ovo record FI+6 -@%CC?.!.C IG e verrB #tilizzato nel database come chiave primaria della tabella FIP?%!+?a >.aIGP #sername@login: campo al0an#merico della l#nghezza di massimo &' caratteri FI)+?CH+?F&'GIGP non potrB essere v#oto e verrB #tilizzato per contenere nome associato all'#tente a#torizzato ad accedere all'amministrazioneP password@login: campo al0an#merico della l#nghezza di massimo 4' caratteriP non potrB essere v#oto e conterrB la password per consentire l'accesso all'#tente dotato dello #sername ad essa associato. Campo id@login #sername@login password@login abella IpostI: id@post: campo n#merico intero della l#nghezza di massimo 5 ci0reP non p#D essere v#oto2 verrB incrementato a#tomaticamente ad ogni inserimento di #n n#ovo record e sarB #tilizzato come chiave primaria della tabellaP titolo@post: campo al0an#merico della l#nghezza di massimo (55 caratteriP non potrB essere v#oto e conterrB il titolo associato ad ogni postP testo@post: campo test#ale di l#nghezza non de0inibile FI .^ IGP non potrB essere v#oto e conterrB il testo di ogni singolo post. a#tore@post: campo al0an#merico della l#nghezza di massimo 1' caratteriP non potrB essere v#oto e conterrB i nomi degli a#tori dei postP data@post: campo destinato ad ospitare la data di p#bblicazione dei post2 per esso stato scelto #n tipo di dato #tilizzato appositamente per le date2 cio I<+ .I2 che registrerB l'in0ormazione nel 0ormato Iaaaa 9 mm 9 ggI FannoHmeseHgiornoGP non p#D essere v#oto. Campo id@post titolo@post testo@post a#tore@post data@post ipo intF5G varcharF(55G teLt varcharF1'G date C#ll Co Co Co Co Co .Ltra a#to@increment ipo intF&G varcharF&'G varcharF4'G C#ll Co Co Co .Ltra a#to@increment
&($
abella IcommentiI id@commento: campo n#merico intero della l#nghezza di massimo 6 ci0reP non p#D essere v#oto2 verrB incrementato a#tomaticamente ad ogni inserimento di #n n#ovo record e sarB #tilizzato come chiave primaria della tabellaP id@post: campo n#merico intero della l#nghezza di massimo 5 ci0reP non p#D essere v#oto e sarB #tilizzato per ospitare l'identi0icativo #nivoco del post a c#i ri0erito il commento memorizzato nel recordP a#tore@commento: campo al0an#merico della l#nghezza di massimo 1' caratteriP non potrB essere v#oto e conterrB i nomi degli a#tori dei commentiP testo@commento: campo test#ale di l#nghezza non de0inibileP non potrB essere v#oto e conterrB il testo di ogni singolo commentoP data@commento: campo destinato ad ospitare la data di inserimento del commento2 per esso stato scelto il tipo di dato <+ .P non p#D essere v#otoP approvato: si tratta di #n campo a c#i associato #n tipo di dato .C6! che consente soltanto l'inserimento di d#e valori de0initi in 0ase di creazione del campo2 nel caso dell'esempio proposto i valori possibili saranno ''' Fda associare ai commenti non approvati o non ancora approvati in 0ase di moderazione dall'amministratoreG e '&' Fda associare ai commenti approvatiG. Campo id@commento id@post a#tore@commento testo@commento data@commento approvato ipo intF6G varcharF5G varcharF1'G teLt date en#mF'''2 '&'G C#ll Co Co Co Co Co Co .Ltra a#to@increment
+nche dal semplice elenco proposto saltano immediatamente all'occhio le diverse relazioni esistenti: i post sono per esempio in relazione tra loro se si considera #n intervallo di date2 i commenti sono in relazione con i post e anche per essi vale il discorso relativo alla data di inserimento e cosE via. L'#tilizzo di A#este relazioni per lo svil#ppo dell'applicazione destinata alla gestione di #n blog sarB #n argomento 0ondamentale per il resto di A#esta trattazione.
della A#ale sono disponibili tre campi da popolare2 i dati in essa inseriti permetteranno all'#tilizzatore di disporre dei parametri necessari per l'a#tenticazione all'interno dell'area di amministrazione del blog. %n PHP l'inserimento dei dati all'interno di #na tabella possibile passando come parametro alla 0#nzione m,sAl@A#er,FG #n'istr#zione *8L basata s#l comando %C*.? %C - a c#i devono seg#ire tra parentesi tonde i nomi dei campi interessati dall'inserimento e i relativi valori da inserire in essi2 introdotti dalla chiave )+L6.* e sempre tra parentesi tonde. <i seg#ito verrB mostrata #na 0#nzione con modi0icatore p#blic che sarB inserita tra le 0#nzioni messe a disposizione dalla classe !,sAlClass e che permetterB di e00ett#are #na A#er, di %C*.? tramite il passaggio di tre argomenti: Xt: il nome della tabella in c#i e00ett#are l'inserimentoP Xv: i valori da inserireP Xr: i campi da popolare tramite i valori speci0icati dall'argomento precedente. <i seg#ito verrB proposto il codice della 0#nzione2 s#ccessivamente si passerB all'analisi dei diversi passaggi: HH0#nzione per l'inserimento dei dati in tabella p#blic 0#nction inserisciFXt2Xv2Xr Y n#llG \ i0FissetFXthis9TattivaGG \ Xistr#zione Y '%C*.? %C - '.XtP i0FXr MY n#llG \ Xistr#zione .Y ' F'.Xr.'G'P ] 0orFXi Y 'P Xi S co#ntFXvGP XiQQG \ i0Fis@stringFXvZXi[GG XvZXi[ Y 'I'.XvZXi[.'I'P ] Xv Y implodeF'2'2XvGP Xistr#zione .Y ' )+L6.* F'.Xv.'G'P XA#er, Y m,sAl@A#er,FXistr#zioneG or die Fm,sAl@errorFGGP ]else\ ret#rn 0alseP ] ] ] La 0#nzione inserisciFG 0#nziona s#lla base di #n semplice meccanismo: il parametro IXtI rappresenta il nome della tabella in c#i si desidera e00ett#are l'inserimento2 &1&
A#esta variabile verrB A#indi passata come argomento al comando %C*.? %C -P IXrI #n arra, destinato a contenere i nomi dei campi da popolare2 A#esto arra, non potrB essere v#oto2 A#indi la 0#nzione ne controllerB il conten#to prima di eseg#ire la A#er,P IXvI #n arra, che rappresenta i valori che andranno a popolare i diversi campi i c#i nomi sono anche i valori del vettore IXrIP grazie ad #n ciclo 0or Frigo &(G verranno eseg#ite tante iterazioni A#ante sono i valori compresi nell'arra, IXvI2 dato che il ling#aggio *8L prevede che i valori stringa debbano essere delimitati da apici singoli all'interno delle interrogazioni2 ad ogni iterazione del ciclo la 0#nzione Iis@stringFGI intercetterB t#tti i valori stringa presenti nell'arra, IXvI sostit#endoli con il medesimo valore delimitato da apici. l'arra, IXvI modi0icato verrB IimplosoI Frigo &"G in modo da ottenere #n'#nica seA#enza in c#i s#ddividere ogni valore presente in esso tramite #na virgola Fs#lla base della sintassi prevista dall'istr#zione %C*.? %C - nel ling#aggio *8LGP ora la variabile Xistr#zione conterrB come valore l'istr#zione *8L Frigo &4G da passare alla 0#nzione m,sAl@A#er,FG Frigo ('G che potrB A#indi essere eseg#itaP t#tti i passaggi previsti avranno l#ogo soltanto nel caso in c#i sia stata aperta #na connessione al <;!*2 diversamente la 0#nzione restit#irB immediatamente 3+L*. ignorando A#alsiasi altro passaggio. 6na volta creata l'apposita 0#nzione2 l'inserimento dei dati in tabella richiederB poche righe di codice: HH incl#sione del 0ile contenente la classe incl#de I0#nzioni@m,sAl.phpI HH istanza della classe Xdata Y new !,sAlClassFGP HH connessione a !,*8L Xdata9TconnettiFGP HH de0inizione delle variabili da passare alla 0#nzione per l'inserimento dei dati Xt Y IloginIP HH nome della tabella Xv Y arra, FIadminI2sha&FIpasswordIGGP HH valori da inserire Xr Y I#sername@login2password@loginIP HH campi da popolare HH chiamata alla 0#nzione per l'inserimento dei dati Xdata9TinserisciFXt2Xv2XrGP HH disconnessione Xdata9TdisconnettiFGP La tabella login sarB A#indi coinvolta da #n'istr#zione %C*.? %C - in c#i i campi #sername@login e password@login verranno popolati con i valori admin e password Fmodi0icabili arbitrariamenteG e saranno A#esti che dovranno essere #tilizzati per la proced#ra di a#tenticazione. *i noti come2 per ragioni di sic#rezza2 il valore relativo alla password non venga inserito nella tabella Iin chiaroI2 cio letteralmente2 ma prima criptato tramite la 0#nzione sha&FG che prod#ce #na stringa di 4' caratteri da #na A#alsiasi stringa passata come parametro2 per A#esto motivo stata associata #na l#nghezza di 4' caratteri al campo password della tabella.
&1(
&11
Cel caso del piccolo blog engine descritto in A#esta trattazione verrB #tilizzata m,sAl@0etch@ob:ectFG all'interno di #na 0#nzione personalizzata chiamata estraiFG interna alla classe !,sAlClassP HH 0#nzione per l'estrazione dei record p#blic 0#nction estraiFXris#ltatoG \ i0FissetFXthis9TattivaGG \ Xr Y m,sAl@0etch@ob:ectFXris#ltatoGP ret#rn XrP ]else\ ret#rn 0alseP ] ] +nche in A#esto caso la 0#nzione controlla innanzit#tto che esista #na connessione attiva a !,*8L2 se A#esta presente2 il ris#ltato della A#er, *.L.C passata alla 0#nzione m,sAl@A#er,FG sarB #tilizzato come argomento per m,sAl@0etch@ob:ectFG prod#cendo il valore di ritornoP se invece non dovesse essere attiva alc#na connessione2 la 0#nzione si limiterB a restit#ire 3+L*..
$'1utentica&ione
La proced#ra di a#tenticazione per il bac79end del piccolo blog engine d'esempio si articolerB in tre 0asi: inserimento in #n mod#lo dei dati richiesti per l'a#tenticazione F#sername e passwordGP con0ronto tra i dati inviati dal mod#lo e il conten#to della tabella richiamata in A#er,P esito del con0ronto: in caso positivo Fi dati inviati tramite il mod#lo corrispondono a A#elli memorizzati in tabellaG si avrB accesso all'amministrazione2 diversamente sarB eseg#ita #na proced#ra di rindirizzamento verso la homepage del sito. <i seg#ito viene presentato il codice necessario per il login2 compreso di 0orm per l'invio dei dati di a#tenticazione2 i commenti ai#teranno nella comprensione dei diversi passaggi ma verranno 0ornite s#ccessivamente #lteriori in0ormazioni s#l s#o 0#nzionamento: SNphp HH inizializzazione della sessione session@startFGP HH se la sessione di a#tenticazione HH giB impostata non sarB necessario e00ett#are il login HH e il browser verrB reindirizzato alla pagina di scritt#ra dei post i0 FissetFX@*.**%-CZ'login'[GG \ HH reindirizzamento alla homepage in caso di login mancato headerFILocation: gestisci.phpIGP ] HH controllo s#l parametro d'invio i0FissetFX@P-* Z's#bmit'[G __ FtrimFX@P-* Z's#bmit'[G YY ILoginIGG &14
\ HH controllo s#i parametri di a#tenticazione inviati i0F MissetFX@P-* Z'#sername'[G ee X@P-* Z'#sername'[YYII G \ echo I+ttenzione2 inserire la #sername.IP ] elsei0F MissetFX@P-* Z'password'[G ee X@P-* Z'password'[ YYIIG \ echo I+ttenzione2 inserire la password.IP ]else\ HH validazione dei parametri tramite 0iltro per le stringhe X#sername Y trimF0ilter@varFX@P-* Z'#sername'[2 3%L .?@*+C% %K.@* ?%C/GGP Xpassword Y trimF0ilter@varFX@P-* Z'password'[2 3%L .?@*+C% %K.@* ?%C/GGP Xpassword Y sha&FXpasswordGP HH incl#sione del 0ile della classe incl#de I0#nzioni@m,sAl.phpIP HH istanza della classe Xdata Y new !,sAlClassFGP HH chiamata alla 0#nzione di connessione Xdata9TconnettiFGP HH interrogazione della tabella Xa#th Y Xdata9TA#er,FI*.L.C id@login 3?-! login 5H.?. #sername@login Y 'X#sername' +C< password@login Y 'Xpassword'IGP HH controllo s#l ris#ltato dell'interrogazione i0Fm,sAl@n#m@rowsFXa#thGYY'G \ HH reindirizzamento alla homepage in caso di ins#ccesso headerFILocation: indeL.phpIGP ]else\ HH chiamata alla 0#nzione per l'estrazione dei dati Xres Y Xdata9TestraiFXa#thGP HH creazione del valore di sessione X@*.**%-CZ'login'[ Y Xres9T id@loginP HH disconnessione da !,*8L Xdata9TdisconnettiFGP HH reindirizzamento alla pagina di amministrazione in caso di s#ccesso headerFILocation: gestisci.phpIGP ] ] ]else\ HH 0orm per l'a#tenticazione NT Sh&T+ccesso all'amministrazione:SHh&T S0orm actionYISNphp echo X@*.?).?Z'PHP@*.L3'[P NTI methodYIP-* IT 6sername:Sbr HT Sinp#t nameYI#sernameI t,peYIteLtITSbr HT Password:Sbr HT Sinp#t nameYIpasswordI t,peYIpasswordI sizeYI('ITSbr HT Sinp#t nameYIs#bmitI t,peYIs#bmitI val#eYILoginIT SH0ormT &15
SN ] NT Commentando il 0#nzionamento del codice proposto possibile 0ornire la seg#ente descrizione: viene lanciata #na sessione che sarB aperta solo nel caso in c#i il processo di a#tenticazione dovesse avere s#ccessoP viene e00ett#ato #n controllo s#ll'invio dei dati tramite mod#lo2 se #no dei d#e campi di inp#t non dovesse essere 0orm#lato si riceverB #na noti0ica relativa all'omissioneP nel caso siano stati inviati t#tti e d#e i parametri richiesti2 A#esti verranno passati alla 0#nzione 0ilter@varFG che grazie all'argomento 3%L .?@*+C% %K.@* ?%C/ permetterB di 0iltrare gli inp#t evitando stringhe potenzialmente pericolose per l'applicazione e i dati da essa gestitiP la A#er, di selezione consiste nell'estrazione del valore relativo al campo denominato I#sername@loginI F*.L.C #sername@loginG dove i parametri di inp#t sono identici ai valori memorizzati nei campi I#sername@loginI e Ipassword@loginI F5H.?. #sername@login Y 'X#sername' +C< password@login Y 'Xpassword'GP l'operatore di con0ronto +C< consente di introd#rre #n n#ovo criterio di selezione oltre A#ello giB proposto tramite 5H.?.2 essa restit#isce ?6. soltanto nel caso in c#i entrambi i con0ronti e00ett#ati prod#cano #n ris#ltato positivo. m,sAl@n#m@rowsFG #na 0#nzione nativa di PHP che ha il compito di restit#ire il n#mero di righe coinvolte da #n ris#ltato per le istr#zioni *.L.C 2 accetta come parametro l'esito della A#er, passata a m,sAl@A#er,FG e p#D essere #tilizzata per proced#re di controlloP nel caso del codice proposto2 per esempio2 il n#mero di righe coinvolte dall'interrogazione non potrB essere #g#ale a I'I2 diversamente l'esito del con0ronto tra gli inp#t inviati e il conten#to della tabella sarebbe negativo e l'a#tenticazione non avrebbe l#ogo. *e il controllo e00ett#ato da m,sAl@n#m@rowsFG dovesse restit#ire I'I allora il login 0allirebbe e il browser dell'#tente s#birB #na rindirizzamento alla homepage del blog. Cel caso di esito positivo verrB invece richiamata la 0#nzione estraiFG che estrarrB dalla tabella il valore relativo al campo Iid@loginI e lo #tilizzerB per creare #n valore di sessione che permetterB di accedere alle altre pagine dell'amministrazione. %l s#ccesso della proced#ra di login determinerB #na rindirizzamento alla pagina gestisci.php in c#i sarB presente il mod#lo per l'inserimento dei post.
session@startFGP HH controllo s#l valore di sessione i0 FMissetFX@*.**%-CZ'login'[GG \ HH reindirizzamento alla homepage in caso di login mancato headerFILocation: indeL.phpIGP ] HH valorizzazione delle variabili con i parametri dal 0orm i0FissetFX@P-* Z's#bmit'[G__FX@P-* Z's#bmit'[YYI*criviIGG\ i0FissetFX@P-* Z'a#tore'[GG\ Xa#tore Y addslashesF0ilter@varFX@P-* Z'a#tore'[2 3%L .?@*+C% %K.@* ?%C/GGP ] i0FissetFX@P-* Z'titolo'[GG\ Xtitolo Y addslashesF0ilter@varFX@P-* Z'titolo'[2 3%L .?@*+C% %K.@* ?%C/GGP ] i0FissetFX@P-* Z'testo'[GG\ Xtesto Y addslashesF0ilter@varFX@P-* Z'testo'[2 3%L .?@*+C% %K.@* ?%C/GGP ] HH incl#sione del 0ile della classe incl#de I0#nzioni@m,sAl.phpIP HH istanza della classe Xdata Y new !,sAlClassFGP HH chiamata alla 0#nzione di connessione Xdata9TconnettiFGP Xt Y IpostIP c nome della tabella Xv Y arra, FXtitolo2Xtesto2Xa#tore2dateFIa9m9dIGGP c valori da inserire Xr Y Ititolo@post2testo@post2a#tore@post2data@postIP c campi da popolare HH chiamata alla 0#nzione per l'inserimento dei dati Xdata9TinserisciFXt2Xv2XrGP echo I+rticolo inserito con s#ccesso.IP HH disconnessione Xdata9TdisconnettiFGP ]else\ HH 0orm per l'inserimento NT Sh&T%nserimento post:SHh&T S0orm actionYISNphp echo X@*.?).?Z'PHP@*.L3'[P NTI methodYIpostIT itolo:SbrT Sinp#t nameYItitoloI t,peYIteLtITSbr HT esto:SbrT SteLtarea nameYItestoI colsYI1'I rowsYI&'ITSHteLtareaTSbr HT +#tore:SbrT Sinp#t nameYIa#toreI t,peYIteLtITSbr HT Sinp#t nameYIs#bmitI t,peYIs#bmitI val#eYI*criviIT SH0ormT &1"
SN ] NT %l meccanismo che consente la p#bblicazione dei post molto semplice: se sono stati inviati i parametri di inp#t Ftitolo2 testo e a#tore del postG viene lanciata la 0ase di inserimento dei valori nella tabella2 diversamente verrB vis#alizzato il 0orm necessario per la scritt#ra dell'articoloP i dati inviati vengono tras0ormati in variabili che contengono i valori da inserire in tabellaP oltre ai campi titolo2 testo e a#tore necessario popolare anche il campo relativo alla data di stes#ra2 A#est'#ltimo caratterizzato dal tipo di dato <+ . che prevede #n 0ormato per le date Ianno9mese9giornoI2 A#indi per creare il valore da inserire viene richiamata la 0#nzione dateFG di PHP che registra la data corrente s#lla base dei parametri passati come argomento2 nel caso speci0ico vengono passati come parametri IaI Fanno in A#attro ci0reG2 ImI Fn#mero del mese preced#to da I'I se 0ormato da #na sola ci0ra2 ad esempio I'$I per settembreG e IdI Fgiorno del mese preced#to da I'I se 0ormato da #na sola ci0ra2 ad esempio I'&I per il primo giorno del meseG. Le variabili relative ai parametri inviati vengono passate alla 0#nzione inserisciFG per la popolazione della tabella2 #na volta eseg#ita la A#er, di %C*.? viene chi#sa la connessione al <;!* in modo da liberare risorse per il sistema
&14
<i seg#ito possibile analizzare il codice della 0#nzione per la creazione delle anteprime: HH 0#nzione per la creazione di anteprime dei testi p#blic 0#nction previewFXpost2 Xo00set2 XcollegamentoG \ ret#rn Fco#ntFXanteprima Y eLplodeFI I2 XpostGG T Xo00setG N implodeFI I2 arra,@sliceFXanteprima2 '2 Xo00setGG . Xcollegamento : XpostP ] Prima di passare al codice per la vis#alizzazione dei post in homepage2 #tile proporre anche #na seconda 0#nzione2 si ricordi in0atti che ad ogni post associato #n valore relativo alla data che #tilizza il 0ormato Iaaaa9mm9ddI2 se si desidera ri0ormattare la data in modo da #tilizzare la disposizione cons#eta nei paesi mediterranei2 Igg9mm9aaaaI2 sarB possibile creare #na piccola 0#nzione che s#ddivida la data nei tre diversi componenti e li ri#nisca nell'ordine desiderato: HH 0#nzione per la 0ormattazione della data p#blic 0#nction 0ormat@dataFXdG \ Xvet Y eLplodeFI9I2 XdGP Xd0 Y XvetZ([.I9I.XvetZ&[.I9I.XvetZ'[P ret#rn Xd0P ] La 0#nzione IvedeI la data registrata nel campo Idata@postI della tabella IpostI come #na stringa che IesplodeI s#lla base del carattere di delimitazione I9I2 0atto A#esto la s#ddivide in tre elementi che verranno risistemati in ordine inverso rispetto a A#ello originale per ottenere il valore desiderato. %n alternativa possiamo #tilizzare le 0#nzioni strtotime e str0time per la 0ormattazione della data. )ediamo come: HH 0#nzione per la 0ormattazione della data p#blic 0#nction 0ormat@dataFXdG \ HH converte la data in timestamp Xvet Y strtotimeFXdGP HH converte il timestamp della variabile Xvet HH in data 0ormattata Xd0 Y str0timeF'bd9bm9ba'2 XvetGP ret#rn Xd0P ]
potranno avere in0ormazioni s#00icienti per decidere se proseg#ire o meno con la lett#ra degli articoli. <i seg#ito viene proposto il codice necessario per la vis#alizzazione dei post in homepage: ShtmlT SheadT StitleT!io;logSHtitleT SHheadT Sbod,T Sh&T!io;log: realizzato in PHP e !,*8LSHh&T SNphp HH incl#sione del 0ile di classe incl#de I0#nzioni@m,sAl.phpIP HH istanza della classe Xdata Y new !,sAlClassFGP HH chiamata alla 0#nzione di connessione Xdata9TconnettiFGP HH A#er, per l'estrazione dei record Xpost@sAl Y Xdata9TA#er,FI*.L.C R 3?-! post -?<.? ;a data@post <.*CIGP HH controllo s#l n#mero di records presenti in tabella i0Fm,sAl@n#m@rowsFXpost@sAlG T 'G\ HH estrazione dei record tramite ciclo whileFXpost@ob: Y Xdata9TestraiFXpost@sAlGG\ Xid@post Y Xpost@ob:9Tid@postP Xtitolo@post Y stripslashesFXpost@ob:9Ttitolo@postGP Xtesto@post Y stripslashesFXpost@ob:9Ttesto@postGP Xa#tore@post Y stripslashesFXpost@ob:9Ta#tore@postGP Xdata@post Y Xpost@ob:9Tdata@postP HH vis#alizzazione dei dati echo ISh([email protected](TWnIP echo I+#tore SbTI. Xa#tore@post . ISHbTWnIP echo ISbr HTWnIP echo IP#bblicato il SbTI . Xdata9T0ormat@dataFXdata@postG . ISHbTWnIP echo ISbr HTWnIP HH collegamento al testo completo del post Xleggi@t#tto Y ISbr HTSa hre0YWIpost.phpNid@postYXid@postWIT+rticolo completoSHaTWnIP HH anteprima del testo echo ISpTI.Xdata9TpreviewFXtesto@post2 5'2 Xleggi@t#ttoG.ISHpTWnIP echo IShrTWnIP ] ]else\ HH noti0ica in assenza di record in tabella echo IPer il momento non sono disponibili post.IP ] HH chi#s#ra della connessione a !,*8L Xdata9TdisconnettiFGP NT &4'
SHbod,T SHhtmlT Per ottenere l'o#tp#t desiderato2 stata passata come argomento alla 0#nzione personalizzata A#er,FG l'istr#zione *Al *.L.C R 3?-! post -?<.? ;a data@post <.*C2 che ItradottaI in ling#aggio #mano signi0ica: Iseleziona t#tti i record presenti nella tabella post e ordinali s#lla base dei valori conten#ti nel campo data@post disposti in ordine discendente2 dall'#ltimo al primo per data di scritt#raI. <.*C in0atti #na delle d#e cla#sole che possibile associare al comando -?<.? ;a di *8L e consente di vis#alizzare dei valori partendo dal maggiore Fo nel caso speci0ico2 dal piJ recenteG 0ino ad estrarre come #ltimo record A#ello corrispondente al valore minoreP l'ordinamento contrario2 cio a partire dal valore in0eriore2 ottenibile sostit#endo <.*C con +*C. La stessa A#er, avrebbe pot#to coinvolgere soltanto #no speci0ico n#mero di record2 ad esempio soltanto A#elli corrispondenti agli #ltimi dieci post p#bblicati2 #tilizzando #na particolare cla#sola chiamata L%!% 2 in A#esto caso l'istr#zione sarebbe stata la seg#ente: *.L.C R 3?-! post -?<.? ;a data@post <.*C L%!% &'P ma sarebbe stato anche possibile estrarre soltanto i record validi per #n determinato intervallo di valori2 ad esempio2 l'istr#zione *.L.C R 3?-! post -?<.? ;a data@post <.*C L%!% 52&'P avrebbe consentito la vis#alizzazione dei record che disposti in senso cronologico crescente avessero occ#pato le posizioni ricompresse tra la A#inta e la decima. *i noti inoltre2 come il ris#ltato dell'applicazione della 0#nzione A#er,FG s#ll'istr#zione *8L sia stato si passato alla 0#nzione estraiFG A#ale condizione di #n ciclo while2 ciD stato necessario perchh i record conten#ti all'interno della tabella possono essere piJ di #no2 A#indi ogn#no di essi dovrB essere vis#alizzato tramite #na diversa iterazione del ciclo 0ino a A#ando non venga piJ soddis0atta la condizione prevista per esso e t#tti i ris#ltati non siano stati mostrati a video.
Xid@post Y X@/. Z'id@post'[P ] NT ShtmlT SheadT StitleT!io;logSHtitleT SHheadT Sbod,T SNphp HH incl#sione del 0ile di classe incl#de I0#nzioni@m,sAl.phpIP HH istanza della classe Xdata Y new !,sAlClassFGP HH chiamata alla 0#nzione di connessione Xdata9TconnettiFGP HH A#er, per l'estrazione dei record Xpost@sAl Y Xdata9TA#er,FI*.L.C R 3?-! post 5H.?. id@post Y Xid@postIGP HH controllo s#lla presenza in tabella del record corrispondente dell'id richiesto i0Fm,sAl@n#m@rowsFXpost@sAlG T 'G\ HH estrazione dei record Xpost@ob: Y Xdata9TestraiFXpost@sAlGP Xid@post Y Xpost@ob:9Tid@postP Xtitolo@post Y stripslashesFXpost@ob:9Ttitolo@postGP Xtesto@post Y stripslashesFXpost@ob:9Ttesto@postGP Xa#tore@post Y stripslashesFXpost@ob:9Ta#tore@postGP Xdata@post Y Xpost@ob:9Tdata@postP HH vis#alizzazione dei dati echo ISh&[email protected]&TWnIP echo I+#tore SbTI. Xa#tore@post . ISHbTWnIP echo ISbr HTWnIP echo IP#bblicato il SbTI . Xdata9T0ormat@dataFXdata@postG . ISHbTWnIP echo ISbr HTWnIP echo [email protected] echo I :: Sa hre0YWIcommenti.phpNid@postYXid@postWIT%nserisci #n commentoSHaTWnIP echo ISbr HTWnIP ]else\ HH noti0ica in assenza di record echo ICon esiste alc#n post per A#esto id.IP ] HH chi#s#ra della connessione a !,*8L Xdata9TdisconnettiFGP NT SHbod,T SHhtmlT La pagina controlla che il parametro di inp#t inviato in A#er,string sia valido2 esso in0atti deve essere impostato Fcio deve essere de0inito e A#indi IesistereIG e deve essere n#merico2 altrimenti non verrB riten#to valido e il browser s#birB #n rindirizzamento alla homepageP nat#ralmente PHP mette a disposizione str#menti piJ ra00inati per la validazione delle A#er,string e dei loro conten#ti2 &4(
il discorso perD allontanerebbe dal tema centrale di A#esta trattazione e nella sezione PHP di H !L.it sono giB presenti n#merosi articoli e g#ide in materia. %l parametro inviato per A#er,string verrB associato come valore ad #na variabile che nh conserverB l'in0ormazione e verrB #tilizzata all'interno dell'istr#zione necessaria per l'interrogazione *Al *.L.C R 3?-! post 5H.?. id@post Y Xid@postP Xid@post rappresenterB A#alsiasi valore n#merico presente in tabella2 se per esempio alla variabile dovesse corrispondere il valore I&'I2 allora l'istr#zione che verrB lanciata al <;!* sarB la seg#ente *.L.C R 3?-! post 5H.?. id@post Y &'. La 0#nzione m,sAl@n#m@rowFG permetterB di controllare che nella tabella sia presente #n record con identi0icativo #nivoco di valore pari a A#ello della variabile Xid@post e2 solo in caso di esito positivo2 verrB richiamata la 0#nzione estraiFG per la vis#alizzazione dei valori conten#ti nel record selezionato. %n A#esto caso il ris#ltato di estraiFG non dovrB essere #tilizzato come condizione di #n ciclo while in A#anto l'identi0icativo 2 app#nto2 #nivoco2 A#indi ad esso p#D corrispondere soltanto #n #nico record.
i0FissetFX@P-* Z's#bmit'[GG\ i0FMissetFX@P-* Z'a#tore'[G ee MissetFX@P-* Z'commento'[G ee MissetFX@P-* Z'post@id'[G ee M is@n#mericFX@P-* Z'post@id'[GG \ echo I #tti i campi sono obbligatoriIP ]else\ Xa#tore Y htmlentitiesFaddslashesFX@P-* Z'a#tore'[GGP Xpost@id Y X@P-* Z'post@id'[P Xcommento Y htmlentitiesFaddslashesFX@P-* Z'commento'[GGP Xt Y IcommentiIP c nome della tabella Xv Y arra, FXpost@id2Xa#tore2Xcommento2dateFIa9m9dIGGP c valori da inserire Xr Y Iid@post2a#tore@commento2testo@commento2data@commentoIP c campi da popolare HH chiamata alla 0#nzione per l'inserimento dei dati Xdata9TinserisciFXt2Xv2XrGP headerFILocation: post.phpNid@postYXpost@idIGP ] ]else\ HH controllo s#ll'id del post inviato per A#er,string i0F issetFX@/. Z'id@post'[G __ is@n#mericFX@/. Z'id@post'[G G\ Xid@post Y X@/. Z'id@post'[P XsAl@commenti Y Xdata9TA#er,FI*.L.C id@post 3?-! post 5H.?. id@postY'Xid@post'IGP i0Fm,sAl@n#m@rowsFXsAl@commentiG T 'G\ HH viene vis#alizzato il 0orm solo nel caso in c#i l'#nico dato inviato sia l'id del post NT S0orm actionYISNphp echo X@*.?).?Z'PHP@*.L3'[P NTI methodYIpostIT +#tore:Sbr HT Sinp#t nameYIa#toreI t,peYIteLtITSbr HT Commento:Sbr HT SteLtarea nameYIcommentoI colsYI1'I rowsYI&'ITSHteLtareaTSbr HT Sinp#t nameYIpost@idI t,peYIhiddenI val#eYISNphp echo Xid@postP NTIT Sinp#t nameYIs#bmitI t,peYIs#bmitI val#eYI%nviaIT SH0ormT SNphp HH noti0iche in caso di A#er,string v#ota o non valida ]else\ echo ICon possibile accedere alla pagina da A#esto percorso.IP ] ]else\ echo ICommenti non consentiti2 articolo inesistente.IP ] ] HH disconnessione Xdata9TdisconnettiFGP NT SHbod,T SHhtmlT O possibile postare #n commento a partire dalla homepage o da #n singolo articolo2 0acendo clic s#l &44
collegamento chiamato %nserisci #n commentoP il clic7 s#l lin7 prod#rrB #na A#er,string che conserva al s#o interno l'in0ormazione relativa all'identi0icativo #nivoco dell'articolo che si desidera commentare2 A#esto dato 0ondamentale perchh permette di popolare il campo post@id della tabella commenti per mettere in relazione post e commenti. L'inserimento dei dati in tabella avviene grazie all'invio di d#e parametri Fa#tore e commentoG da valorizzare tramite #n mod#lo che conserva come dato nascosto FhiddenG anche l'identi0icativo #nivoco del post di ri0erimentoP #na volta compilato il mod#lo2 l'e00ettivo invio dei parametri verrB controllato e2 se l'esito dovesse essere positivo2 A#esti verranno 0iltrati e #tilizzati per de0inire delle variabili che andranno a popolare i campi della tabella commenti creando #n n#ovo record grazie alla 0#nzione inserisciFGP il campo denominato approvato relativo al n#ovo record avrB associato il valore prede0inito I'I e il commento non sarB visibile prima che A#esto non sia modi0icato in I&I. *i noti come il valore relativo al campo .C6! approvato sia posto tra singoli apici2 apparentemente in0atti sembrerebbe associato ad #n dato n#merico e invece si tratta di #n valore che il <;!* vede come #n carattere2 A#indi2 rispettando la sintassi *8L prevista per !,*8L esso non dovrB essere inserito in istr#zione senza apici2 come avverrebbe per i valori n#merici2 ma delimitato da essi.
Xcommento@sAlYXdata9TA#er,FI*.L.C id@commento2testo@commento2a#tore@commento2data@commento 3?-! commenti 5H.?. approvatoY''' -?<.? ;a data@commento <.*CIGP echo ISh&T.lenco dei commenti da approvareSHh&TWnIP HH controllo s#l n#mero di record presenti in tabella i0Fm,sAl@n#m@rowsFXcommento@sAlG T 'G\ echo IS#lTWnIP HH estrazione dei record tramite ciclo whileFXcommento@ob: Y Xdata9TestraiFXcommento@sAlGG\ Xid@commento Y Xcommento@ob:9Tid@commentoP Xtesto@commento Y stripslashesFXcommento@ob:9Ttesto@commentoGP Xa#tore@commento Y stripslashesFXcommento@ob:9Ta#tore@commentoGP Xdata@commento Y Xcommento@ob:9Tdata@commentoP HH vis#alizzazione dei dati echo ISliTWnIP echo I+#tore: I . Xa#tore@commento . I *critto il I. Xdata9T0ormat@dataFXdata@commentoG . IWnIP echo ISbr HTWnIP echo ICommento: I . Xtesto@commentoP echo ISbr HTWnIP echo I :: Sa hre0YWImoderazione.phpNid@commentoYXid@commentoWITapprovaSHaTWnIP echo ISHliTWnIP ] echo ISH#lTWnIP ]else\ HH noti0ica in assenza di record che soddis0ino le caratteristiche richieste echo IPer il momento non sono disponibili commenti da approvare.IP ] HH chi#s#ra della connessione a !,*8L Xdata9TdisconnettiFGP NT +d ogni commento elencato corrisponderB #n lin7 chiamato approva e destinato a prod#rre #na A#er,string che trasmetta alla pagina moderazione.php l'identi0icativo #nivoco del commento selezionato: SNphp HH inizializzazione della sessione session@startFGP HH controllo s#l valore di sessione i0 FMissetFX@*.**%-CZ'login'[GG \ HH reindirizzamento alla homepage in caso di login mancato headerFILocation: indeL.phpIGP ] HH controllo s#ll'id del commento inviato per A#er,string i0 FissetFX@/. Z'id@commento'[G __ is@n#mericFX@/. Z'id@commento'[GG &46
\ Xid@commento Y X@/. Z'id@commento'[P NT S0orm actionYISNphp echo X@*.?).?Z'PHP@*.L3'[P NTI methodYIP-* IT Sh&T+ttenzioneMSHh&T *i sta per approvare il commento selezionato.Sbr HT Premere il p#lsante per eseg#ire l'operazione richiesta.Sbr HT SbrT Sinp#t nameYIcommento@idI t,peYIhiddenI val#eYISNphp echo Xid@commentoP NTIT Sinp#t nameYIs#bmitI t,peYIs#bmitI val#eYI!oderaIT SH0ormT SNphp ] HH controllo s#ll'id del commento inviato per 0orm elsei0FissetFX@P-* Z'commento@id'[G __ is@n#mericFX@P-* Z'commento@id'[GG \ Xcommento@id Y X@P-* Z'commento@id'[P HH incl#sione del 0ile di classe incl#de I0#nzioni@m,sAl.phpIP HH istanza della classe Xdata Y new !,sAlClassFGP HH chiamata alla 0#nzione di connessione Xdata9TconnettiFGP Xdata9TA#er,FI6P<+ . commenti *. approvatoY'&' 5H.?. id@commento Y Xcommento@idIGP HH reindirizzamento alla pagina di gestione dei commenti headerFILocation: [email protected] HH chi#s#ra della connessione a !,*8L Xdata9TdisconnettiFGP ] NT L'identi0icativo #nivoco inviato alla pagina per la moderazione indispensabile per identi0icare il record da aggiornare all'interno della A#er, per la modi0icaP come anticipato2 A#esta si basa s#l comando *8L 6P<+ . a c#i deve seg#ire il nome della tabella che contiene il record e il nome del campo da aggiornare con il n#ovo valore introdotti dalla chiave *. F6P<+ . commenti *. approvato Y '&'GP per sapere a carico di A#ale record dovrB essere e00ett#ato l'#pdate2 l'istr#zione dovrB prevedere anche la cla#sola 5H.?. che speci0icherB il valore dell'identi0icativo #nivoco corrispondente al record da modi0icare F5H.?. id@commento Y Xcommento@idG. %l codice presente nel 0ile per la moderazione potrB essere modi0icato 0acilmente anche per e00ett#are l'eliminazione di #n commento2 in0atti l'#nica operazione da 0are sarB A#ella di sostit#ire la A#er, basata s#l comando 6P<+ . con #n'altra basata s#l comando <.L. .P in A#esto caso in0atti si dovrB #tilizzare l'istr#zione: Xdata9TA#er,FI<.L. . 3?-! commenti 5H.?. id@commento Y Xcommento@idIGP %n #na A#er, per la cancellazione di #n record s#00iciente passare in istr#zione l'identi0icativo di #na riga introdotto dalla cla#sola 5H.?.2 in A#esto modo il <;!* potrB identi0icare con precisione il record da cancellare senza coinvolgere altri dati in A#esto processo potenzialmente pericoloso. &4"
approvato Y '&'P n@commenti #n IaliasI2 cio #n campo in realtB non presente all'interno di #na tabella ma che viene creato temporaneamente per la generazione di #n ris#ltato desideratoP in A#esto caso l'alias conterrB il ris#ltato relativo al conteggio dei record coinvolti dall'istr#zione. + A#esto p#nto2 il discorso relativo alla gestione dei commenti p#D ritenersi concl#so2 manca soltanto la parte che concerne la vis#alizzazione dei commenti per ogni articolo il c#i codice dovrB essere inserito nella pagina destinata a mostrare il testo integrale dei singoli postP ciD sarB possibile attraverso #na semplice A#er, di selezione: HH estrazione dei commenti Xpost@commentiYXdata9TA#er,FI*.L.C a#tore@commento2testo@commento2data@commento 3?-! commenti 5H.?. id@post Y Xid@post +C< approvatoY'&' -?<.? ;a data@commento <.*CIGP i0Fm,sAl@n#m@rowsFXpost@commentiG T 'G\ echo IS#lTWnIP whileFXcommenti@ob: Y Xdata9TestraiFXpost@commentiGG \ Xa#tore@commento Y stripslashesFXcommenti@ob:9Ta#tore@commentoGP Xtesto@commento Y stripslashesFXcommenti@ob:9Ttesto@commentoGP Xdata@commento Y stripslashesFXcommenti@ob:9Tdata@commentoGP echo ISliTWn IP echo I+#tore: I . Xa#tore@commento . I *critto il I. Xdata9T0ormat@dataFXdata@commentoG . IWnIP echo ISbr HTWnIP echo ICommento: I . Xtesto@commentoP echo ISHliTWn IP ] echo ISH#lTWnIP ]else\ echo ICess#n commento per A#esto postIP ] %l listato esposto eseg#e #n'interrogazione s#lla base dell'identi0icativo #nivoco relativo al post vis#alizzato: F*.L.C j 3?-! commenti 5H.?. id@post Y Xid@postG2 essa prevede che siano mostrati soltanto i commenti approvati F+C< approvato Y '&'G relativi al post corrente e che l'ordine per la loro vis#alizzazione sia impostato a partire dal commento piJ recente F-?<.? ;a data@commento <.*CG.
&4$
*i immagini per esempio di voler ricercare il termine IdataI all'interno del conten#to dei post: la chiave verrB passata all'applicazione per la ricerca sotto 0orma di parametro di inp#t inviato tramite 0ormP l'applicazione e00ett#erB #n controllo s#lla validitB del parametro di inp#t e lo #tilizzerB come valore da associare ad #na variabile FX7e, nell'esempioGP a A#esto p#nto verrB e00ett#ata #na A#er, *.L.C s#lla tabella dei post F*.L.C R 3?-! postGP la A#er, verrB e00ett#ata con0rontando la parola ricercata con il conten#to dei record relativi ai titoli e al testo dei post F5H.?. Ftitolo@post L%>. 'bI . X7e, . Ib'G -? Ftesto@post L%>. 'bI . X7e, . Ib'G P sarB possibile ottenere #n ris#ltato valido non soltanto se la chiave sarB rilevata all'interno dei titoli e dei testi ma anche se verrB trovata in #no solo di A#esti termini di con0ronto2 ciD possibile grazie all'#tilizzo dell'operatore -? al posto di +C<2 il primo in0atti2 a di00erenza del secondo2 restit#isce ?6. anche se soltanto #no degli argomenti di #n con0ronto ris#lta veroP i ris#ltati della A#er, verranno ordinati in senso decrescente s#lla base dei valori conten#ti nel campo data@post F-?<.? ;a data@postG. <i seg#ito viene proposto il codice necessario per il motore di ricerca: ShtmlT SheadT StitleT!io;logSHtitleT SHheadT Sbod,T Sh&T!otore di ricercaSHh&T SNphp HH incl#sione del 0ile di classe incl#de I0#nzioni@m,sAl.phpIP HH istanza della classe Xdata Y new !,sAlClassFGP HH chiamata alla 0#nzione di connessione Xdata9TconnettiFGP NT S0orm actionYISNphp echo X@*.?).?Z'PHP@*.L3'[P NTI methodYIP-* IT Sinp#t t,peYIteLtI nameYI7e,I val#eYII HT Sinp#t t,peYIs#bmitI val#eYIcercaI classYIs#bmitI HT SH0ormT SNphp i0FissetFX@P-* Z'7e,'[G__FX@P-* Z'7e,'[MYIIG__Fpreg@matchFIHfZa9z'9$[QXHiI2 X@P-* Z'7e,'[GGG \ X7e, Y X@P-* Z'7e,'[P XsAl@cerca Y Xdata9TA#er,FI*.L.C R 3?-! post 5H.?. Ftitolo@post L%>. 'bI . X7e, . Ib'G -? Ftesto@post L%>. 'bI . X7e, . Ib'G -?<.? ;a data@postIGP Xtrovati Y m,sAl@n#m@rowsFXsAl@cercaGP i0FXtrovati T 'G \ echo ISpT rovate Xtrovati voci per il termine SbTI.stripslashesFX7e,G.ISHbTSHpTWnIP whileFXcerca@ob: Y Xdata9TestraiFXsAl@cercaGG &5'
\ Xid@post Y Xcerca@ob:9Tid@postP Xtitolo@post Y stripslashesFXcerca@ob:9Ttitolo@postGP Xtesto@post Y stripslashesFXcerca@ob:9Ttesto@postGP Xa#tore@post Y stripslashesFXcerca@ob:9Ta#tore@postGP Xdata@post Y Xcerca@ob:9Tdata@postP HH vis#alizzazione dei dati echo ISh([email protected](TWnIP echo I+#tore SbTI. Xa#tore@post . ISHbTWnIP echo ISbr HTWnIP echo IP#bblicato il SbTI . Xdata9T0ormat@dataFXdata@postG . ISHbTWnIP echo ISbr HTWnIP HH lin7 al testo completo del post Xleggi@t#tto Y ISbr HTSa hre0YWIpost.phpNid@postYXid@postWIT+rticolo completoSHaTWnIP HH anteprima del testo echo ISpTI.Xdata9TpreviewFXtesto@post2 5'2 Xleggi@t#ttoG.ISHpTWnIP ] ]else\ HH noti0ica in caso di mancanza di ris#ltati echo I+l momento non sono stati p#bblicati post che contengano A#esto termine.IP ] ] HH disconnessione Xdata9TdisconnettiFGP NT L%>. #n operatore di con0ronto che permette di e00ett#are #na comparazione tra campi simili anche se non #g#aliP % d#e simboli percent#ali FbG2 vengono #tilizzati dal <;!* per rilevare se prima e dopo il termine ricercato vi siano altre paroleP se invece di L%>. si 0osse #tilizzato l'operatore di identitB Fad esempio: 5H.?. Ititolo@post Y' . X7e, . ' -? testo@post Y' . X7e, . 'G l'istr#zione avrebbe cercato soltanto i titoli o i testi contenenti escl#sivamente la chiave inviata in inp#t. *i noti come la chiave di ricerca2 prima di partecipare alla A#er,2 sia stata validata tramite #n'espressione regolare Fpreg@matchFIHfZa9z'9$[QXHiI2 X@P-* Z'7e,'[IGG2 A#esto perchh per ragioni di sic#rezza nella parola ricercata non devono essere presenti caratteri speciali.
&5&