Professional Documents
Culture Documents
1 La scelta di PHP
itando testualmente la avremo gli strumenti di base 1 I listati
C prefazione del manuale uf-
ficiale di PHP.net: “L'obiet-
tivo principale del linguaggio
per migliorare i nostri siti e per
affrontare una delle più impor-
tanti funzionalità di PHP, ossia
completi
sono sul CD
PHP è di permettere agli svi- l'integrazione con i database e
luppatori Web di scrivere velo- in particolare con MySQL.
cemente pagine Web dinami-
che, ma con PHP si possono fa- La storia
re molte altre cose”. del linguaggio PHP
È in questo spirito che PC PHP è un acronimo ricorsivo
Open introduce nelle sue pagi- (tipico dell'ambiente open
ne questo minicorso di PHP, source) che significa PHP: Hy-
potente linguaggio di scripting pertext Preprocessor. Che cosa
open source, pienamente inte- sia un ipertesto è chiaro, men-
grabile con HTML (da cui la tre può lasciare perplessi il si-
propedeuticità del corso Web- gnificato di Preprocessor: PHP,
master, fornito sul CD Guida n. come ASP, è un linguaggio ser-
2 unito a questo numero, utile ver-side, ossia il codice PHP è
anche se non necessaria) e in- prima elaborato dal server e
dirizzato prevalentemente allo solo dopo indirizzato al brow-
sviluppo dei siti Internet dina- ser che ha chiamato la pagina. La pagina phpinfo.php è la prima pagina di questo corso realizzata in PHP
mici. PHP viene utilizzato an- In tal senso PHP elabora la pa-
che per creare scripting di ri- gina “prima” della sua visualiz-
ghe comando e applicazioni zazione. creare immagini, file PDF, fil- su macchine client con sistemi
client-side GUI (Graphical User È una caratteristica total- mati Flash, generare file basati operativi Windows, Linux, BSD
Interface) utilizzando le esten- mente diversa rispetto a lin- su XML, utilizzare i protocolli o Mac e interfacciabile con tut-
sioni PHP-GTK. Tralasciando guaggi come Javascript che in- di posta POP3 e IMAP (ne ve- ti i più popolari Web server.
queste due applicazioni spe- vece sono client-side, ossia in- dremo un'applicazione nella
cialistiche, vedremo come PHP teramente interpretati dai seconda parte del corso), com- Utilizzare PHP off line
offra strumenti professionali browser. Vedremo in seguito primere file in gzip e bz2, gesti- e scrivere i primi listati
molto evoluti per la gestione come questa caratteristica ser- re sessioni, utilizzare funzioni e I listati in PHP possono esse-
Web, pur mantenendo una ver-side consenta l'implemen- classi, fare uso della program- re creati utilizzando un qualsia-
struttura semplice, adatta an- tazione di strutture e funziona- mazione orientata agli oggetti e si editor di testo e salvando le
che a chi si avvicina per la pri- lità assolutamente inedite per naturalmente interagire con pagine con estensione .php.
ma volta a linguaggi di pro- chi è abituato a ragionare in tutti i database più diffusi. Per Proviamo a scrivere il nostro
grammazione di questo tipo. termini di HTML puro. alcune di queste funzioni biso- primo semplice listato (la parte
Alla fine di questo minicorso PHP consente, inoltre, di gna installare estensioni forni- PHP è in grassetto. Più avanti
te con il file binario di PHP e ne approfondiremo il significa-
quindi si dovrà verificare pres- to), salviamolo col nome ph-
IL CALENDARIO DELLE LEZIONI so il proprio Web provider l'in- pinfo.php (listato1) e poi visua-
GET e POST stallazione delle specifiche li- lizziamolo col nostro browser:
Lezione 1: - Esempi brerie (ad esempio quelle gra-
- La scelta di PHP fiche). LISTATO 1 (phpinfo.php)
- PHP con un server off line PHP ha ormai quasi 10 anni <html>
- La prima pagina PHP: Le prossime puntate di storia alle spalle (è stato <head>
inseriamo PHP in HTML Lezione 2: Approfondiamo creato nel 1994 da Rasmus Ler- <title>Prova PHP</title>
- Funzioni base e variabili PHP dorf e la prima distribuzione ri- </head>
- I costrutti di controllo: Lezione 3: PHP e i database sale al 1995; sito di riferimento: <body>
if else, while, do until, www.php.net), sposa appieno <?php
foreach Lezione 4: PHP e MySql la filosofia open source ed è di- phpinfo();
- I form: Lezione 5: Gestire un sito stribuito con licenza GPL. È un ?>
passaggio di dati coi metodi dinamico con PHP e MySql linguaggio multipiattaforma, </body>
utilizzabile indifferentemente </html>
1a lezione
Sul vostro browser vedrete o stabile di PHP per il proprio si- ScriptAlias /php/ "c:/php/" IIS, PWS e Xitami
una pagina totalmente vuota stema direttamente dal sito uf- AddType application/x-httpd-php .php Con IIS, PWS e Xitami la vita è
oppure il listato esattamente ficiale: www.php.net. Action application/x-httpd-php più semplice rispetto ad Apa-
come è scritto qui sopra. Cos'è Al momento in cui scrivia- "/php/php.exe" che, sempre che ci si acconten-
successo? Abbiamo affermato mo, la release stabile è una ti dell'installazione minima (ge-
che PHP è un linguaggio ser- 4.3.x, in attesa del sospirato ri- sostituendo a c:\php la car- neralmente sufficiente per i no-
ver-side, quindi per visualizza- lascio della release 5. Trala- tella di installazione. PHP viene stri scopi).
re le pagine create abbiamo bi- sciamo l'installazione di PHP installato nella versione CGI: In questo caso si deve solo
sogno di tre strumenti: un ser- su Linux, in quanto è un'opera- fate ripartire il server Apache e eseguire l'installer PHP: duran-
ver Web, il supporto PHP (il zione generalmente eseguita in poi verificate se la pagina ph- te la procedura di installazione
parser, gli elementi di una frase automatico scegliendo gli op- pinfo.php viene visualizzata ci verrà chiesto se è presente
o di un’istruzione) attivato da portuni pacchetti della propria nella maniera corretta. un server da configurare con
parte del server scelto e un distribuzione, e dedichiamoci Questo tipo di installazione PHP. Scegliete IIS o Xitami e at-
browser. all'ambiente Windows. Nell'a- è giudicato non sicuro e meno tendete la conclusione dell'in-
Nel nostro esempio ci siamo rea download di www.php.net performante dell'installazione stall shield: da adesso saremo
serviti solamente del browser si trovano due file utilizzabili di PHP come modulo, però dal in grado di verificare off line le
che, da solo, non è in grado di con sistemi Windows: momento che ce ne serviamo nostre pagine PHP. Per verifica-
interpretare la pagina PHP e la • un file installer (come: php- solo per scopi didattici (esclu- re il funzionamento, fate partire
fa vedere come fosse un nor- 4.3.7-installer.exe). Questo file sivamente off line) va comun- il server, provate a inserire nel-
male documento HTML (quin- ha dimensioni minime (circa que bene per i nostri scopi. la cartella scelta come root dei
di, in questo caso, apparente- 1 MB), è direttamente esegui- Non è possibile, però, installa- documenti il file phpinfo.php e
mente vuoto) oppure come un bile nel sistema e configura re alcuna estensione. richiamatelo col browser: do-
file testo. Nel primo caso la pa- automaticamente i server IIS Il secondo metodo richiede vete ottenere l'immagine 1 della
gina sembra vuota, ma se an- e Xitami, consentendo l'in- il file zip binario. Per prima co- pagina a lato.
diamo a vedere il codice sor- stallazione come versione sa si deve scompattare il file in L'installazione delle esten-
gente (ogni browser consente CGI per il server Apache. L'in- una cartella tipo c:\php, quindi sioni implica l'utilizzo del file
di farlo selezionando l'apposita staller non comprende le copiare il file php.ini-dist nella zip binario e qualche passo
voce presente nei menu) ve- estensioni di PHP. %SYSTEMROOT% (per Win- “manuale” aggiuntivo. Non la
dremo il listato 1. Per vedere in- • un file zippato contenente il dows 2000 è C:\WINNT) modifi- trattiamo in questa sede, ma è
vece la pagina PHP interpretata codice binario (come: php- candone il nome in php.ini. Al- comunque presente il file in-
nella maniera esatta, avremmo 4.3.7-Win32.zip). Questo file tra operazione da compiere è stall.txt che vi assiste passo pas-
dovuto per prima cosa caricare ha dimensioni ben più consi- copiare il file php4ts.dll nella so.
la pagina phpinfo.php su un ser- stenti (circa 7 MB), ma con- cartella c:\php\sapi. Ultimi
ver Web (abilitato per la tradu- sente l'installazione (manua- sforzi: editare il file httpd.conf Estensioni
zione delle pagine PHP) e poi le) di tutti i moduli. del server Apache (Start > Pro- Per utilizzare le estensioni
richiamare la pagina col brow- grammi > Apache > Configure > si deve effettuare l'installazione
ser (vedi disegno a fondo pagi- Il server Apache Edit the httpd.conf configuration del parser PHP tramite il file zip
na). Avremmo ottenuto quanto Come ASP richiamava il ser- file) e, dopo essersi posiziona- binario. Andrà poi modificato il
visibile nell'immagine 1: la no- ver IIS, così PHP richiama il ti nella sezione LoadModule, ag- file php.ini (dalla %SYSTEM-
stra prima pagina ci restituisce server Apache. Tuttavia, non giungere le seguenti righe (per ROOT%) inserendo l'indicazio-
tutte le caratteristiche della esiste al momento una proce- Apache 2.0.x): ne C:\php\extensions dopo l'u-
versione PHP installata sul ser- dura automatica per configura- guale nella riga che inizia con
ver Web. re il server Apache, sia esso LoadModule php4_module extension_dir =. Fatto questo,
Per la maggior parte delle 1.3.x o 2.0.x (supporto piena- c:/php/sapi/php4apache2.dll [o sempre nel file php.ini, cercare
persone è certamente impro- mente abilitato solo con una php4apache.dll per Apache 1.3.x] la sezione Windows extensions
ponibile pensare di poter im- versione di PHP oltre la 4.3.1). AddType application/x-httpd-php .php e togliere il punto e virgola da-
parare a programmare in PHP Si può procedere in due mo- vanti alle estensioni da abilita-
restando connessi a Internet, di, configurando PHP in versio- Facciamo le necessarie veri- re (ad esempio, per utilizzare le
vuoi a causa dei costi, vuoi per ne CGI (installazione più sem- fiche, dopodiché siamo pronti funzioni PDF bisogna abilitare
la scomodità di dover ogni vol- plice) o come modulo (installa- per iniziare. l'estensione php_pdf.dll).
ta caricare le proprie pagine zione consigliata per motivi di
via FTP (o con upload dedicati) sicurezza).
1 Caricamento pagina 3 Il server, ricevuta la richiesta, chiede
per poi richiamarle tramite Nel primo caso utilizziamo il
sul server (via FTP) al parser di interpretare la pagina sorgente
browser (vedi disegno A ). file Installer. Eseguiamolo (ri-
Risulta quindi necessario in- cordandoci la cartella dove INTERNET
stallare un server sul proprio PHP verrà installato: C:\PHP va PAGINA
4 Il parser
SORGENTE
PC, col supporto alle pagine benissimo, ma potete cambiar- PHP PHP
PHP per le operazioni di par- la a piacere) e arriviamo al ter- Server Parser restituisce
sing. L'installazione di un ser- mine dell'installazione (anche WEB PHP
al server
ver sul proprio PC è già stata scegliendo l'opzione di confi- la pagina
descritta nella 7a lezione del gurazione automatica di Apa- interpretata
2 Richiesta pagina
corso Webmaster e la si dà per che, il software vi risponderà
da parte del browser
acquisita (l'installazione del che questa procedura non è
server Web va fatta prima di ancora applicabile). Ora dove- 5 Il server
PHP). Vediamo adesso come te editare il file httpd.conf del restituisce al
installare il parser, con indica- server Apache (Start > Pro- Schema per la BROWSER browser la pagina
zioni riguardanti tre server: grammi > Apache > Configure > UTENTE
interpretata dal
Apache, Xitami e IIS di Micro- Edit the httpd.conf configuration visualizzazione parser (NON viene
soft. file) e, dopo esservi posiziona- restituita la pagina
La prima regola fondamen- ti nella sezione ScriptAlias, ag- di pagine PHP sorgente in PHP)
tale è scaricare l'ultima release giungete le seguenti righe:
1a lezione
P
booleano (boolean), $1prova = 1;
re PHP e scoprirne le ca- disposizione: ossia assume solo valori ve- // il nome della variabile non
ratteristiche, abbiamo bi- ro (true) o falso (false). Il nu- è valido (numero dopo $)
sogno di spendere ancora qual- $prova1 = 12; mero 0 o una stringa vuota cor- Ridichiarando le variabili, o
che minuto per introdurre la // $prova1 è un tipo di dato intero rispondono al valore booleno concatenandole, PHP sceglie
gestione delle variabili. (integer), false; un numero diverso da 0 o sempre automaticamente il ti-
Diversamente da ASP, con in questo esempio è un inte- una stringa non vuota corri- po di dato da gestire. Se voles-
PHP non serve dichiarare espli- ro a base decimale, ma avrem- spondono al valore booleano simo sapere, ad esempio per
citamente le variabili indican- mo potuto fare una dichiara- true. motivi di debug, quale sia il ti-
do nome e tipo, ma, più sem- zione con le notazioni esadeci- po di dato di una certa variabi-
plicemente, basta assegnare al- male o ottale. In caso di supe- $prova4 = “pippo”; le, si può usare la funzione
la variabile il suo valore: sarà il ramento del limite massimo // $prova4 è un tipo di dato gettype:
parser ad attribuire alla varia- previsto per un intero, PHP as- stringa (string).
bile il giusto “tipo” (dichiara- segna automaticamente alla va- La stringa può essere defini- <?php
zione implicita). Tutte le varia- riabile il tipo float. ta utilizzando le virgolette sin- $prova = 1,2;
bili vanno indicate col simbolo gole ' (single quotes) o le virgo- echo gettype ($prova); // si ottiene a
$ davanti al nome scelto (il pri- $prova2 = 1,23; lette doppie “ (double quotes). video il tipo di dato: float
mo digit dopo $ non deve mai // $prova2 è un tipo di dato Nel proseguimento del corso si ?>
essere un numero). a virgola mobile (float). userà la seconda notazione che
permette, tra le altre cose, di Il tipo può essere imposto
Tipi di variabili scalari $prova3 = TRUE; inserire dei nomi di variabili al- mediante l'istruzione settype
Vediamo i quattro tipi di va- // $prova3 è un tipo di dato l'interno della dichiarazione all'atto già della dichiarazione
1a lezione
(esplicita) della variabile o at- identificate da un numero. Per segnare a una variabile lo spe- metici, logici e di confronto.
traverso l'imposizione (ca- fare riferimento a un elemento ciale valore NULL. Per comodità sono stati rias-
sting) del tipo (boolean, int, specifico (per stamparlo, mo- Nell'ambito delle variabili, sunti nel riquadro della pagina
float, string, array, object, null): dificarlo e così via) si usa il co- oltre a quelle definite da noi successiva, indicando solo gli
strutto: troviamo le cosiddette variabi- operatori che verranno utiliz-
<?php li superglobals, arrays conte- zati nel corso; per tutti gli altri
setype ($prova, “int”); $array[n] nenti informazioni sul Web ser- operatori (e per la loro prio-
$prova = 1,2; con n valore intero che parte da 0. ver, sull'ambiente di utilizzo e rità) fare riferimento al manua-
echo $prova; // si ottiene a video sugli input degli utenti. Alcuni le di PHP.net.
il valore del tipo “int”: 1 Creare un array come tabella esempi si possono vedere (coi
?> di hash è altrettanto semplice e relativi valori) aprendo la no- Costanti
versatile, ma in questo caso ci stra prima pagina creata (ph- Per alcune esigenze potrem-
<?php dovremo preoccupare di indi- pinfo.php), e altri li vedremo in- mo avere bisogno di definire
$prova = 1,2; care anche il valore (sia esso troducendo i form e le sessioni. delle costanti e non delle varia-
$intero = (int) $prova; un numero o una stringa) da Quasi tutti questi array super- bili. In questo caso il costrutto
echo $intero; // si ottiene a video assegnare alla chiave dell'ele- globali iniziano con un under- da usare è:
il valore del tipo “int”: 1 mento dell'array: score: $_POST, $_GET, $_SES-
?> SION, S_SERVER. define (“nome”, valore);
$hash_a = array (“italia” => ”roma”, echo nome;
Variabili di tipo composto “francia” => ”parigi”, “spagna” => Operatori
Oltre alle variabili di tipo ”madrid”, 12 => “pippo”); Gli operatori consentono di Valore può essere solo di ti-
scalare, ci sono due variabili di $hash_b[“italia”] = “roma”; eseguire operazioni sulle varia- po scalare; nome non è prece-
tipo composto: array e object. $hash_b [“francia”] = “parigi”; bili, operazioni non solo di na- duto dal simbolo $ ed è case
Array non è solo il classico $hash_b[12] = “pippo”; tura numerica (esempio: cal- sensitive.
vettore (ossia una lista di ele- coli aritmetici) e testuale
menti individuati da un indice La stampa dell'hash la pos- (esempio: concatenazione), ma Applicazione:
numerico avente numero ini- siamo vedere nell'esempio ha- anche operazioni di controllo immagine random
ziale 0), ma può essere anche sh.php (listato_06). Per elimina- (esempio: logica binaria) e con- Vediamo finalmente un
una tabella di hash (una map- re, modificare, stampare i dati fronto (esempio: confronto di esempio pratico di quanto ab-
pa), dove un elemento è indivi- dell'hash vi faremo riferimento valori e tipi). biamo imparato: immaginiamo
duato da una chiave non ne- con i due costrutti (diversi a La concatenazione è senza di avere inserito in una certa
cessariamente numerica. Ciò seconda del tipo di chiave): dubbio una delle operazioni cartella del nostro spazio Web
lascia estrema libertà di utiliz- più usate: le variabili in PHP una serie di immagini contenu-
zo del tipo array, ma impone $array[numero] possono essere concatenate te nella directory Immagini e
anche di prestare attenzione $array[“chiave”] // o: $array['chiave'] usando il segno “.”: aventi nome vacanza_x.jpg do-
quando viene richiamato un ve x è un numero intero pro-
valore. Le chiavi possono esse- Si rivelerà utile questa pos- <?php gressivo che parte dal valore 1.
re valori sia numerici, sia di ti- sibilità che ci concede PHP: do- $a = “PC OPEN”; Sulla nostra home page è vi-
po stringa; gli elementi dell'ar- po aver dichiarato un array ha- $b = “una rivista di informatica”; sualizzata una di queste imma-
ray possono essere di qualun- sh_a, possiamo inserire gli ele- $c = $a.”, “.$b; gini, ma noi vorremmo, per
que tipo (anche altri array). menti anche senza fare riferi- echo $c; // si ottiene come output: rendere il sito più attraente e
Se vogliamo creare un vetto- mento a una chiave specifica: PCOPEN, una rivista di informatica farlo sembrare sempre diverso
re, lo possiamo fare in maniera ?> e aggiornato, fare apparire
esplicita (indico la parola chia- $hash_a[ ] = “topolino”; un'immagine diversa ogni volta
ve array) o implicita (assegno i Notate l'inserimento, tra vir- che l'home page viene richiesta
valori alla variabile che sarà il In questo caso la chiave del- golette doppie, della virgola e (o quando viene fatto il refre-
vettore): l'elemento sarà il numero inte- dello spazio vuoto per meglio sh). La situazione di partenza è
ro successivo al numero intero visualizzare a video le due va- visibile nella pagina intro.html
$vettore_a = array (2, 5, 7, 9, 11); più alto già presente nell'hash. riabili. (listato 8) che mostra l'immagi-
// dichiarazione esplicita con elementi Pertanto, come mostrato dal- Lo stesso risultato lo si sa- ne (un quadrato colorato) va-
solo numerici l'array hash_b dell'esempio ha- rebbe ottenuto utilizzando op- canza_1.jpg al centro della pa-
$vettore_b = array (2, “pippo”, true, sh-due.php (listato 7), possia- portunamente la funzione echo gina.
1.24, array (1,2,3)); // dichiarazione mo creare facilmente un array (senza però utilizzare la varia- Dovremo fare in modo che il
esplicita con elementi misti assegnando come chiave ini- bile $c): valore x sia generato in manie-
$vettore_c = array (0 => 2, 1 => ziale un numero diverso da 0. ra random a ogni chiamata del-
“pippo”, 2 => true); // notazione per Vedremo come questo possa echo ”$a, $b”; // equivalente a: echo la home page. Utilizzeremo a
indicare le chiavi del vettore (potevano essere utile quando parleremo $a.”, “.$b; tale scopo la funzione
essere omesse senza problemi) di date. rand(y,z) di PHP, supponendo
$vettore_d[0] = 2; // dichiarazione Il tipo di dato object lo ana- Si può anche “concatenare” di avere cinque immagini nel
implicita del primo elemento del lizzeremo nel prosieguo del una stringa con se stessa con server Web. Il risultato è visibi-
vettore_d corso parlando delle classi. questa sintassi abbreviata: le aprendo la pagina
$vettore_d [1] = “pippo”; random.php (listato 9): la parte
// dichiarazione implicita del secondo Tipi di variabili speciali <?php che ci interessa, quella che ge-
elemento del vettore_d Per finire l'analisi, vi sono $a = “PCOPEN “; nera il numero casuale com-
ancora due tipi speciali di va- $a. = ”amico” // equivale a: $a = preso tra 1 e 5 e che visualizza
Per visualizzare un array e le riabili: resource e null. Il primo $a.”amico”; l'immagine è la seguente:
sue chiavi usiamo la funzione è creato e usato da una serie di echo $a; // si ottiene a video: PC
print_r, come indicato nell'e- funzioni ben definite (per ap- OPEN amico <?php
sempio vettore.php (listato 5). profondimenti vedere le ap- ?> $num=rand(1,5);
Dagli esempi qui sopra ottenia- pendici del manuale PHP), // rand(min,max) genera un numero
mo coppie che sono sempre mentre il secondo serve ad as- Vi sono poi operatori arit- casuale intero compreso tra min e max
1a lezione
4 I form
er interagire con chi acce- trasmettere, in maniera total- 2
L'esempio può essere am- sibile variare la dimensione (in dimensione dei font cui è stata tium) per accrescere l'usabilità
pliato coinvolgendo tutte le ca- pixel) del carattere. assegnata una dimensione fis- del Web a persone cui può es-
ratteristiche della pagina co- Si potrebbe pensare che sa (in punti o pixel). sere assolutamente necessario
me indicato dalle proprietà dei questa indicazione definisca la scalare i caratteri.
CSS. Anche qui, però, mancano dimensione del carattere in Le disposizioni del W3C Tenete poi presente che una
le strutture di controllo: cosa maniera fissa, indipendente dal Chi sbaglia? Diversamente certa dimensione in pixel può
succede se si accede alla pagi- browser. da quanto si potrebbe pensare, essere splendida per certe ri-
na senza passare attraverso In realtà se aprite la pagina è Explorer a non rispettare i soluzioni video, ma per altre
l'introduzione? Sarà il browser articolo.php con Mozilla (oppu- dettami stabiliti per i browser può rivelarsi non adatta perché
a decidere la visualizzazione, re Opera o Firefox) vedrete che Internet: anche se questa pos- troppo piccola.
ma chiaramente questa è una usando le combinazioni CTRL+ sibilità di ridimensionamento Non prendetevela, quindi, se
condizione inaccettabile per il + o CTRL+ - i caratteri aumente- manda in crisi i webmaster (de- dopo aver speso giorni e giorni
webmaster. ranno o diminuiranno di di- siderosi di mantenere il layout a stabilire la giusta visualizza-
mensione. studiato per la pagina), essa è zione della pagina fissando tut-
Accessibilità dei siti Web Microsoft Explorer, invece, espressamente richiesta dal ti i font, un semplice CTRL+ +
Nell'esempio indicato è pos- non modifica assolutamente la W3C (World Wide Web Consor- potrà scompaginare tutto.
5 Costrutti di controllo
er costruire script avanza- lo. Viene definita una condizio- to.php (listato 16): creiamo due Questo costrutto è molto
P ti bisogna padroneggiare
assolutamente le strutture
di controllo, ossia quelle istru-
ne: se (if) è rispettata (condi-
zione vera) viene eseguito il
codice tra le parentesi graffe
numeri interi casuali $a e $b
compresi tra 1 e 4 e verifichia-
mo quale dei due sia più gran-
utilizzato per leggere le liste:
ad esempio si usa while per
mandare a video tutti i record
zioni che consentono di ese- dopo la if, altrimenti si esce de: di una tabella terminando l'e-
guire delle azioni solo a fronte dalla if senza eseguire il codice In alcuni frangenti si dimo- secuzione quando la tabella è
della verifica di particolari con- o viene eseguito del codice al- stra utile usare la parola chiave vuota (vedremo questo utiliz-
dizioni. ternativo (else): exit all'interno di una condizio- zo nelle lezioni dedicate a My-
L'esempio tipico è dato dalla ne: quando viene incontrata SQL).
pagina protetta da password: if (condizione) { questa istruzione, il server Con il costrutto while siamo
volendo descrivere a parole l'a- codice da eseguire se condizione blocca la “traduzione” della pa- finalmente in grado di miglio-
zione connessa, essa suona co- è vera gina e la invia al browser client rare l'esempio creato per la vi-
me Accedi alla pagina solo se la } come definita in quel momen- sualizzazione random di una
password che hai fornito corri- else { to. Un esempio è disponibile in foto (random.php, listato_09).
sponde a quella registrata per il codice da eseguire se condizione controllo-exit.php (listato_17): Cosa succede, infatti, se in-
nome utente inserito. “Solo se” è è false se la prima condizione è soddi- seriamo altre immagini nella
il costrutto di controllo. } sfatta non posso più visualiz- cartella Web che abbiamo scel-
PHP ci fornisce tutti i co- zare quanto scritto dopo la to, sempre seguendo le stesse
strutti standard (for, if, while, Le condizioni if possono es- chiusura del ciclo if: logiche di numerazione?
switch) e un paio di istruzioni sere nidificate senza problemi Dovremmo correggere off-li-
estremamente utili (foreach e per creare strutture comples- if ($a>$b) { ne il listato di cui sopra, sosti-
isset) per accelerare i tempi di se. La condizione elseif con- echo "\$a=$a e \$b=$b:<br>"; tuendo al valore 5 il valore più
scrittura del codice. sente di aggiungere ulteriori echo "\$a è maggiore di \$b"; alto delle nuove immagini in-
condizioni da verificare prima echo "<p><h3> Verificata questa serite, per poi trasferire di
If – else – elseif di arrivare al codice else o di condizione blocco il codice successivo nuovo la pagina sul server so-
La condizione if (con l'even- uscire dal costrutto. usando exit. vrascrivendo la precedente.
tuale aggiunta di else o elseif) è Un esempio di utilizzo lo Non potete sapere cosa c'è scritto Facile, ma è una possibile fon-
la base dei costrutti di control- possiamo vedere in confron- dopo il blocco if!</h3>"; te di errori: PHP ci può rispar-
exit; miare questa operazione ren-
} dendo la nostra pagina valida
LISTATO 16 qualunque sia il numero di im-
While magini presenti nella cartella.
<?php Il costrutto del ciclo while è Per questo sfruttiamo le fun-
$a = rand (1,10); veramente semplice e al con- zioni per le directory (in parti-
$b = rand (1,10); tempo potente: le istruzioni colare opendir e readdir) e i co-
if ($a>$b) { contenute nel ciclo sono itera- strutti di controllo.
echo “$a=$a e \$b=$b:<br>\$a è maggiore di \$b”; // il carattere te finché la condizione è vera, Innanzi tutto usiamo open-
escape (\) serve a visualizzare come output simboli particolari come $ ogni volta andando a leggere dir per registrare (e validare) il
} (ordinatamente) il valore suc- percorso della cartella, e poi
elseif ($a==$b) { // notare l'operatore di confronto == cessivo della condizione. readdir per leggere il primo file
echo “$a=$a e \$b=$b:<br>\$a è uguale a \$b”; Quando la condizione diventa della directory.
} falsa il ciclo si arresta e prose- Qui interviene while: attra-
else { gue oltre: verso una condizione while su
echo “$a=$a e \$b=$b:<br>\$a è minore di \$b”; while (condizione) { readdir, la directory viene letta
} codice file dopo file e ogni riferimento
?> } è registrato su un array. Esau-
1a lezione
rita la lettura, il codice esce dal for (punto iniziale; condizione da LISTATO 20
ciclo while e possiamo final- rispettare; tipo di iterazione) {
mente definire $max, ossia il codice da eseguire if ($fine%2==0) { // controllo se nella cartella c'è un numero pari di immagini
numero di immagini che ab- } for ($i=2;$i<count($lista);$i=$i+2) { // il ciclo di for visualizza due file
biamo trovato nella directory ad ogni iterazione
Immagini. For si rivela utilissimo per $ordine=$i-1;
Ecco quindi la pagina ran- costruire strutture di pagina $j=$i+1;
dom-due.php (listato 18). di cui non possiamo conoscere echo "<span class='dispari'>File $ordine: $lista[$i]</span>";
La parte più utile da analiz- con anticipo tutti gli elementi: echo "<span class='pari'>File $i: $lista[$j]</span>";
zare è la seguente: stiamo parlando, quindi, di ve- }
ri e propri siti dinamici. }
while (false !== ($file = readdir($cartella))) { Per capire meglio, possiamo else { // il numero di immagini è dispari, quindi si deve aggiungere l'ultima riga
// il ciclo while verrà iterato finché costruire un esempio basan- dispari
la cartella non sarà stata interamente doci su quanto visto per il co- for ($i=2;$i<$fine;$i=$i+2) { // il ciclo for visualizza due file per ogni
letta. A ogni iterazione $file assume strutto while con la directory iterazione e si ferma prima dell'ultima immagine
il nome del file successivo. Immagini. $ordine=$i-1;
Con la prima iterazione creo l'array In questo caso, però, il no- $j=$i+1;
e registro il primo nome di file, stro scopo è ottenere la lista echo "<span class='dispari'>File $ordine: $lista[$i]</span>";
poi l'array viene riempito con i nomi delle immagini contenute nella echo "<span class='pari'>File $i: $lista[$j]</span>";
dei file seguenti cartella, visualizzandole nella }
$lista[ ]=$file; pagina Web elenco-dir.php. Qui $j=$i-1;
} trovate la parte del listato che echo "<span class='dispari'>File $j: $lista[$i]</span>";
// count conta il numero si riferisce al costrutto for (li- }
di elementi contenuti nell'array. Viene stato 19).
diminuito di due perché l'array della Possiamo migliorare la visi-
cartella contiene sempre le indicazioni bilità del nostro elenco visua-
UNIX "." e ".." lizzando i file alternativamente mero prefissato di immagini, o Dove sta la differenza? Nel
$max=count($lista)-2; su righe aventi colore di sfon- altri oggetti, per ogni pagina primo caso la variabile $mese
if ($max==0) { do diverso (elenco-dir-due.php, (ad esempio sei immagini per è valutata all'inizio del costrut-
echo "Attenzione: Non ci sono listato_20). Qui l'attenzione va pagina) e una barra di naviga- to e poi il valore è solo con-
immagini nella cartella"; posta nel conteggio delle righe zione per spostarsi tra le pagi- frontato con quelli delle istru-
} da mandare in output: se sono ne. zioni case, mentre nel caso di
else { pari verrà eseguito un ciclo for if la variabile $mese è valutata
$num=rand(1,$max); e usciremo dalla pagina, men- Switch e verificata ogni volta, con uno
} tre se sono dispari il ciclo for Il costrutto switch somiglia spreco di risorse e tempo di
dovrà fermarsi prima dell'ulti- a una serie di if di uguaglianza: elaborazione.
Ricordiamo che PHP 5, al ma riga, che andrà stampata a una variabile (array e object Notate la parola chiave
momento rilasciato solo come parte (listato 20). esclusi) viene confrontata con break: va inserita al termine di
release candidate, prevede una Un buon esercizio per verifi- dei valori predefiniti così da ogni blocco di codice case, al-
nuova funzione, scandir, in gra- care di aver compreso bene i eseguire differenti blocchi di trimenti il parser continuereb-
do di evitare questo passaggio concetti di cui sopra può esse- codice a seconda del valore be leggendo il blocco succes-
con while: scandir sarà infatti re il seguente (è una variazione assunto dalla variabile: sivo invece di uscire dal co-
in grado di leggere i contenuti sul tema di quanto appena vi- strutto.
di una cartella e registrarli di- sto): creare una galleria delle $mese=date('n'); È possibile definire un case
rettamente in un array senza immagini della directory, vi- switch ($mese) { con valore default: il codice
utilizzare altre funzioni. sualizzandole a due a due, una case 1: sarà eseguito quando tutte le
di fianco all'altra. echo “Siamo in Gennaio”; altre condizioni case si rivele-
For Chiaramente dovremo usare break; ranno false.
Il ciclo for consente di itera- le tabelle e/o i CSS, ponendo case 2:
re un'azione, definendo la con- attenzione all'eventuale ultima echo “Siamo in Febbraio”; Isset
dizione iniziale di un puntato- immagine dispari. La soluzione break; Abbiamo spesso la neces-
re, il controllo da fare e l'incre- da me proposta la trovate nel- case 3: sità di controllare, prima di
mento del puntatore dopo la pagina elenco-galleria.php echo “Siamo in Marzo”; compiere un'azione, se una va-
ogni ciclo. L'azione verrà ese- (sul CD). break; riabile è definita (anche se ma-
guita (e rieseguita) finché il Vedremo nelle prossime .................. gari con valore nullo) oppure
controllo darà risposta true al- puntate del corso come creare } se non lo è.
la verifica. una galleria con un certo nu- Questo controllo è assolto
Lo stesso risultato si sareb- semplicemente da isset in
be raggiunto con: combinazione con if: isset, in-
LISTATO 19 fatti, restituisce un valore true
$mese=date('n'); se la variabile cui fa riferimen-
echo "<h4>La cartella 'immagini' contiene questi file:</h4><p>"; if ($mese==1) { to esiste:
for ($i=2;$i<=count($lista)-1;$i++) { // il contatore $i parte da 2 echo “Siamo in Gennaio”;
perché i primi due valori registrati nell'array $lista sono } if (isset($variabile)) {
“.” e “..”, e non voglio visualizzarli if ($mese==2) { codice
echo “Siamo in Febbraio”; }
$ordine=$i-1; }
echo "---------------------------------------------------<br>"; if ($mese==3) { Possiamo usare isset per mi-
echo "<span class='output'>File $ordine: $lista[$i]</span><br>"; echo “Siamo in Marzo”; gliorare l'esempio in cui modi-
} } ficavamo la visualizzazione di
.................. un articolo.
1a lezione
<style>
usare un ciclo for (ma dobbia-
mo sapere quanti elementi I corsi
span.output {
font-family:
compongono l'array) o un ciclo
while (con una struttura non
Webmaster
<?php molto amichevole). Oppure un disponibili
if (isset($_POST['carattere'])) {
echo $_POST['carattere'];
semplice ciclo foreach (pagina
lista-disney.php, listato 22): nel CD
// valido solo se è stato sottoscritto il form e quindi $_POST esiste Un altro esempio concreto
} lo si ha in occasione della vali- Nel CD Guida 2 allegato
else { dazione dei dati passati attra- a questo numero di PC
echo "Arial"; verso un form: se vogliamo Open, all’interno della
// è la visualizzazione di default quando $_POST non esiste, porre tutti i campi di un form cartella PDF/Corsi, trovate
ossia non è mai stato cliccato il bottone “invia” del form come obbligatori, dovremo due corsi completi che
} controllare tutti i campi per ve- possono essere un utile
?>; rificare che sia stato immesso complemento al corso PHP.
} un valore, inserendo quindi Uno è il corso Web
</style> una serie di istruzioni if e/o is- Developer ASP, 97 pagine
set. Foreach ci viene in aiuto suddivise in quattro lezioni
per rendere la scrittura più agi- per capire come realizzare
le e per evitare banali dimenti- siti dinamici in tecnologia
LISTATO 22 canze, come si vede dalla pagi- ASP.
na check.php (listato 23):
$lista=array (“pippo”, “topolino”, “paperino”, “pluto”); Notate, nel ciclo if, la funzio-
foreach ($lista as $copia) { ne trim il cui scopo è eliminare
echo “Un personaggio Disney: $copia<br>”; tutti gli spazi vuoti all'inizio di
} un campo: in questo modo se
un utente compilasse il form
Si può utilizzare foreach anche per definire un secondo array contenente le chiavi solo con degli spazi vuoti, il no-
dell'array originale: stro test comunque non ne va-
liderebbe l'inserimento (una
$lista=array (“pippo”, “topolino”, “paperino”, “pluto”); funzione if semplice, invece, l'a-
foreach ($lista as $chiave=>$copia) { vrebbe fatto passare).
echo “Personaggio Disney numero $chiave -> $copia<br>”; Un controllo di questo tipo è
} sufficiente per la maggior parte
delle nostre esigenze, come ve-
dremo nella prossima puntata
del corso.
Introduciamo qui anche la
LISTATO 23 funzione die che interrompe
l'esecuzione della pagina vi-
if (!isset($_POST['nome'])) { sualizzando come output il co-
// serve solo alla prima chiamata della pagina dice chiuso dalle parentesi. Il corso Webmaster spiega,
die ("<p><h3>Tutti i campi vanno obbligatoriamente compilati</h3>"); Lo stesso compito era assol- invece, in 88 pagine
} to anche da exit, vista in uno suddivise in otto lezioni tutto
foreach ($_POST as $ctr) { degli esempi precedenti. quello che bisogna sapere
// foreach ci consente di controllare tutto l'array $_POST per costruire un sito
if (trim($ctr)==""){ Siti di riferimento e imparare il linguaggio
// trim toglie gli spazi vuoti eventualmente presenti in $ctr Se volete avere ulteriori ap- HTML 4.01, i CSS (fogli
die ("<p><h3>Tutti i campi vanno obbligatoriamente compilati</h3>"); profondimenti su PHP potete di stile), Java Script e CGI.
} visitare questi siti: Il corso è completato da utili
} consigli per promuovere
http://www.php.net il proprio sito on line.
http://freephp.html.it
http://www.apache.org
Invece di usare un form in- Foreach
termedio di passaggio (tra l’al- Foreach, un po' come isset, Se state ricercando un sug-
tro poco elegante, dal momen- ci aiuta a risparmiare tempo gerimento su una qualsiasi fun-
to che il nostro utente potreb- per compiere un'azione di cui zione di PHP, potete accedere
be accedere direttamente alla spesso si ha bisogno: attraver- velocemente alle pagine del
pagina articolo.php una volta sare completamente un array, manuale on-line scrivendo
che ne conosca l'URL), po- effettuando delle operazioni l'URL del sito seguito da uno
tremmo definire dei valori di (assegnazione, confronto, vi- slash con la parola da ricerca-
default validi finché non viene sualizzazione, ...) su un secon- re, ad esempio http://
scelto un diverso carattere dal do array “copia” appositamen- www.php.net/isset (sul manua-
form cliccando su “invia”. te creato. le sarà cercata la parola isset).
Il controllo della definizione La funzione più importante È utile farlo perché, oltre alla
iniziale delle variabili è de- la si rileva quando bisogna descrizione del manuale, si tro-
mandato proprio a isset come operare su un array completo, vano anche molti esempi prati-
esemplificato in articolo- anche solo per visualizzare tut- ci scritti dagli utilizzatori di
due.php (listato 21): ti gli elementi. PHP.
2a lezione
1 Approfondire PHP
ella lezione 1 abbiamo Il discorso sarà poi concluso IL CALENDARIO DELLE LEZIONI
N esplorato le basi di PHP,
dando tutti gli elementi
per creare le nostre prime pa-
nella terza puntata, dove ver-
ranno trattate anche tematiche
relative alla sicurezza e alla ge- Lezione 1: - Proteggere una pagina
gine e alcuni spunti per coglie- stione degli errori. - PHP con un server off line - Cookie e sessioni
re le potenzialità di questo lin- Non parleremo ancora della - Funzioni base e variabili - La funzione mail
guaggio. connessione tra PHP e i data- - I costrutti di controllo
Nella seconda lezione mette- base (con particolare riguardo Le prossime puntate
remo in luce, invece, funziona- a MySQL), in quanto questo ar- Lezione 2: Lezione 3: PHP e database
lità avanzate che ci consenti- gomento sarà oggetto di tratta- - Approfondiamo PHP Lezione 4: PHP e MySQL
ranno di migliorare i nostri zione specifica e approfondita - Include e require Lezione 5: Gestire un sito
script, rendendoli più efficienti nelle prossime puntate del cor- - Funzioni e classi dinamico con PHP e MySQL
e utilizzabili anche per il futuro. so.
3 Funzioni e classi
pesso si scrivono righe di La funzione deve avere un Una volta scritta, la funzione variabile come fosse la $sconto
almeno un file (ed elegante) consiste, invece, proprietà. Lo faccio senza pen- bo colorato. A questo punto
{ nello salvare le funzioni in file sare all'oggetto specifico X o al- per risolvere il nostro compito
$cartella=@opendir('varie'); separati includendoli poi co- l'oggetto specifico Y, bensì non ci resta che creare due “og-
if (!$cartella) { me già visto. Ogni modifica fat- guardando al concetto più getti” facenti riferimento a que-
return "Attenzione: è inutile cercare ta sulla funzione verrà quindi astratto possibile grazie al qua- sta classe, inizializzando sem-
file... la cartella non esiste e quindi propagata automaticamente a le posso poi definire gli oggetti plicemente i due oggetti con le
devi prima crearla"; tutte le pagine: specifici. loro caratteristiche. Siamo in
} Una classe è, quindi, una col- grado di creare infiniti rombi e,
while (false !== ($file = <?php lezione di variabili (proprietà) fondamentale, siamo in grado
readdir($cartella))) { include (“funzione_controllo.inc.php”); e funzioni (metodi) che utiliz- di farlo pur non sapendo nulla
$lista[]=$file; ?> zano queste variabili: di cosa sia un rombo! Forniti i
} dati di colore e dimensioni, in-
$fine=count($lista)-2; Non è possibile, per chiarez- class Nuova_classe fatti, è la classe che si incarica
if ($fine==0){ za di comportamento del codi- { di restituire gli oggetti in ma-
return "Attenzione: Non ci sono file ce, ridefinire funzioni già di- variabili (proprietà) niera del tutto trasparente per
nella cartella"; chiarate all'interno di uno stes- funzioni (metodi) l'utente.
} so listato (overloading). } Vediamo di fare un esempio
return “Prosegui pure: nella cartella di programmazione di classe:
c'è almeno un file”; Le classi Definita una classe come ve- supponiamo di creare una clas-
} Le funzioni sono costrutti dremo in seguito, possiamo ge- se Quadrato grazie alla quale,
listato 5 semplici, adatti a lavori ripeti- nerare un oggetto utilizzando il una volta definito il lato, pos-
tivi da cui ci si aspetta un unico costrutto new: sano essere ricavati i valori di
Per rendere più utilizzabile risultato. area, perimetro e diagonale. La
questa funzione, si può passare Non sempre ciò è sufficiente, $oggetto = new Nuova_classe; definizione completa della clas-
alla funzione un argomento basti pensare al caso di costru- se la trovate in classe_quadra-
uguale al percorso della cartella zioni di codice avanzato in gra- È il codice della classe che to.inc.php, mentre qui ci basta
da controllare. La modifica è fa- do di interagire con altre fun- “definisce” l'oggetto, il quale un estratto (listato_06) con so-
cile (la trovate in checkvarie_ zioni e variabili: un esempio deve essere creato, tramite l'i- lo il metodo “area”.
plus.php): basta definire la fun- può essere la creazione di un struzione new, con un nome
zione controllo ($directory) e sistema di gestione avanzato di diverso da quello di altri ogget- class quadrato
inserire $directory all'interno commercio elettronico, magari ti istanziati (cioè inizializzati) {
della funzione come argomen- da esportare su più siti. In que- dalla stessa classe. Per il con- // dichiarazione delle variabili
to di opendir. sto caso un'architettura de- cetto stesso che sta alla base utilizzate (da accompagnare con una
Ulteriore esercizio è prende- mandata a funzioni stand-alone della programmazione OO, in- descrizione, per rendere più leggibile il
re il percorso della cartella da è possibile, ma diventa sempre fatti, è possibile definire quanti codice)
controllare direttamente da un più difficile da gestire all'au- oggetti si vuole basandoli su var $lat;
form: provate a costruire la pa- mentare della complessità ri- una stessa classe. Ricordate la var $ar;
gina da soli e poi confrontatela chiesta. scorsa puntata quando parla- var $per;
con checkvarie_form.php (vedi Per esigenze di questo tipo vamo dei tipi di variabili? Man- var $diago;
immagine 5). Adesso potete ci viene in aiuto il concetto di cava solo il tipo object, ossia
controllare tutte le cartelle che classe, grazie al quale potremo proprio quello definito usando function quadrato($lato)
volete, l'unica accortezza è ri- addentrarci brevemente nella la classe. // costruttore
cordarsi che il percorso della programmazione rivolta agli Definito un oggetto, a esso è {
cartella è relativo e non assolu- oggetti. La trattazione non può possibile applicare tutti i me- $this->lat=$lato;
to. essere esaustiva perché l'argo- todi implementati nella classe }
Abbiamo detto all'inizio del mento prevede conoscenze di appartenenza, in maniera
paragrafo che la funzione origi- specialistiche, ma la cosa im- molto semplice e con una puli- function area()
nale deve essere presente nel portante è riuscire a cogliere il zia di codice inarrivabile per // calcola l'area del quadrato
codice prima di un’eventuale concetto alla base della pro- una programmazione stan- {
chiamata. Potremmo pensare grammazione OO (Object dard. $this->ar=$this->lat*$this->lat;
di inserire (copia-incolla) la Oriented) per poterlo poi ap- Facciamo un esempio tratto return $this->ar;
funzione in tutte le pagine che profondire con testi o corsi dalla vita di tutti i giorni: se de- }
ci interessano, ed è una valida specifici. vo disegnare un rombo grande }
idea se le pagine che usano Orientarsi agli oggetti signi- rosso e un rombo piccolo gial- listato 6
questa funzione sono poche, fica porre l'accento sulla defi- lo, sostanzialmente devo fare
altrimenti ricadiamo nei pro- nizione di tutte le proprietà ge- due operazioni simili. Ci sono due cose da notare:
blemi già descritti in preceden- neriche di un certo oggetto e Qual è la differenza tra i due quando è definita una funzione
za. Una soluzione più efficiente delle funzioni legate a queste “oggetti” da disegnare? Solo la con lo stesso nome della clas-
dimensione e il colore, dal mo- se, questa funzione prende il
5 mento che la definizione di nome di costruttore. Il costrut-
rombo è unica! Bene, allora è tore è utile in certe classi per-
sufficiente che sia dichiarata ché inizializza il tipo di oggetto
(una volta per tutte) una “clas- della classe stessa. In questo
se” Rombo all'interno della caso il costruttore serve a ini-
quale siano introdotte le varia- zializzare l'oggetto col valore
bili dimensioni e colore che del lato del quadrato. Il co-
consentono di effettuare il di- struttore può anche non essere
segno. indicato, ma se lo è sarà inter-
Alla classe non interessa il ti- no alla classe e avrà necessa-
po di rombo da disegnare, ma riamente il nome della classe
Il risultato in pagina della funzione controllo solo definire che cos'è un rom- stessa.
2a lezione
C
<input type="submit" name="invio"
zioni e classi abbiamo diamo adesso un paio di esem- fronte al form vuoto. value="Connetti">
esaurito le nozioni fonda- pi, rimandando poi l'approfon- </form>
mentali di PHP. dimento del discorso a dopo <?php <?php
Arrivati a questo punto non l'introduzione dei database (le- }
dovrebbe quindi essere un pro- zione 4). function controllo ($confronto, $pass) { else {
blema affrontare un compito PHP ci consente di ottenere if ($confronto==$pass) { // la password è esatta e quindi
molto pratico (e utile), ossia la protezione di una pagina in return true; posso avere accesso alla pagina
elaborare qualche strategia per molti modi. Quello scelto per } echo "<h3>Hai inserito la password
proteggere una o più pagine esercizio implica la creazione return false; giusta. La pagina è a tua
del nostro sito Web da occhi in- di una funzione e l'uso di un ci- } disposizione</h3>";
discreti. In pratica, vogliamo clo di controllo (listato_08). La }
che a certe pagine possano pagina di esempio è protet- $password=”pluto”; ?>
avere accesso solo le persone ta_1.php, e al primo accesso ci // la password “pluto” l'abbiamo listato 8
dotate di una password, o me- fa vedere un form dove l'unico impostata noi
glio di una precisa accoppiata campo da compilare è quello Una variazione sullo stesso
username-password. relativo alla password da inse- $check=controllo($_POST['pwd'], tema (meno elegante, ma
I motivi di questa decisione rire. $password); ugualmente efficace) la potete
possono essere i più vari: su La funzione controllo si oc- // $check assumerà valore true o vedere in protetta_1_var.php.
una pagina possiamo avere in- cupa solo di restituire un valo- false in dipendenza del valore inserito Per migliorare la costruzio-
serito testi e immagini che solo re true o false, a seconda che il nel form ne presentata, bisogna quanto-
i nostri amici più cari devono confronto tra le due variabili meno posizionare in un file
leggere, ma potrebbe anche es- dia esito positivo o negativo. if ($check==false) { esterno la funzione e il valore
sere una esigenza di lavoro che Nel nostro caso, il valore resti- // la password è errata o non è mai assegnato da noi alla password
ci impone di tutelare certe tuito dalla funzione sarà asse- stata inserita (vedere password.inc.php e pro-
informazioni, oppure una parte gnato a una variabile $check, la ?> tetta_1_inc.php).
del Web site deve essere pro- quale chiama la funzione usan- <h3>Inserisci la password corretta per In questo modo è possibile
tetta perché da essa è possibi- do come campi la password in- entrare nella pagina protetta</h3> usare il costrutto include per
le gestire gli aggiornamenti del serita nel form e la password <form action="protetta_1.php" inserire senza errori la stessa
sito stesso. definita da noi (pluto). Se method="post"> password in più pagine e se si
Qualunque sia il motivo, ab- $check avrà valore true allora la <input type="password" modifica la password lo si fa in
biamo la necessità di protegge- pagina sarà visualizzata, altri- name="pwd"> = password<p></p> un unico punto.
2a lezione
Un altro limite, però, è pro- il codice precedente, introdu- } sulla pagina protetta_2.php.
prio quello di avere una sola cendo un controllo username- } Adesso siamo in grado di mo-
password per tutte le persone password. return false; dificare username e password
che hanno accesso alle pagine: Usiamo la stessa logica vista } delle singole coppie.
se dovessimo cambiarla per nel primo esempio, con la no- Anche in questo caso, poi,
motivi di sicurezza (poniamo vità di creare un array conte- // valori di username e password sarà buona consuetudine por-
che sbadatamente qualcuno nente le coppie username-pas- decisi da noi tare in un file esterno la funzio-
abbia comunicato la password sword. $coppie=array("pippo"=>"pluto", ne e la definizione di $coppie
a persone non autorizzate) do- La parte di codice che ci in- "topolino"=>"minni", (vedi pagine password_2.inc.
vremo informare necessaria- teressa (con la nuova funzione "paperino"=>"paperina"); php e protetta_2_inc.php).
mente tutti gli attori coinvolti. di confronto e con l'array $cop- Nel prosieguo del corso ve-
Sarebbe invece più efficiente pie) è visibile in listato_09: // $check darà un valore true o false dremo come usare i database
assegnare a ogni persona una $check=controllo_coppia($coppie,$_ per proteggere una pagina e
diversa coppia username-pas- function controllo_coppia($confronto, POST['user'],$_POST['pwd']); come evitare di dover inserire
sword, in modo da modificare, $user,$pass) { listato_09 username e password su ogni
eventualmente, soltanto la pas- foreach ($confronto as $chiave=>$val) pagina protetta.
sword di quella persona speci- { La parte che segue il listato 9 Ma per questi argomenti
fica. if ($chiave==$user and $val==$pass) { è uguale a quanto già visto e l'e- l’appuntamento è alle lezioni 4
Vediamo allora di modificare return true; sempio completo è riportato e 5.
5 Cookie e sessioni
l protocollo HTTP è un proto- prima di cookie e poi introdur- dal disco fisso del client. Se il valido sei mesi.
queste pagine. L'ultima volta che hai ne passato attraverso un sione solo dati che possano, tutto cancellata con l'istruzio-
aperto questa pagina è stato il cookie temporaneo che viene nel caso più malaugurato, es- ne session_destroy.
".$_COOKIE['data']."</h4>"; poi cancellato dal client quan- sere letti da altri senza danni.
} do viene chiuso il browser (o Giusto per fare un esempio, Il carrello della spesa
else { quando la sessione è esplicita- se si vuole usare la sessione E ora vediamo un esempio
echo "<h4>Ciao amico, è la prima mente chiusa con un'operazio- per mantenere attivo, durante pratico che può dare molti
volta che visualizzi questa pagina ne di logout). Da parte del un collegamento, l'accesso a spunti: il carrello della spesa.
oppure hai cancellato il cookie dalla Webmaster non c'è da fare nul- più pagine riservate, è bene Supponiamo di avere una pagi-
memoria del tuo PC</h4>"; la di particolare. non salvare come variabile di na all'interno della quale sia
} Il secondo sistema, invece, sessione un dato sensibile co- possibile scegliere tra libri e di-
?> consiste nel passare il SID at- me la password. In ogni caso, schi da due elenchi (vedi la pa-
listato 11 traverso l'URL di una pagina niente allarmismi: ricordo che gina lista.php), e una pagina
usando i metodi GET o POST, il SID identificante la sessione che funga da riepilogo (vedi
Un cookie può essere can- quindi ogni link di pagina sarà è composto da 32 caratteri al- carrello.php) di quanto scelto
cellato assegnandogli un valo- del tipo: fanumerici casuali ed è quindi durante la sessione in corso,
re null in questo modo: estremamente improbabile potendo anche tornare in un
<a href=”nuova pagina.php?<?php che un estraneo possa entrare secondo momento nella lista
setcookie (“data”); echo SID; ?>">Clicca qui</a> accidentalmente in una nostra per ordinare altri prodotti.
sessione! Sulla pagina lista.php va no-
Sessioni Quale scegliere? Il metodo Per usare le sessioni, le re- tata la chiamata della sessione
I cookie, lo abbiamo appena “cookie” è più semplice dal gole da conoscere sono relati- e la trasmissione del SID all'in-
visto, salvano un piccolo file di momento che non bisogna fare vamente poche. terno della riga di intestazione
informazioni all'interno del no- nulla, però dovremo preoccu- Innanzi tutto, quando un vi- del form. In questo modo non
stro PC, quindi lato client. Le parci di prevedere la trasmis- sitatore accede al sito, PHP ci interessa sapere se un uten-
sessioni, al contrario, sono un sione del SID anche per quegli controllerà (su nostra esplicita te abbia o meno i cookie atti-
metodo lato server per archi- utenti che hanno disabilitato i richiesta formulata tramite la vati:
viare informazioni relative a un cookie, quindi o si fa un con- funzione session_start) se uno
singolo accesso. trollo per vedere se i cookie di specifico ID di sessione sia pre- <form action='carrello.php?<?php
Per avere un esempio, pos- sessione sono attivi (basta ve- sente. echo SID; ?>' method="post">
siamo pensare ai siti di com- rificare se esiste un cookie In caso positivo il preceden-
mercio elettronico in cui è pre- chiamato PHPSESSID) o si tra- te ambiente salvato verrà ri- Fatta la selezione e fatto clic
sente un “carrello della spe- smette sempre e comunque il creato, altrimenti verrà inizia- sul pulsante Vai ci troviamo
sa”: il compito essenziale per il SID. lizzata una nuova sessione col nella pagina carrello.php dove
Webmaster è mantenere regi- In realtà esiste anche un ter- suo specifico SID. si vedono le selezioni effettua-
strate le scelte effettuate da zo metodo di passaggio del Come visto per i cookie, an- te fino a quel momento. Ciò è
un cliente durante un collega- SID, completamente traspa- che session_start() dovrà esse- reso possibile dalle variabili di
mento (l'utente potrebbe ac- rente per programmatore e re chiamata prima di qualsiasi sessione, come si può vedere
quistare N libri, spostandosi utente dal momento che il SID output html. Le variabili di ses- analizzando l'estratto visibile
continuamente di pagina in pa- è trasmesso automaticamente. sione saranno poi richiamate nel listato 12.
gina). La sessione serve pro- Questa possibilità, però, impli- come variabili globali $_SES-
prio a questo, a mantenere me- ca l'attivazione dell'opzione SION, e potranno essere “can- <?php
moria delle scelte fatte duran- trans_sid nel php.ini, cosa non cellate” in maniera molto sem- session_start();
te un collegamento da ogni sin- sempre possibile se il server plice usando l'istruzione unset. // controllo se è stato selezionato un
gola persona, scelte che poi non è nostro. Inoltre general- La sessione può essere del libro
possono essere memorizzate o mente l'opzione è disattivata
cancellate! Si potrebbero an- di default e quindi non tratte- 6
che usare i cookie, ma in que- remo questo caso.
sto caso ci sarebbe il problema Cosa succede dei file sessio-
di cosa fare se sono stati disa- ne registrati sul server? Quan-
bilitati. to tempo restano salvati? La
Con le sessioni, i dati sono durata di salvataggio dei dati
registrati nel server che ospita sul server e anche la durata
il sito e vengono identificati (e della sessione stessa sono de-
differenziati gli uni dagli altri) finite nel php.ini e quindi di-
tramite un identificativo uni- pendono dal gestore del ser-
voco denominato SID (Session ver: questi valori sono visibili
Identifier). Il SID (casuale e non visualizzando la pagina ph-
prevedibile: è formato da 32 pinfo di cui abbiamo parlato
caratteri alfanumerici) viene nella prima lezione.
assegnato a ogni utente che si È chiaro, altresì, che un file
collega al sito e la sessione vie- di sessione potrà essere recu-
ne mantenuta attiva (ossia vie- perato e riutilizzato in un se-
ne mantenuto lo “stato”) fin- condo momento solo se si è te-
ché il SID viene passato tra nuta nota del SID, altrimenti
server e client durante la navi- non vi si potrà accedere in nes-
gazione del sito. sun caso.
Fondamentale, dunque, è il Va posto un minimo di at-
passaggio del SID, operazione tenzione al fatto che i file sal-
che può avvenire in due modi. vati sul server sono semplici fi-
Nel primo caso tornano utili i le di testo non criptati: è bene,
cookie: se sono attivi, il SID vie- quindi, salvare nei file di ses- La pagina carrello.php presenta le selezioni effettuate dall’utente
2a lezione
1 PHP e i database
a terza puntata del corso è concetti fondamentali riguar-
IL CALENDARIO DELLE LEZIONI
L divisa concettualmente in
due sezioni ed è il trâit d'u-
nion tra i due oggetti di questa
danti i database, concetti sen-
za i quali non saremo in grado
di sfruttarne al meglio le carat-
Lezione 1:
- PHP con un server off line
- La funzione upload
- Lavorare con i file
serie di lezioni per Web deve- teristiche. - Funzioni base e variabili - La gestione degli errori
loper. Capiremo cosa siano un Da- - I costrutti di controllo - Accenni di sicurezza
Nella prima parte conclude- tabase System e un DBMS (Da- - DataBase: il database
remo il corso di PHP sviluppa- tabase Management System) e Lezione 2: system
to nelle due precedenti lezioni, vedremo i principi basilari per - Approfondiamo PHP - Siti Web dinamici
approfondendo gli ultimi aspet- la corretta costruzione di una - Include e require - Teoria dei database
ti pratici di programmazione e base di dati. - Funzioni e classi
introducendo alcuni suggeri- Al termine di questa lezione - Proteggere una pagina Le prossime puntate
menti generali in termini di ge- saremo quindi in grado di pa- - Cookie e sessioni
stione degli errori e di sicurez- droneggiare PHP e la teoria dei - La funzione mail Lezione 4: PHP e MySQL
za. DB, pronti a unire queste due Lezione 5: Gestire un sito
La seconda parte, invece, è conoscenze nelle due puntate Lezione 3: PHP e i database dinamico con PHP e MySQL
dedicata all'introduzione dei restanti del corso.
2 Upload di file
ella prima le- ne dello spazio a nostra dispo- sia perché, accidentalmente o Ci sono tre cose cui prestare
N zione abbia-
mo visto co-
me installare un
sizione.
Spesso solo webmaster,
webdesigner e webcontent,
volutamente, potrebbero can-
cellarne tutti i contenuti.
attenzione (listato 01): la parti-
colare istruzione enctype nel-
l'intestazione del form (senza
I listati server locale per ognuno per la sua area di com- Come effettuare l’upload la quale l'operazione non viene
completi poter testare off li- petenza, si occupano di carica- dei file svolta), l'imposizione della di-
sono sul CD ne in tutta calma le re contenuti nel sito, ma in al- La soluzione è quindi creare mensione massima (in byte)
pagine PHP prima cuni casi potremmo voler dare una pagina Web attraverso la del file caricabile e il type “file”
di caricarle sul no- la stessa possibilità anche ai quale compiere l'operazione di dell'istruzione di input.
stro spazio Web. nostri visitatori (o ai nostri upload dei file. A seconda dei
clienti). nostri scopi la pagina potrà es- Listato_01
L’accesso FTP del provider Pensiamo, ad esempio, al ca- sere o no protetta, consenten- <form enctype="multipart/form-data"
Per compiere questa opera- so di un sito di viaggi amato- do l'accesso ai soli utenti auto- action="file_upload.php"
zione il provider ci avrà asse- riali che voglia consentire agli rizzati. method="post">
gnato un accesso FTP (File utenti (meglio se registrati) di PHP è in grado di ricevere fi- <input type="hidden" name="MAX_
Transfer Protocol) protetto da caricare (uploadare) le imma- le (in forma testuale o binaria) FILE_SIZE" value="100000">
username e password, accesso gini della loro ultima vacanza, o direttamente da un form di una File da inviare: <input name="mio"
grazie al quale saremo in grado ad un sito di un ente pubblico pagina Web e ci fornisce una type="file" size="40"><p>
di spostare, aggiungere, can- in cui una persona designata si serie di funzioni di autentica- <input type="reset" value="Cancella"
cellare, rinominare file diretta- occupi di caricare le delibere di zione e manipolazione grazie > <input type="submit"
mente sul server remoto come interesse pubblico senza do- alle quali abbiamo un comple- value="Invia">
stessimo utilizzando il ben co- ver ogni volta passare attra- to controllo su quanto viene </form>
nosciuto Esplora Risorse di verso il webmaster. caricato e sulla sua gestione fu-
Windows. È chiaro che queste persone tura. Il file individuato dopo aver
Possiamo anche fare l'u- non devono assolutamente Costruiamo per prima cosa premuto il bottone sfoglia (o
pload di immagini, filmati, file avere accesso tramite FTP alla il form di inserimento, come vi- browse se abbiamo impostato
musicali; l'unico limite è gene- struttura del sito Web, sia per sibile nella pagina form_ la lingua inglese di visualizza-
ralmente dato dalla dimensio- motivi di sicurezza e privacy upload.php. zione) viene caricato in memo-
A
listato 05
visto come lavorare coi fi- <select name="nome" size="1"><option></option> sul giorno e l'ora del clic: que-
le e con le directory quan- <?php sto file potrà poi essere editato
do abbiamo introdotto le fun- $cartella=@opendir('upload'); con un foglio elettronico per ri-
zioni basename, opendir e while (false !== ($file = readdir($cartella))) { cavarne delle statistiche.
readdir nelle lezioni preceden- $lista[]=$file; Il sorgente della pagina
ti, e lo stesso caricamento di fi- } link.php ci mostra come otte-
le appena visto è un altro esem- $lista=array_slice($lista,2); nere questo risultato. Per pri-
pio di utilizzo delle funzioni fi- // array_slice lo uso per eliminare le indicazioni . e .. presenti in readdir. ma cosa impostiamo la sezione
lesystems di PHP. Abbiamo a È un sistema più veloce per compiere la stessa operazione vista HTML: non ci sono difficoltà,
disposizione numerosissime nella prima lezione salvo l'accortezza di indicare
funzioni pronte all'uso (sem- foreach ($lista as $nomi) { ogni link in questo modo:
pre che si abbia la pazienza di echo "<option>".$nomi."</option>";
leggere il manuale), sta solo a } <a href="link.php?url=http://
noi trovare la maniera migliore ?> www.pcopen.it">PC Open</a><p>
di operare. </select> // link.php è la pagina dove ci
Nel paragrafo precedente, troviamo. L'url del link viene qui
ad esempio, move_uploaded_ assegnato alla variabile
file ha rivelato il difetto di so- form. Potremmo migliorare l'e- lettura e/o scrittura, posizionando il $_GET['url']
vrascrivere, senza avvertire, i sempio (pagina puntatore all'inizio o alla fine del file.
file presenti nella cartella. Me- checkcan_plus.php) creando un Usando un sistema windows è La sezione PHP (in testa al
glio predisporre, quindi, un form (vedi listato 05) con una meglio usare sempre l'opzione codice sorgente della pagina
controllo in grado di verificare casella a discesa nella quale aggiuntiva “t” come “mode” per i file link.php) contiene il codice che
la presenza o meno di un certo siano presenti tutti i file della testo e “b” per i file binari. consente di scrivere nel file (li-
file nella directory esaminata. cartella “upload”: selezionan- fread ($handle, length); stato_06). Per prima cosa viene
La funzione è: done uno possiamo decidere di // legge il contenuto di un file controllato che esista
cancellarlo o di vederne alcune aperto dal descrittore $handle. Se $_GET['url'], il che vuol dire
file_exists ($nome); caratteristiche con la funzione length non è settato, il file viene che qualcuno ha cliccato su
// $nome comprende il percorso pathinfo (immagine 2). letto fino alla fine. uno dei link. Poi viene assegna-
di ricerca del file e il suo nome Vedendo il listato originale, fwrite ($handle, $content); to un nome al file di testo dove
noterete che sono state usate // scrive $content sul file aperto dal verranno registrati i dati per le
Potremmo anche desiderare @opendir e @unlink: nel prossi- descrittore $handle statistiche: scegliamo di dargli
cancellare un file presente in mo paragrafo vedremo a cosa fclose ($handle); un nome del tipo “annosetti-
una cartella: in questo caso la serve la @ davanti al nome di // chiude il file aperto dal mana.txt”, in modo da avere fi-
funzione da utilizzare è: una funzione. descrittore $handle le separati per ogni settimana
PHP consente di lavorare (usiamo le funzioni di data già
unlink ($nome); non solo con i file, ma anche Con poche nozioni siamo in viste nella lezione 1). Il succes-
// $nome comprende il percorso “sui” file: possiamo, infatti, grado di creare un paio di sivo ciclo if si occupa di defini-
di ricerca del file e il suo nome aprire e modificare i file scri- esempi interessanti. Supponia- re il descrittore $file e di aprire
vendo informazioni al loro in- mo di avere nel nostro sito una (eventualmente creare) il file
Un esempio concreto è pre- terno. Per questi scopi si usano pagina di link (immagine 3) e di annosettimana.txt, posizionan-
sente nella pagina checkcanc. una serie di funzioni specifi- voler sapere quali sono effetti- do il puntatore di scrittura al
php, attraverso la quale si può che: vamente cliccati e quante vol- termine del testo già inserito.
controllare se un file è presente te. Per avere queste informa- Mi occupo poi di definire la riga
nella cartella “upload” (ed $handle=fopen ($nome, mode); zioni può essere sufficiente da scrivere, inserendo il per-
eventualmente cancellarlo) // il descrittore $handle apre, scrivere su un file di testo delle corso del link, una tabulazione
semplicemente compilando il tramite la funzione fopen, un file in righe che contengano l'indica- (“\t”), la data e l'ora del click e,
2 3
Form per ricavare informazioni su un file e per cancellarlo Con PHP possiamo individuare i link più cliccati di una pagina
listato 06 listato 07
<?php $conteggio= fread($file,filesize($visite));
if (isset($_GET['url'])) { // assegno a $conteggio il valore che leggo nel file di testo
$nome_file = date("YW").".txt"; (dove c'è solo un numero)
// il file che verrà creato è del tipo annosettimana.txt, fclose($file);
if ($file=fopen($nome_file, 'at')) { $conteggio++;
// apro il file o lo creo. $file è il "descrittore"; il mode "a" serve // incremento il contatore
a posizionare il puntatore alla fine del file, il mode "t" serve per la $file = fopen($visite,"w");
modalità testo per Windows fputs ($file,$conteggio);
$ins = $_GET['url']."\t"; // scrivo il nuovo valore sul file eliminando il precedente
$ins.= date('d/m/Y H:i')."\n";
fwrite($file, $ins);
// scrivo la stringa $ins passando alla funzione fwrite 4
il descrittore
fclose($file);
// chiudo il file passando alla funzione fclose il descrittore
}
header("Location: ".$_GET['url']);
// indirizzo l'utente al link su cui aveva cliccato
}
?>
Il file testo ottenuto indica quali link risultano più visitati
per ultimo, l'indicazione di fine http://127.0.0.1/lezione_3/link.php? gnando il valore ad una varia- mo visto che possono rivelarsi
riga (“\n”). url=http://www.linux.org bile. Quindi, chiuso il file (è estremamente utili anche se,
Ora non ci resta che scrivere // scrive nel file di testo un link non buona norma tenere i file aper- per le loro caratteristiche, non
la riga con fwrite, chiudere il fi- compreso nella pagina originale ti il meno possibile), incremen- possono sostituire i database.
le con fclose e indirizzare il no- tiamo il valore trovato e riscri- Come al solito, per approfondi-
stro utente (in maniera del tut- Bisognerebbe dunque pre- viamo il file con questo nuovo re e conoscere tutte le funzioni
to trasparente per lui) verso il vedere dei controlli di inte- valore. Queste nuove operazio- filesystems di PHP bisogna leg-
link cliccato. grità, e senza dubbio un lavoro ni sono riportate nel listato 07. gere l'ottimo manuale di
Il file di testo ottenuto sarà migliore lo si otterrebbe regi- Ogni volta che la pagina conta- PHP.net; questo anche per evi-
del tipo visibile in immagine 4. strando i dati in un database. tore.php verrà caricata vedre- tare, magari chiedendo aiuto in
Adesso siamo in grado, con po- Ma questo lo impareremo nelle mo aumentare di una unità il un newsgroup, di sentirsi ri-
che modifiche al file originale, prossime lezioni; l'importante valore visualizzato. spondere con l'acronimo
di aggiungere a piacere tutta in questo frangente era solo di- Lavorare coi file può non es- RTFM, ossia “Read the f... ma-
una serie di informazioni come mostrare come non sia troppo sere sempre facile, ma abbia- nual!”.
il browser del visitatore e il suo difficile lavorare sui file con
indirizzo remoto. E adesso non PHP. 5
ci resta che analizzare il nostro Il secondo esempio (pagina
file settimanale delle statisti- “contatore.php”) consente di
che dei link. creare un rudimentale contato-
Certo questo è un buon si- re per le nostre pagine (imma-
stema, ma non è ottimale e in- gine 5), mantenendo memoriz-
fatti si presta a piccole “mano- zato il valore nel file di testo
missioni” esterne: ad esempio “conteggio.txt”.
si può aggiungere una riga al fi- Rispetto all'esempio prece-
le di testo anche senza cliccare dente, in questo caso dobbia-
su nessun link, semplicemente mo prima leggere il contenuto
scrivendo un URL del tipo del file conteggio.txt, asse- Un semplice contatore delle visite della pagina
6 I database
e tecnologie basate sui da- è certamente un database, in nate azioni (inserimento, recu- Il database system
L tabase (letteralmente “rac-
colte di dati”) giocano un
ruolo critico in tutte le aree fon-
quanto è una collezione di dati
aventi un significato implicito
(nome, indirizzo, telefono) e tra
pero, aggiornamento, cancella-
zione dati). Un libro, quindi,
non è un database, mentre lo è
La rappresentazione grafica
un ambiente di sviluppo “mo-
derno” di un database è visibile
damentali della nostra vita: loro correlati. Anche la pagina un dizionario. in figura 8. A valle, memorizzato
pensiamo, ad esempio, all'uso di un libro, però, potrebbe es- Un database può contenere in un qualsivoglia mezzo elet-
di database per consentire la sere vista come un database in più o meno dati ed essere più o tronico, c'è il database fisica-
gestione del nostro conto in quanto rappresenta una colle- meno complesso: pensiamo, ad mente esistente, composto dai
banca, per prenotare delle visi- zione di parole tra loro collega- esempio, alla nostra agenda te- dati e dalle informazioni sulla
te in ospedale, per verificare gli te. Così non è, dal momento lefonica e alla banca dati di un sua stessa struttura (meta-da-
esami effettuati all'università, che un database è considerato gestore di telefonia. Una base di ti).
per la gestione delle aziende tale quando ha queste pro- dati potrebbe essere gestita an- Per creare il DB, accedervi e
(coi software ERP) e via dicen- prietà: che manualmente, ma all'au- interrogarlo utilizzeremo un
do. • rappresenta uno o più aspetti mentare della complessità DBMS (DataBase Management
Ne sentiamo tanto parlare, del mondo reale (il cosiddetto avremo bisogno di un supporto Systems), ossia un'applicazio-
ma cos'è realmente un databa- “minimondo”); tecnologico e informatico per ne in grado di processare delle
se? Volendo semplificare al • è una collezione di dati logi- costruire ed utilizzare il DB, e richieste e di accedere ai dati in
massimo la definizione, possia- camente coerenti tra loro e coe- nel contesto di questo corso gli scrittura e lettura. MySQL è un
mo vederlo come una collezio- renti con la descrizione della strumenti scelti sono il databa- DBMS, come lo sono anche Mi-
ne di dati tra loro correlati, do- realtà scelta (non è, quindi, un se MySQL e PHP. Dal punto di crosoft Access e SQL Server,
ve per “dati” intendiamo dei va- insieme di dati messi a caso); vista informatico un database è PostgreSQL, Oracle e moltissi-
lori conosciuti che possono es- • è disegnato, costruito e po- assimilabile ad una tabella tipo mi altri programmi.
sere registrati e hanno un signi- polato per un certo gruppo di foglio elettronico, con i distin- Per utilizzare il DBMS, infine,
ficato implicito. Da questo pun- utenti interessati ad interagire guo che vedremo in un para- servirà un'applicazione in gra-
to di vista un'agenda personale con esso compiendo determi- grafo successivo. do di inviare una richiesta: po-
A
10
vantaggi offerti dalle basi si ed agli esami e dati relativi ai
di dati per il nostro sito, ci professori.
troviamo adesso nella neces- Il primo passo è realizzare lo
sità di creare un DB efficiente. schema concettuale: è uno
Fondamentale, ai nostri fini, è schema non utilizzabile diretta-
che il database non abbia infor- mente dal DBMS, ma fornisce
mazioni ridondanti (ossia non concetti vicini a quelli utilizzati
abbia duplicazioni di dati) per- da una persona nel percepire e
ché questo comporterebbe concettualizzare la realtà og-
spreco di memoria, minore effi- getto di studio (il minimondo). Lo schema concettuale: modello Entità-Relazione
cienza del sistema e la probabi- Useremo, data la sua diffusione
le introduzione di inconsisten- e la sua intuitività, il modello
ze e/o perdite di dati. Entità-Relazione proposto da dati registrati nell'entità (l'i- di E2 corrispondono (possono
Per ottenere questo risultato P. Chen nel 1976 (la figura 10 stanza). Ciò significa che non ci corrispondere) più istanze del-
si compiono delle operazioni riassume come rappresentare potranno essere due istanze l'altra entità coinvolta.
di modellizzazione allo scopo graficamente lo schema con- con lo stesso valore: questo at- Un esempio, con la rappre-
di esplicitare la struttura finale cettuale). Questo modello uti- tributo è detto chiave. Anche sentazione dei tipi di relazione
del DB che andrà creata col lizza come base il costrutto En- una relazione può contenere e degli attributi, è visibile inve-
DBMS scelto. Questo primo tità: rappresenta un oggetto degli attributi. ce in figura 11. Le entità coin-
passo, da fare anche con carta della realtà che, ai fini dell'ap- Ultimo sforzo è definire il vin- volte sono quattro (studente,
e penna, è forse il più noioso, plicazione di interesse, ha una colo di relazione tra due entità, piano studi, corso, professore)
ma è assolutamente importan- propria identità (è “distinguibi- vincolo classificabile con una di ed esemplificano i tre vincoli di
te e vale quanto detto in prece- le” dagli altri oggetti) ed ha una queste tipologie: relazioni previste:
denza: meglio dedicare molto esistenza fisica (es: studente, • 1:1 (uno-a-uno; one-to-one): • studente - inserisce - piano
tempo alle fasi progettuali piut- professore) o concettuale (es: ad ogni istanza di E1 corrispon- studi = relazione 1:1 -> ogni stu-
tosto di accorgersi alla fine del- corso, piano di studi). Ogni en- de (può corrispondere) una ed dente deve inserire un solo pia-
la necessità di modificare la tità è messa in relazione con al- una sola istanza di E2 e vice- no di studi, e ogni piano di stu-
struttura per renderla più effi- tre entità, da cui il nome dello versa; di deve essere riferito ad un so-
ciente. schema, allo scopo di definirne • 1:N (uno-a-molti: one-to- lo studente. In questo esempio
Come esempio di lavoro vo- le reciproche corrispondenze. many): ad ogni istanza di E1 abbiamo assunto che non vi
gliamo creare lo schema di un L'entità è accompagnata da una corrispondono (possono corri- siano piani di studi standard tra
database il cui scopo è memo- serie di attributi che ne descri- spondere) più istanze di E2, i quali uno studente possa sce-
rizzare i dati degli studenti uni- vono le proprietà elementari mentre ad ogni istanza di E2 gliere (la relazione sarebbe sta-
versitari: in particolare ci inte- (es: matricola, nome, data, vo- corrisponde (può corrisponde- ta 1:N)
ressa conoscere la situazione to), ed uno di questi attributi (o re) una sola istanza di E1; • studente - fa la tesi con - pro-
degli esami svolti, quindi do- la combinazione di due o più) • N:N (molti-a-molti; many-to- fessore: relazione 1:N -> ogni
vremo registrare dati relativi deve definire univocamente i many): ad ogni istanza di E1 o studente può (se ha concluso
gli esami) fare la tesi con un so- • per ogni relazione N:N si crea- 11
lo professore (il relatore ufficia- no tre tabelle corrispondenti
le), mentre ogni professore può alle due entità coinvolte ed alla
avere N tesisti. relazione che intercorre tra lo-
• studente - fa esami del - corso: ro. Quest'ultima tabella avrà co-
relazione N:N -> ogni studente me chiave primaria la combi-
può dare gli esami di N corsi, ed nazione delle chiavi delle altre
ogni corso può essere oggetto due tabelle.
di esami da parte di N studenti. Lo schema che ne esce è vi-
Terminato lo schema concet- sibile in figura 13. L'ultimo sfor-
tuale, per creare fisicamente il zo prima di avere uno schema
DB dobbiamo passare allo sche- efficiente si chiama normaliz-
ma logico il quale sarà imple- zazione: è un procedimento, in
mentabile direttamente nel più fasi, che interviene sulla
DBMS. Vi sono vari tipi di sche- struttura delle tabelle di un da-
ma, ma il miglior compromesso tabase e sui collegamenti tra es- Schema concettuale: un esempio di
tra qualità e semplicità è dato se. La trattazione approfondita modello Entità-Relazione
dal modello relazionale propo- del tema esula dal presente cor-
sto da E. Codd (primi anni '70). so, ma vale la pena accennare a
Il modello si basa, semplice- tre consigli previsti dalle Forme 12
mente, su un unico costrutto Normali.
detto relazione. Questa relazio- Il primo prevede di usare in
ne è una tabella (useremo da tutte le tabelle attributi univoci
adesso questo termine per non (non ripetuti) e semplici (non
ingenerare confusione con lo composti). Questo vuol dire
schema concettuale) con le se- che un'ipotetica tabella “stu-
guenti caratteristiche (figura denti” non deve mai compren-
12): dere una serie di colonne del ti-
• un numero prestabilito di co- po Esame1, Esame2... EsameN
lonne (detti anche campi o at- (l'attributo è sempre Esame, e
tributi) di cui va stabilito il tipo non va mai ripetuto), né deve
di valori (testo, numerico, ecc) comprendere un campo Esame Esempio di una relazione (tabella) nel modello Relazionale
e il loro eventuale dominio; se all'interno di questo voglio
• un numero variabile di righe registrare più di un dato (es: co-
(dette anche record o tuple o dice esame, votazione, data, rire, come anagrafica, nella ta- to scritto, il nostro DB è già
istanze); professore). In entrambi i casi bella Studenti: questi campi di- molto affidabile ed efficiente,
• uno o più campi formeranno va prevista la creazione di una pendono solo dal Comune di re- ed è pronto per essere inserito
la chiave primaria della tabella, tabella da legare a quella stu- sidenza indicato, non dalla ma- nel DBMS.
il cui valore identificherà uni- denti: in effetti è quello che ab- tricola dello studente che è la Nella prossima puntata ve-
vocamente un record. biamo fatto nel nostro esempio. chiave della tabella. Anche in dremo come creare il DB con
In linea di massima si potrebbe Il secondo consiglio è di questo caso va prevista una ta- MySQL e come compiere le
anche pensare di costruire un creare una nuova tabella cui fa- bella esterna che leghi un Co- operazioni di inserimento, ag-
DB con una sola grandissima re riferimento se siamo costret- mune al suo CAP ed alla Pro- giornamento e cancellazione
tabella, ma questo manifeste- ti ad inserire continuamente va- vincia di appartenenza. imparando ad usare il linguag-
rebbe immediatamente proble- lori ripetuti. Un esempio banale Un altro accorgimento, di gio universale di interrogazione
mi di ridondanze e anomalie. Il potrebbe essere il dipartimento buon senso, è di non memoriz- delle base di dati: SQL, ovvero
modello di Codd, per evitare di appartenenza di un profes- zare mai dati che possano es- lo Structured Query Language.
questo, si basa sulla teoria ma- sore: a forza di inserire il nome sere calcolati, quindi mai regi- Infine vedremo come usare
tematica dei sistemi e per ga- del dipartimento rischiamo di strare un campo “Età” se si ha a PHP per interfacciarsi con My-
rantire l'integrità e le coerenza commettere errori di digitazio- disposizione l'anno di nascita. SQL e portare su Web i risultati
dei dati vi sono delle regole ne pregiudicando ricerche fu- Se abbiamo rispettato quan- delle operazioni compiute.
aventi lo scopo di creare N ta- ture, e inoltre se un diparti-
belle, più piccole possibili, da mento cambiasse nome do- 13
mettere in collegamento tra lo- vremmo modificare uno a uno STUDENTE PIANO STUDI
ro attraverso i valori delle chia- tutti i valori già inseriti. 1
Matricola Codice
vi. Per passare dallo schema Meglio, quindi, creare una ta-
Nome
1 Presentato il
concettuale a quello logico si bella “Dipartimenti” cui fare ri-
usa un algoritmo di “traduzio- ferimento: in questo modo non Cognome
ne” (mapping): ci sarebbero errori di inseri- Città
• per ogni relazione 1:1 si crea- mento, l'aggiornamento verreb- 1
Codice piano
no due tabelle corrispondenti be fatto in un unico punto ed N
alle entità coinvolte. Tra i cam- automaticamente propagato a In tesi con ESAME
N
pi di una delle due tabelle si ac- tutti i record interessati della Matricola
clude, come chiave esterna, la tabella Professori. Codice corso
N
PROF CORSO
chiave dell'altra tabella; Ultimo consiglio è di non in-
• Per ogni relazione 1:N si crea- serire in una tabella dei campi C.F. Data Codice corso
1 Voto 1
no due tabelle corrispondenti che non siamo direttamente di- Nome Anno
alle entità coinvolte. Tra i cam- pendenti dai campi chiave del- Cognome Aula
pi della tabella del ramo N si ac- la tabella stessa. Un esempio Schema logico: esempio di modello
Città relazionale con indicazione degli Orario
clude, come chiave esterna, la possono essere i campi CAP e attributi di ogni tabella
chiave della tabella del ramo 1; Provincia che potremmo inse-
1 MySQL e PHP
a terza lezione del corso ci è Per queste operazioni usere-
IL CALENDARIO DELLE LEZIONI
L servita per imparare i con-
cetti fondamentali relativi
alla costruzione di un database
mo MySQL, le istruzioni SQL
(Structured Query Language) e
il linguaggio PHP che ci forni-
Lezione 1:
- PHP con un server off line
- Il database system
- Siti Web dinamici
efficace ed efficiente. Prenden- sce adeguati strumenti di in- - Funzioni base e variabili - Teoria dei database
do spunto da un caso reale terrogazione e gestione remota - I costrutti di controllo
(creare una base di dati per me- del DB. Lezione 4:
morizzare la carriera universi- Se qualcuno ha avuto diffi- Lezione 2: - PHP e MySQL
taria di uno studente), abbiamo coltà ad installare o configura- - Approfondiamo PHP - MySQL, database
visto come costruire uno sche- re i programmi citati nelle scor- - Include e require opensource
ma concettuale ed il conse- se puntate e quelli introdotti in - Funzioni e classi - Costruzione e interrogazione
guente schema logico, tenendo questa lezione (come Apache, - Proteggere una pagina di un database: il linguaggio
conto delle tecniche di norma- PHP, MySQL e PhpMyAdmin), - Cookie e sessioni SQL
lizzazione per garantire l'inte- provi a fare riferimento al sito - La funzione mail - Interfaccia GUI: PhpMyAdmin
grità del database e la rilevanza easyPHP (http://www.ea- - Integrazione MySQL e PHP
dei dati. Quanto descritto ha syphp.org). Questo sito, di ori- Lezione 3: PHP e i database
validità assolutamente genera- gini francese e tradotto anche - La funzione upload La prossima puntata
le: adesso, però, è il momento in lingua italiana, è chiaro e ag- - Lavorare con i file
di implementare i nostri schemi giornato e fornisce in un unico - La gestione degli errori Lezione 5: Gestire un sito
su un DBMS e rendere interatti- pacchetto autoinstallante i pro- - Accenni di sicurezza dinamico con PHP e MySQL
va la nostra base di dati. grammi citati.
L se di dati va implementato
utilizzando un DBMS (Data-
base Management System), il
dese TcX (ora MySQL AB), una
società cui serviva un DB velo-
ce, flessibile e affidabile. Non
luzioni interne ad un'attività,
ad esempio per gestire la con-
tabilità, le spedizioni, le buste
di MySQL. Scari-
sono sul CD
chiamo da http://dev.mysql.
com/downloads/ l'ultima ver-
componente software che con- trovandolo tra i prodotti esi- paga o semplicemente per or- sione stabile di MySQL databa-
sente di operare i processi di stenti, i progettisti svedesi de- dinare una volta per tutte la se server and standard clients
definizione, costruzione e ma- cisero di crearselo distribuen- propria infinita collezione di li- per Windows (disponibile an-
nipolazione del database. dolo poi con licenza GPL (vedi bri. Il simbolo di MySQL è il del- che nel CD Guida 1 nella cartel-
Per il corso, coerentemente riquadro “Licenza GPL e licen- fino Sakila, per cui tuffiamoci la PDF\Corsi\PHP) e procedia-
con la scelta opensource effet- za commerciale di MySQL”). Il nel processo di installazione mo come al solito. Il processo è
tuata nelle lezioni precedenti, è risultato è un sistema in grado del software e nella creazione totalmente automatico se si ac-
stato scelto MySQL, un RDBMS di gestire con efficienza e sicu- del nostro primo database. cetta di installare il programma
libero (free) distribuito con li- rezza enormi moli di dati, con sulla cartella predefinita c:/my-
cenza GPL, basato sullo stan- una velocità di esecuzione di Installazione e avvio sql: approfittiamo di questa op-
dard SQL e disponibile per am- tutto rispetto. Ci sono ancora del server portunità lasciando l'alternati-
bienti Linux, Macintosh e Win- dei passi da fare per rendere MySQL è un cosiddetto da- va a chi voglia perdere qualche
dows. L'acronimo non è sba- MySQL veramente completo tabase server, e quindi per po- minuto in più per il settaggio
gliato: la R indica la parola “Re- (vedi “il futuro di MySQL” più ter funzionare necessita non successivo del file my.ini.
lational” a sottolineare come avanti nell’articolo), ma co- solo del software installato ma Terminata l'installazione fac-
MySQL (così come Postgre- munque le caratteristiche di anche di un server attivo (Apa- ciamo doppio clic sul file c:/my-
SQL, MS Access, Oracle e altri) questo database ne fanno un che, IIS, Xitami e via dicendo). sql/bin/winmysqladmin.exe per
sia un DBMS basato sul con- punto di riferimento assoluto Il nostro server è già impostato avviare per la prima volta il no-
cetto basilare di relazione tra del settore. Non solo sul Web, (vedi prima lezione), quindi stro server MySQL. Ci verrà
tabelle. dove è uno dei principali attori, concentriamoci sulla parte di chiesta una coppia user-pas-
4a lezione
sword: possiamo anche la- appena effettuata ci mette a di- del sistema, la persona cui è
sciarla in bianco dal momento
che questi parametri servono
sposizione un client con una
spartana interfaccia a caratte-
concesso il controllo assoluto
di MySQL, è l'utente root. Win-
Licenza GPL
solo in caso di amministrazio- ri, addirittura lanciata attra- dows crea automaticamente e licenza
ne remota del server MySQL. A verso una finestra DOS. quattro profili identificati da
questo punto avremo accesso La cosa non è così strana co- user, password e server di pro- commerciale
al pannello di gestione, rappre-
sentato da una icona a forma di
me potrebbe sembrare a prima
vista: MySQL, infatti, è un'ap-
venienza (localhost e remoto).
I profili, tutti generati senza
di MySQL
semaforo posta nella traybar plicazione server e l'interfaccia password predefinite, sono: La licenza GPL (GNU General
(immagine 1). Se il semaforo è client a caratteri consente di la- Public License) è la base del
verde, siamo pronti a creare il vorare con qualsiasi computer - root connesso da localhost: tutti sistema GNU/Linux e del
nostro primo database. indipendentemente dalle inter- i privilegi; software libero. Compilata da
facce grafiche installate e per- - root connesso da remoto: tutti Richard Stallman, questa licenza
1 mette di inviare facilmente co- i privilegi; impone, tra le altre cose, di
mandi via telnet da un compu- - utente anonimo connesso da ridistribuire liberamente il codice
ter collegato in rete. Inoltre ga- localhost: tutti i privilegi previsti per i sorgente di un programma che
Il semaforo verde conferma l'attivazione rantisce velocità e flessibilità, database presenti nel server; sia basato tutto, o in parte, su
del server MySQL chiedendo solamente di cono- - utente anonimo connesso da remoto: del codice soggetto a licenza
scere pochi comandi e le basi privilegi da assegnare. GPL. È il cosiddetto “effetto
Cliccando col tasto destro del linguaggio SQL. virale” (ossia contagioso) della
del mouse sul semaforo e sce- Naturalmente ci sono molte Questa configurazione è ac- licenza GPL. Dal 2001 MySQL
gliendo show me si apre la fine- interfacce grafiche già pronte cettabile finché usiamo il DB in AB, società che detiene i diritti
stra di gestione: potremo vede- (una la vedremo tra poco) per locale e lo curiamo solo noi, ma di MySQL ha deciso di fornire il
re sulla linguetta Environment semplificarci la vita, però al- è chiaramente pericolosa nel DB con una duplice licenza: GPL
(immagine 2) l'indirizzo IP lo- meno una volta è opportuno momento in cui al DB avessero e commerciale.
cale del nostro server (lo stes- utilizzare lo strumento di de- accesso altre persone o quan- La versione commerciale (a
so di Apache o IIS) e sulla lin- fault fornitoci, per capire le rea- do fosse messo in rete. La rac- pagamento) serve appunto a
guetta my.ini Setup i valori del li potenzialità di MySQL senza comandazione, quindi, è di superare il vincolo di libera
file my.ini: la riga che più ci in- farci distrarre da nessun aspet- cancellare subito l'utente ano- redistribuzione del codice:
teressa è la datadir che ci forni- to grafico. nimo connesso da localhost, chiunque, pertanto, desideri
sce il percorso di registrazione Sulla barra di Windows clic- assegnare le password a root e usare MySQL per applicazioni di
dei dati (utile saperlo per un chiamo su Start, Esegui e scri- creare degli utenti reali cui as- cui non vuole rendere pubblico il
backup). Sempre grazie al no- viamo cmd per aprire una con- segnare i privilegi voluti. codice sorgente dovrà
stro semaforo potremo ferma- sole DOS. Al prompt scrivia- Il manuale che si trova nella acquistare una licenza
re e far ripartire il servizio che mo: cd mysql\bin per portarci directory di installazione commerciale da MySQL AB.
presiede al funzionamento del sulla cartella di sistema di My- (C:\mysql\Docs\manual.html)
server MySQL. In alternativa SQL. è molto completo (salvato co-
per compiere la stessa opera- MySQL è studiato per appli- me file PDF occupa quasi 1.300 vizio. Ad esempio per fermare
zione possiamo usare l'utility cazioni client-server, quindi, pagine di formato A4) e si ri- il server si può scrivere:
Servizi che abbiamo a disposi- per motivi di sicurezza, utilizza manda alle pagine specifiche mysqladmin -u root -p shutdown
zione in Pannello di controllo, la gestione dei profili di acces- per queste operazioni. Per le (viene chiesta la password di root per
Strumenti di amministrazione. so degli utenti: a seconda delle esigenze didattiche di questo rendere effettiva l'istruzione)
autorizzazioni concesse (i co- corso vediamo però come in-
Client e sicurezza siddetti “privilegi”) gli utenti serire la password “pluto” per Useremo invece l'istruzione
Il server MySQL è stato av- potranno, ad esempio, solo fa- l'utente root (connesso da lo- mysql per aprire il client e agi-
viato, ma da solo non basta: re la gestione dei dati di data- calhost, ossia dal nostro server re sul database prescelto se-
per la gestione e per tutte le base specifici oppure creare interno) scrivendo questa riga condo quanto previsto dai no-
operazioni inerenti i database nuovi database ma senza poter (dalla console DOS): stri privilegi di accesso. Per
abbiamo infatti bisogno di uti- accedere ad altri oppure solo mysqladmin -u root -p password pluto collegarci scriviamo:
lizzare un client. L'installazione inserire dati. L'amministratore (verrà chiesto di inserire la password mysql -u root -p
vecchia: era vuota quindi basta solo
2 premere invio) e inseriamo la password. Se ci
troviamo di fronte un prompt
Fermiamo e facciamo ripar- (immagine 3) del tipo:
tire il server MySQL per carica- mysql>
re i nuovi privilegi. Da adesso
ci collegheremo al server e al Siamo pronti a gestire un da-
client MySQL con l'identità di tabase. Il client accetta due tipi
root e la password inserita. di inserimenti: comandi MySQL
o istruzioni SQL (da conclude-
Le prime istruzioni re sempre con un segno di pun-
Utilizzeremo l'istruzione my- to e virgola “;”). I comandi My-
sqladmin per compiere opera- SQL sono relativamente pochi
zioni “una tantum” che interes- (scrivere help per vederli) e ci
sano il server nella sua genera- interessano in particolar modo
lità: interrogazioni sullo stato, USE (per agire su un database
cambiare password, ma anche specificato) e QUIT (per uscire
creare e distruggere database dal client). Alle istruzioni SQL è
(cosa possibile anche utiliz- invece dedicato il prossimo pa-
I pannelli di configurazione del tool WinMySQLadmin zando il client) o fermare il ser- ragrafo. Come esempio scrivia-
4a lezione
3 4
bug di alcune versioni (la 4.0.13 INSERT INTO tabella VALUES mento alla tabella “prof” non cando una condizione da ri-
ad esempio) la password di (campo_1, campo_2, ...); esistente. La stessa cosa acca- spettare per cancellare la riga o
root (la nostra “pluto”) in que- de se, al momento di registrare le righe in questione:
sta istruzione va inserita im- La differenza tra le due istru- il voto di un esame, inseriamo DELETE FROM tabella [WHERE
mediatamente dopo l'opzione zioni è che la prima consente di una matricola errata o un codi- condizione];
“-p” senza spazi intermedi. In indicare (nell'ordine che prefe- ce di un corso inesistente. Que- (la clausola where è opzionale: se c'è
generale è sempre comunque riamo) solo i campi che voglia- sto, è dovuto al mancato sup- vengono cancellati solo i record che
possibile inserire la password mo effettivamente riempire porto dell'integrità referenziale rispettano la condizione, altrimenti
in questo modo in ogni istru- con dei valori (gli altri saranno delle tabelle MyISAM. vengono cancellati tutti i record della
zione di comando dalla shell completati in accordo con le Se volessimo avere questo tabella)
del DOS. Se la versione che ave- caratteristiche definite per i supporto avremmo dovuto de-
te installato è esente dal bug, campi della tabella), mentre la finire tutte tabelle (ogni tabella Ad esempio se volessi can-
fate a meno di inserire la pas- seconda istruzione ci impone ci sono riferimenti a valori di cellare tutti gli studenti di co-
sword sulla riga di comando, di scrivere tutti i valori dei chiave esterni) utilizzando il gnome “Rossi”, l'istruzione
scrivendola invece solo quan- campi di un record (comprese “type” InnoDB e i comandi FO- sarà:
do richiesto come visto in pre- quindi stringhe vuote, valori REIGN KEY - REFERENCES di mysql> DELETE FROM studente
cedenza. Altri comandi che po- null o predefiniti) esattamente SQL: WHERE cognome=”Rossi”;
tremmo scrivere sono: nell'ordine in cui è costruita la mysql> CREATE TABLE studente
tabella. L'utilizzo dell'una o del- (matricola CHAR(8) NOT NULL, nome La modifica dei dati può es-
mysqldump -u root -ppluto -d l'altra istruzione dipende dal VARCHAR(30) NOT NULL, cognome sere fatta su tutti i record di
universitas studente corso > tipo di inserimento che dob- VARCHAR(30) NOT NULL, data_nascita una tabella o su delle tuple se-
universitas_parz.sql biamo fare. DATE, tesi_con CHAR(13), PRIMARY lezionate con un'apposita con-
(backup dei soli dati delle tabelle Poniamo di voler inserire un KEY(matricola), INDEX (tesi_con, dizione:
'studente' e 'corso' del database valore nella tabella studenti: cognome, nome), FOREIGN KEY UPDATE tabella SET campo_1=
“universitas”: il file creato è mysql> INSERT INTO studente SET (tesi_con) REFERENCES prof(cod_fisc)) aggiornamento_1, campo_2=
“universitas_parz.sql”. L'opzione -t cognome=”Rossi”, nome=”Antonio”, TYPE=INNODB; aggiornamento_2, ... [WHERE
avrebbe fatto il backup della sola matricola=”912345IG”, (il riferimento alla tabella prof è dato condizione];
struttura senza i dati. Va inserita la data_nascita=”19780427”; con l'istruzione FOREIGN KEY: bisogna (la clausola where è opzionale e serve
password di root) (ho inserito nella tabella studente, però ricordare di indicare il campo a restringere il numero di record da
nell'ordine che volevo, solo i dati cui “tesi_con” anche negli indici) aggiornare)
mysql -u root -p universitas < volevo attribuire un valore. Svantaggio
universitas_db.sql è che devo ricordare i nomi corretti dei Così facendo siamo obbliga- Un esempio potrebbe essere
(ripristino o inserimento, nel database campi) ti ad inserire nel campo “te- un cambio del professore con
già creato “universitas”, delle tabelle si_con” un valore già presente cui fare la tesi da parte di uno
oggetto di backup contenute nel file Equivalente sarebbe stata l'i- nella tabella “prof”. A titolo di studente ben preciso, identifi-
“universitas_db.sql”. Le tabelle non struzione: esempio, nel CD trovate il file cato con la sua matricola:
vengono sovrascritte) mysql> INSERT INTO studente VALUES universitas_innodb.sql che con- mysql> UPDATE studente SET
(“912345IG”, “Antonio”, “Rossi”, tiene la struttura del database tesi_con=”BBBCCC52B41A123B”
Eseguendo l'ultima istruzio- “19780427”, null); costruita con tabelle InnoDB e WHERE matricola=”123456IG”;
ne avrete il vostro database uni- (qui avrei dovuto inserire tutti i valori tutte le integrità referenziali ri-
versitas completo della struttu- nel giusto ordine, compreso l'ultimo spettate. Caricando queste ta- Altro esempio: supponiamo
ra di tutte le tabelle e pronto ad valore null perché questo studente belle si noterà l'impossibilità di di dover trasformare tutti i vo-
essere gestito. Se il file universi- ancora non è in tesi con alcun caricare dati non coerenti con ti (al momento espressi in tren-
tas_db.sql non fosse nella car- professore. Il vantaggio in questo caso quanto definito in termini di tesimi) in voti centesimali. Ba-
tella “bin” di mysql (quella dove è che non devo inserire i nomi dei integrità referenziale. Lo spazio sta una modifica su tutta la ta-
ci troviamo per eseguire il co- campi) occupato dalle tabelle, però, bella “esame” (immagine 7):
mando), andrà indicato il per- aumenta considerevolmente e mysql> UPDATE esame SET
corso assoluto completo (ad Chiaramente se tentassimo calano le performance di velo- voto=voto*10/3;
esempio: D:\backup\mio\uni- di inserire una matricola (cam- cità.
versitas_db.sql). po chiave) già esistente ci ver- Torniamo al DB con tabella Esiste poi anche il comando
Da questo momento in poi rebbe segnalato un errore (im- MyISAM: il file universitas_da- REPLACE che combina le ca-
daremo per scontato di essere magine 6). Notiamo che l'inse- ti.sql contiene dei valori di ratteristiche di INSERT e UP-
connessi al client MySQL e di rimento della data va fatto nel esempio da caricare per popo- DATE e quindi può fare al con-
trovarci nel database universi- formato corretto (AAAAMM lare il database. Carichiamo tempo funzioni di inserimento
tas (istruzione use universitas). GG) e che ad un eventuale pro- questo file come abbiamo già e aggiornamento.
fessore con cui si fa la tesi ci si imparato e proseguiamo la le-
La gestione dei dati deve riferire tramite il codice fi- zione. Interrogazione
Il database è adesso solo scale, ossia il campo chiave La cancellazione dei dati di dei dati (query)
uno scheletro vuoto, ma que- della tabella “prof”. una tabella può essere fatta in L'interrogazione (query, dal
sta era la parte più difficile. Ge- Non ci viene dato errore se maniera “completa” ossia can- verbo “to query” = interroga-
stire i dati è, al confronto, un'o- inseriamo nel campo cellando tutti i record oppure, re) del database è senza dub-
perazione piuttosto agevole e “tesi_con” un valore di riferi- ed è il caso più frequente, indi- bio l'operazione più utilizzata
vedremo come fare l'inseri- nella gestione di un database,
mento, la cancellazione la mo- 6 ed è al contempo facile e com-
difica dei medesimi usando plessa. La facilità deriva dalla
sempre le istruzioni SQL. strutturazione dell'interroga-
L'inserimento può essere fat- zione standardizzata da SQL,
to in più modi: mentre la sua complessità de-
riva dalla strutturazione rela-
INSERT INTO tabella SET campo_1= zionale della base di dati che ci
valore_1, campo_2=valore_2,...; MySQL ci indica un errore se tentiamo di inserire due studenti con la stessa matricola impone spesso di dover estrar-
4a lezione
F ti di universalità, abbiamo
usato l'interfaccia a caratte-
ri per agire su MySQL, però in
contenente $cfg['PmaAbsolu-
teUri'] e dopo il segno di ugua-
glianza indichiamo il percorso
partire per fare praticamente
tutto quello che vogliamo (se
ne abbiamo i permessi) su da-
ottimizzare le tabelle della ba-
se di dati.
PhpMyAdmin è un ottimo
certe occasioni un'interfaccia da raggiungere tramite server: tabase, tabelle e singoli dati. strumento e vale sicuramente
grafica può aiutarci a compiere $cfg['PmaAbsoluteUri'] = Possiamo inserire i privilegi de- la pena usarlo per applicazioni
certe operazioni di cui, magari, 'http://127.0.0.1/phpMyAdmin'; gli utenti, esportare e importa- interne, ma ricordate che il vo-
non ricordiamo perfettamente (o http://localhost/phpMyAdmin o ...) re database salvati in formato stro provider potrebbe fornirvi
la costruzione. .sql o .zip, scrivere query aiu- un'interfaccia grafica diversa, o
Introduciamo quindi una uti- Poi immediatamente dopo tati dalla grafica, inserire, mo- addirittura non fornirvela af-
le GUI (Graphic User Interface) cerchiamo dificare e cancellare dati, con- fatto.
rilasciata sotto licenza GPL e $cfg['Servers'][$i]['host'] trollare lo stato del server My- Per tutte le opzioni di confi-
totalmente scritta in PHP per SQL, vedere l'ingombro delle gurazione, veramente molte, si
interagire con MySQL: e scriviamo l'indirizzo IP del tabelle e la loro velocità di ri- rimanda al manuale fornito col
PhpMyAdmin. nostro server MySQL interno: sposta, e agire anche su dei co- programma.
L'installazione non compor- $cfg['Servers'][$i]['host'] = “localhost”
ta problemi: è sufficiente, infat- (o 127.0.0.1 o ...) 12
ti, scompattare il file zippato
(lo trovate nel CD oppure su e poi di fianco a
http://www.phpmyadmin.net/h $cfg['Servers'][$i]['auth_type']
ome_page/) in una cartella che
chiameremo “phpMyAdmi” da scriviamo:
porre nella “Document Root” $cfg['Servers'][$i]['auth_type'] = ”http”
del server Apache (ossia dove
finora abbiamo posto le nostre A questo punto apriamo il
pagine PHP per verificarle off-li- nostro browser preferito e scri-
ne, la cartella dove il nostro viamo l'indirizzo dove è instal-
server va a leggere quando sul- lato phpMyAdmin: sarà qual-
la barra dell'indirizzo scrivia- cosa del tipo http://127.0.0.1/
mo, ad esempio, http://lo- phpMyAdmin.
calhost o http://127.0. 0.1). Si aprirà una finestra di ri-
Per far funzionare phpMyAd- chiesta di accesso. Indicando
min entriamo nella cartella di user e password (quelle di root
installazione tramite Gestione o quelle di un utente preceden-
Risorse e apriamo, con un qual- temente creato) avremo acces-
siasi editor di testo, il file con- so al pannello di controllo (im- Il pannello di controllo di PHPMyAdmin
Connessione al server
schema logico generale e infine vremmo prima spiegare loro gli zando SQL; MySQL
all'implementazione fisica al- schemi alla base della costru- • utilizzare i record risultato È piuttosto semplice effet-
l'interno del Relational DBMS zione della base di dati. per comporre informazioni tuare la connessione al server
scelto per ospitare i dati. Siamo Risolvere questi problemi e/o pagine Web; MySQL che ospita il nostro da-
in grado di popolare il database equivale a fare l'ultimo passo • fornire un facile sistema di ge- tabase Universitas. Sono ri-
e di gestire aggiornamenti, can- verso l'ambiente “globale” de- stione al web content. chiesti tre parametri: indirizzo
cellazioni e interrogazioni an- scritto nella lezione 3 e quindi del server MySQL, user e pas-
che di una certa complessità. creare un completo Database PHP è un linguaggio forte- sword di un utente (root o al-
Il problema è che solo noi System. Per fare questo dob- mente votato al connubio con tro):
siamo in grado di farlo, e co- biamo unire le potenzialità di un database e può dare una mysql_connect (server, user,
munque non è sempre facile ri- PHP a quelle di MySQL, allo marcia in più al Web. PHP, inol- password);
cordare tutti i passaggi. Ma se scopo di creare delle soluzioni tre, non è “sposabile” solo con
ci fossero, ed è assolutamente user-friendly di gestione del da- MySQL: potremo altrettanto fa- In caso di successo la fun-
normale sia così, altre persone tabase. Nel caso particolare del cilmente usarlo per interfac- zione restituisce un identifica-
coinvolte nella gestione della nostro corso, il Web developer ciarci con database come DB2, tivo di connessione che ri-
base di dati? E se dovessimo PHP dovrà essere in grado di: Firebird, MSSQL, Oracle, Post- marrà invariato fino alla chiu-
usare i dati “grezzi” estratti da greSQL, Sybase e anche, trami- sura della stessa, mentre in ca-
MySQL per fornire informazioni • creare un database efficiente te i driver ODBC, con Microsoft so negativo viene restituito un
a degli utenti esterni? Non pos- o comunque capirne il fun- Access. valore false.
4a lezione
Effettuata la connessione al
server, si deve indicare su qua- listato connessione_prima.php
le database vogliamo agire. <?php //Creo una connessione con il database universitas
Con l'interfaccia a caratteri si $nome_db = "universitas"; $id_connessione=@mysql_connect("127.0.0.1","root","pluto") or die("Non è possibile
usava il comando use, mentre accedere al server");
con PHP utilizziamo: // mysql_connect apre la connessione al server, e mysql_select_db la sfrutta per accedere ad uno specifico database
mysql_select_db (nome_db, @mysql_select_db($nome_db,$id_connessione) or die(“Non è stato possibile accedere al database”);
identificativo di connessione); ?>
4 Il database
a prima operazione da cettuale Entità-Relazione (vedi mo una gestione che non ne- temente dalla struttura definita
definizione della struttura della to. Le entità non sono molte: i finite relazioni con altre Entità: • amministrazione: nome (chiave),
base di dati da realizzare. commenti, le aree, gli argo- chi amministra, infatti, sovrin- user, password, e-mail
Come visto nella lezione 3, si menti e i giornalisti. Non ci so- tende tutte le attività e pertan- • mailing: nome, e_mail (chiave)
deve definire uno schema con- no le immagini: per loro usere- to non è legato direttamente a • testi_admin: id_testo (chiave),
nessuna. descrizione, testo
A Dallo schema concettuale
deriva lo schema logico (figura Costruire il DB è un ottimo
1 N B) in cui è indicata la composi- esercizio (lezione 4), comun-
Giornalista scrive Commento zione di ogni tabella. I campi que nel CD allegato alla rivista
N chiave sono in grassetto, men- è presente il file commenti.sql
tre i campi con l'asterisco rap- che contiene la struttura com-
presentano una colonna che, pleta del database e alcuni da-
su pur non essendo chiave, con- ti di esempio. Aprendo il file
tiene solo valori numerici unici con un editor di testo si può ve-
ed è quindi utilizzabile come ri- dere nel dettaglio la struttura
1 ferimento esterno per altre ta- ed i tipi di dato di ogni tabella.
N 1 belle. Nello schema finale man- Se scegliamo di caricare il fi-
Argomento appartiene Area cano alcune tabelle che, pur fa- le, creiamo prima il database
cendo parte del database, pos- Commenti, quindi importiamo
siamo definire di servizio gene- struttura e dati usando gli ap-
Lo schema Entità-Relazione del database Commenti rale al sito e sono quindi dota- positi comandi di PhpMyAd-
te di vita propria indipenden- min (vedi immagine 1 e imma-
5a lezione
1 2
Creiamo il database Commenti Azioni per importare struttura e dati nel database Commenti
<a href='pagine/commenti.php? zione (il nome della pagina in in un array $list che ha come stro caso la precedenza è dal-
comm=".$tab_3[2]."' class='art'>". cui ci troviamo sarà scritto in chiave l'identificativo univoco l'alto in basso:
$tab_3[0]."</a> <span grassetto e non sarà cliccabi- dell'argomento e come valore il • $_GET[comm]=x : verrà vi-
class='normale'>[".$tab_3[1]."] le). conteggio appena fatto. Sfrut- sualizzato (testo e immagini)
</span>"; Il menu di navigazione a si- tando questo vettore posso ri- il commento avente identifi-
listato 6: index.php nistra segue la logica vista nel- cavare anche quanti commenti cativo x;
la costruzione della home pa- ci sono in ogni area (creo il vet- • $_GET[arg]=y : visualizzazio-
Ultima annotazione: l'estra- ge. Le differenze riguardano tore $tot_area) facendo una ne della lista dei commenti
zione di un solo record è con- l'aggiunta, a fianco di ogni scrit- semplice somma durante il ci- che fanno parte dell'argo-
sentita dalla clausola LIMIT ta, di una icona col segno “+” e clo while che visualizza gli ar- mento di codice y;
presente nel codice SQL: del numero di commenti con- gomenti di ogni area. I valori • $_GET[area]=z : visualizza-
tenuti in ogni argomento. Clic- appena ricavati serviranno poi zione della lista dei commen-
LIMIT (X,Y) cando sull'icona + si ottiene la per creare le sottopagine di ti che fanno parte dell'area di
lista dei commenti ordinata ogni scelta. Sommando tutti i codice z;
Questa clausola limita il ri- dall'articolo più letto al meno valori dell'array (con la funzio- • nessuna della variabili prece-
sultato ottenuto dall'esecuzio- letto: questo è reso possibile ne PHP array_sum) posso an- denti: viene visualizzata la li-
ne della query, estraendo Y re- dall'aggiunta della variabile che ottenere il numero totale di sta completa dei commenti.
cord a partire dalla posizione X GET di nome “ord” e valore documenti pubblicabili pre- Altre due variabili possono
dei record estraibili. “plus” nel riferimento del link. senti nel database. trovarsi nell'URL e sono affian-
La pagina “biblioteca dei Cliccando sulle scritte, invece, cate alle precedenti:
commenti” (file pagine/com- questa variabile non è presente // conto quanti record ci sono • $_GET[pg]=w : viene visua-
menti.php, immagine 4) sarà in- e si otterrà una lista ordinata raggruppandoli per id_argomento, e lizzata la sottopagina w (se
vece composta da: per data di inserimento decre- registro il numero nel vettore $list non c'è vuol dire che non ci
• una barra di navigazione per scente. Ecco i due link a con- sono sottopagine);
spostarsi tra le pagine; fronto: $sql_3="SELECT id_argomento, • $_GET[ord]=plus : ordina-
• un menu di navigazione divi- COUNT(*) AS num FROM commento mento dall'articolo più letto
so per aree tematiche, a loro echo “<a WHERE commento.pubblicabile='si' al meno letto.
volta suddivise per argomen- href='commenti.php?area=".$tab_1[id GROUP BY id_argomento"; Cosa succede quando nel-
ti con l'indicazione del nume- _area]."&ord=plus'><img $ris_3=mysql_query($sql_3); l'URL c'è la variabile “comm”?
ro di articoli inseriti; src='../servizi/bluplus.gif' alt='Più while ($tab_3=mysql_fetch_array Con una query estraiamo i dati
• un'area di visualizzazione: letti' title='Ordina per i più ($ris_3)) { che ci servono, quindi “stam-
cliccando sul nome di un'area letti'></a> <a $list[$tab_3[id_argomento]]=$tab_3 piamo” questi dati per visualiz-
o su un argomento si potrà href='commenti.php?area=".$tab_1[id [num]; zare l'articolo (immagine 5).
vedere la lista dei commenti, _area]."' } Può essere interessante osser-
lista limitata a 5 commenti class='tit'>".$tab_1[testo_area]."</a listato 7: pagine/commenti.php vare il codice (listato 8) per no-
per sottopagina. Se un titolo ></div>"; tare un paio di particolari. Le
attirasse l'attenzione, basterà La creazione dell'area di vi- immagini, ad esempio, posso-
cliccarci sopra per ottenere Interessante è capire come sualizzazione di destra è la par- no essere al massimo due per
la visualizzazione dell'artico- ricavare il numero di articoli di te più complessa della pagina. commento ($imm1 e $imm2) e
lo stesso, completo di even- ogni argomento. Si usa la clau- Dobbiamo infatti controllare il loro nome è legato al codice
tuali foto. sola SQL di raggruppamento l'URL della pagina per verifica- del commento (es: il commen-
Per la costruzione della bar- GROUP BY (lezione 4), rag- re se ci sono delle variabili GET to “12” può avere collegate due
ra di navigazione si rimanda al- gruppando tutti i commenti la cui presenza, col relativo va- immagini, nella cartella “img”,
la lezione 2. Il codice che con- pubblicabili che hanno lo stes- lore, determina la costruzione denominate “12_1.jpg” e
tiene la barra è nel file pagi- so argomento e operando su di della pagina. In particolare, al- “12_2.jpg”). Con la funzione “fi-
ne/testata.php: il file viene in- essi una operazione di somma cune variabili escludono la pre- le_exists” controlliamo se l'im-
cluso in ogni pagina, adattan- dei record (listato 7). Il sugge- senza di altre a seconda della magine è effettivamente pre-
dosi dinamicamente alla situa- rimento è salvare questi valori precedenza assegnata. Nel no- sente, e solo in caso positivo la
4 5
La pagina di navigazione di tutti i commenti pubblicati La visualizzazione di un articolo (con due immagini)
5a lezione
$tot=array_sum($list);
$sql_r="SELECT area.testo_area, argomento.testo_argomento, commento.titolo, giornalista.nome, commento.testo, $url="";
date_format(commento.data_ins,'%d-%m-%Y'), commento.click, giornalista.email, giornalista.descri, $ur="";
commento.id_commento FROM commento, argomento, area, giornalista WHERE commento.pubblicabile='si' AND // $url e $ur sono usati per
commento.id_commento='".$_GET[comm]."' AND commento.id_argomento=argomento.id_argomento AND completare il testo del link della
argomento.id_area=area.id_area AND commento.id_giornalista=giornalista.id_giornalista"; sottopagina. In questo caso sono
$ris_r=mysql_query($sql_r); vuoti, ma se avessimo scelto di
$tab_r=mysql_fetch_array($ris_r); visualizzare un'area o un argomento
echo "<strong>".$tab_r[0]." - <em>".$tab_r[1]."</em></strong><p><span avremmo dovuto dare loro i valori che
class='titoletto'>".$tab_r[2]."</span><br />[di ".$tab_r[3]."*]<br />"; poi consentono di mantenere il
// visualizzo le immagini solo dopo averne verificato la presenza riferimento alla selezione
$imm1="../img/".$_GET[comm]."_1.jpg"; if ($_GET[ord]==plus)
$imm2="../img/".$_GET[comm]."_2.jpg"; $url="ord=plus";
if (file_exists($imm1)) echo "<img src='".$imm1."' class='vis'>"; echo "<em>Elenco di tutti
if (file_exists($imm2)) echo "<img src='".$imm2."' class='vis'>"; i commenti:</em><br />";
echo "<br />".$tab_r[4]."<p><span class='normalemini'>Data: ".$tab_r[5]." - click: ".$tab_r[6]."<p>*: $mod=$tot%$vis;
".$tab_r[8]."</span><p>"; if ($mod==0) $pagine=$tot/$vis;
// incremento il valore dei click del commento scelto estraendo il valore attuale, aumentandolo di uno e facendo una else $pagine=(int) ($tot/$vis)+1;
query di aggiornamento if ($pagine>1) {
$cont=$tab_r[6]+1; echo "<span class='colore'>pagine:
$incr="UPDATE commento SET click='".$cont."' WHERE id_commento='".$tab_r[9]."'"; </span>";
mysql_query($incr); for ($i=1;$i<=$pagine;$i++) {
listato 8: pagine/commenti.php echo "<a href='".basename
($_SERVER[PHP_SELF])."?".$url.$_
GET[$ur]."&pg=".$i."'>$i</a> ";
visualizziamo. Con questa ge- _giornalista ".$ordine." LIMIT fault la sottopagina è una sola }
stione si può evitare di memo- ".$start.",".$vis; ed ha quindi valore uno): echo "<p>";
rizzare sul database il legame }
tra il nome dell'immagine e il La variabile $ordine indica il if(isset($_GET[pg]) AND $_GET[pg]>0) $ris_r=mysql_query($sql_r);
codice del commento. Avendo tipo di ordinamento dei record $sottopagina=$_GET[pg]; while
scelto di vedere l'articolo, inol- della query e si ricava da un ci- else $sottopagina=1; ($tab_r=mysql_fetch_array($ris_r)) {
tre, devo incrementare il valore clo if effettuato controllando il // $vis=5 è il numero di commenti da echo "<strong>".$tab_r[0]." - <em>
dei “click” ad esso riferiti (que- valore di $_GET[ord]: se è visualizzare per ogni pagina. $start è ".$tab_r[1]."</em></strong><br />
sto valore serve poi a stabilire uguale a “plus” l'ordinamento usato dall'attributo LIMIT delle query <a href='commenti.php?comm=
uno dei due ordinamenti dei si basa sui click, altrimenti l'or- $vis=5; ".$tab_r[4]."' class='cap'>".$tab_r
commenti): ciò si ottiene con dinamento si basa sulla data di $start=($sottopagina-1)*$vis; [2]."</a> [di ".$tab_r[3]."]<br/>
un'opportuna istruzione UP- inserimento: <span class='normalemini'>Data:
DATE. Un ultimo sforzo (listato 9) ".$tab_r[5]." - click:
Se invece nell'URL c'è una if (isset($_GET[ord]) AND ci consente finalmente di stam- ".$tab_r[6]."</span><p>";
variabile “arg” o “area” o nes- $_GET[ord]=='plus') $ordine= pare l'elenco e creare i link per }
suna delle precedenti (il che "ORDER BY click DESC, data_ins vedere le sottopagine. listato 9: pagine/commenti.php
vuol dire che vanno presi DESC"; Per prima cosa ci serve il to-
estratti tutti i commenti), dob- else $ordine="ORDER BY data_ins tale dei commenti $tot, e que- La pagina “scrivici” (file pa-
biamo scrivere tre query diver- DESC, click DESC"; sto valore lo ricaviamo som- gine/formmail.php) è un form
se per ricavare la lista degli ar- mando i valori dell'array $list per spedire una mail all'ammi-
ticoli. Le query sono abbastan- Per visualizzare N commenti del listato 6. Poi calcoliamo il nistratore del sito (lezione 2).
za simili, quindi esaminiamo per ogni sottopagina (in questo resto della divisione (con l'o- Compilati i campi, si apre una
quella che ci consente di vede- caso sono 5) usiamo una clau- peratore “modulo”, lezione 1): finestra (file pagine/risposta-
re tutti i commenti lasciando ai sola LIMIT nella query: $vis è il se è zero il numero di sottopa- mail.php) che ci informa del-
lettori la costruzione delle altre numero di commenti da visua- gine sarà dato dalla semplice l'avvenuta spedizione della
due (c'è solo una condizione lizzare su ogni sottopagina, divisione $tot/$vis, mentre se è mail o dell'impossibilità di spe-
WHERE da aggiungere) visto mentre $start indica da quale diverso da zero dovremo ag- dirla se anche solo un campo è
che la logica è esattamente la record partire per ricavare i 5 giungere 1 al risultato (intero) vuoto. C'è un controllo java-
stessa (si deve sempre fare un commenti. $start è dinamica, che si ottiene dalla divisione. script a monte che verifica se
join che coinvolge le tabelle nel senso che il suo valore di- Infine se le sottopagine sono nel campo mail c'è una @: va
commento, giornalista, argo- penderà dal numero di sotto- più di una faremo eseguire un benissimo usare dei controlli
mento e area): pagina sulla quale ci troviamo. ciclo for per ottenere i link con javascript che verificano i cam-
Il database ha 11 commenti l'opportuno valore assegnato pi prima di spedirli al server
$sql_r="SELECT area.testo_area, pubblicabili (2 non sono anco- alla variabile pg di tipo GET. (PHP lo fa dopo!), però tenete
argomento.testo_argomento, ra approvati), quindi avremo 3 Cliccando sul link della sotto- presente che javascript può es-
commento.titolo, giornalista.nome, sottopagine (vedi immagi- pagina, “commenti.php” viene sere disabilitato da parte del vi-
commento.id_commento, ne_04): se ci troviamo sulla pri- ricaricata (le altre variabili GET sitatore e quindi i controlli PHP
date_format(commento.data_ins,'% ma $start avrà valore 0 (il pri- restano invariate) e quindi il server-side vanno comunque
d-%m-%Y'), commento.click FROM mo record ha sempre posizio- valore $start viene ricalcolato. inseriti! Per spedire la mail
commento, argomento, area, ne 0), sulla seconda $start avrà Infine visualizzare la lista dei dobbiamo estrarre con una
giornalista WHERE valore 5, sulla terza $start avrà commenti con un ciclo while è query l'indirizzo mail dell'am-
commento.pubblicabile='si' AND valore 10. ormai un gioco da ragazzi. ministratore: ormai dovrebbe
commento.id_argomento= Il valore di $start sarà quindi essere un semplice esercizio.
argomento.id_argomento AND dipendente dalla variabile // $tot è il numero di commenti Anche quando si compila la
argomento.id_area=area.id_area AND $_GET[pg] che indica la sotto- presenti nel DB. Uso la funzione PHP pagina della mailing list viene
commento.id_giornalista=giornalista.id pagina da visualizzare (di de- di somma dei valori di un array aperta una pagina di risposta
5a lezione
Form di connessione alle pagine di gestione dell'amministratore Una parte delle opzioni di gestione dell'amministratore
5a lezione
9
<?php
session_start();
// dopo aver inizializzato la sessione, faccio il primo controllo per verificare se era già stata fatta l'autenticazione
if (isset($_SESSION['ok'])) {
if ($_SESSION['ok']!==true) die ("interrompi tutto");
}
// se è la prima volta che accedo in questa sessione, verifico i dati inseriti nel form
Una semplice richiesta di conferma (in
else { javascript) ci può far evitare di
if (!isset($_POST['user']) or !isset($_POST['pwd'])) { commettere errori
die("Per accedere a questa pagina devi inserire login e password");
}
// questo include mi rimanda alla pagina coi dati di connessione al database su “Approvato”, oppure torna-
include "../servizi/dati.php"; re alla pagina generale di am-
$sql="SELECT * FROM amministrazione WHERE user='".$_POST['user']."' AND pwd=PASSWORD('".$_POST['pwd'] ."')"; ministrazione senza convali-
$ris = mysql_query($sql); darlo. Nel primo caso (listato
$righe=mysql_num_rows($ris); 12) viene eseguita una query di
if ($righe==0) { aggiornamento su quel com-
// non c'era alcuna riga nella tabella che avesse quei valori di user e password mento (il valore chiave del
die ("Mi spiace, user e password non sono corrette. Controlla meglio l'inserimento"); commento è memorizzato su
} $_POST[id] che dobbiamo
elseif ($righe==1) { continuare a propagare inse-
// accesso consentito e contemporanea registrazione della variabile di sessione rendolo come valore nascosto
$_SESSION['ok']==true; anche nel form di questa pagi-
} na. In alternativa avremmo do-
} vuto salvare il valore in una va-
?> riabile di sessione), modifican-
listato 11: admin/auth.inc.php do il valore del campo “pubbli-
cabile” da 'no' a 'si', e viene an-
che mandata una e-mail all'au-
sivamente per aumentare la si- e rendere pubblicabili i com- } tore del commento, dopo aver-
curezza: anche se una perso- menti inseriti dai giornalisti. ?> ne estratto l'indirizzo mail, per
na, infatti, avesse casualmente Per far questo il form ci con- </select> informarlo che il suo articolo è
accesso alla tabella “ammini- sente di scegliere uno tra gli ar- adesso disponibile per la lettu-
strazione”, non avrebbe la pos- ticoli non ancora pubblicati Nella casella a discesa sono ra sul sito.
sibilità di recuperare la pas- grazie ad una casella a discesa visualizzati i primi 40 caratteri Cliccando su “Approvato” è
sword. Possiamo anche usare alimentata da una query: del titolo del commento, ma al- comparsa (se avete javascript
altre funzioni di crittografia co- la pagina successiva è passato attivato) una finestrella di con-
me MD5() e SHA1(). <select name="id" size="1" con la variabile $_POST[id] il ferma (immagine 9) che vi
Finalmente abbiamo acces- class="but"> valore dell'identificativo del chiede se siete sicuri della
so alla pagina generale di am- <?php commento (ossia la chiave). scelta fatta: questa finestra,
ministrazione (immagine 8, file $sql="SELECT id_commento, La pagina che si apre (non c'è utile per evitare di fare errori
“admin/admin.php”). La pagi- LEFT(titolo,40) FROM commento bisogno di reinserire i dati di dovuti alla fretta, si ottiene
na è composta da tanti form WHERE pubblicabile='no' ORDER BY amministratore perché la ses- semplicemente inserendo “on-
che rimandano a pagine in cui data_ins"; sione è già stata validata in submit” nella riga di intesta-
si compiono le azioni specifi- $ris=mysql_query($sql); precedenza) riporta l'articolo zione di un form:
che deputate al ruolo di ammi- while ($tab=mysql_fetch_array($ris)) { come verrebbe pubblicato.
nistratore. Una della azioni, ad echo "<option value='".$tab[0]."'>". L'amministratore può renderlo <form method="post"
esempio, è quella di approvare $tab[1]."</option>"; disponibile sul sito cliccando action="adminnews.php"
class="formadmin"
onsubmit="return
$approvato="UPDATE commento SET pubblicabile='si' WHERE id_commento='".$_POST[id]."'"; window.confirm('Sei sicuro?
mysql_query($approvato); Confermi la scelta?');">
echo "<span class='titoletto'>Il commento è stato approvato ed è quindi adesso disponibile sul sito Internet.
E' stata spedita una mail di conferma all'autore.</span><p>"; La pagina (file admin/ad-
// da qui in poi creo la mail automatica da mandare all'autore mincomm.php) che consente
$sql_g="SELECT commento.titolo, giornalista.email FROM commento, giornalista WHERE la cancellazione di un com-
commento.id_commento='".$_POST[id]."' AND commento.id_giornalista=giornalista.id_giornalista"; mento e delle immagini ad es-
$ris_g=mysql_query($sql_g); so collegato è molto simile alla
$tab_g=mysql_fetch_array($ris_g); precedente, salvo che la query
$to=$tab_g[1]; sarà di cancellazione e le im-
$subject="Approvazione commento"; magini, se ci sono, saranno
$object="Ciao, il tuo commento dal titolo \"".$tab_g[0]."\" è stato approvato ed è quindi disponibile da adesso nel cancellate con la funzione un-
sito internet.\n\nL'amministratore"; link (lezione 3):
$sql="SELECT email FROM amministrazione";
$ris=mysql_query($sql); $cancellato="DELETE FROM
$tab=mysql_fetch_array($ris); commento WHERE
$from="From:".$tab[email]; id_commento='".$_POST[id]."'";
mail($to,$subject,$object,$from); mysql_query($cancellato);
listato 12: admin/adminconv.php // cancello le immagini
$imm1="../img/".$_POST[id]."_1.jpg";
5a lezione
$mod="";
if (trim($_POST[arg])!="") $mod.= "testo_argomento='".trim($_POST[arg])."', ";
if (trim($_POST[area])!="") $mod.= "id_area='".trim($_POST[area])."', ";
if ($mod!=="") {
$mod=rtrim($mod,", ");
// questo rtrim elimina la virgola e il carattere vuoto che si trovavano nella
parte destra di $mod
$modifica="UPDATE argomento SET".$mod." WHERE
id_argomento='".$_POST [id]."'";
mysql_query($modifica);
echo "<span class='titoletto'> Aggiornamento dell'argomento effettuato
</span><p>";
}
listato 13: admin/adminarg.php
Elenco dei commenti pubblicati dall'ultima spedizione della newsletter
5a lezione
11 rename ($dir1,$percorso.$
}
id_c."_1.jpg");
Gli altri corsi
Contestualmente all'inseri-
da Webmaster
mento del commento viene disponibili
mandata una mail all'ammini-
stratore (copia al giornalista) nel CD
per avvertirlo che c'è un nuovo
commento da approvare per la Nel CD Guida 2 allegato
pubblicazione sul sito. a questo numero di PC
Un giornalista può poi modi- Open, all’interno della
ficare (file “giorn/giornmod. cartella PDF/Corsi, trovate
php”) uno dei suoi articoli due corsi completi che
(comprese le immagini), però possono essere un utile
in questo caso il commento complemento al corso PHP.
modificato viene reso nuova- Uno è il corso Web
mente “non pubblicabile” e vie- Developer ASP, 97 pagine
ne mandata una mail all'ammi- suddivise in quattro lezioni
nistratore per informarlo che per capire come realizzare
deve ricontrollare il commento siti dinamici in tecnologia
modificato per approvarlo. ASP.
Le opzioni di gestione del giornalista Il giornalista non può can-
cellare i propri articoli, ma può
chiedere all'amministratore, at-
i propri dati di accesso. spettare tre condizioni decise traverso il form della pagina
La logica di accesso è uguale in fase di costruzione del sito: “giorn/giorncanc.php”, di far-
a quanto visto, ma diversa- larghezza e altezza dovranno lo: anche in questo caso all'am-
mente dal caso dell'ammini- essere minori di 120 pixel e ministratore arriverà una mail
stratore unico, l'autenticazio- l'immagine dovrà essere di tipo con la richiesta.
ne (il form di accesso si trova JPG. Con il logout usciamo anche
nel file giorn/index.php) dovrà Per controllare il rispetto di da questa area di amministra-
memorizzare l'identificativo queste regole uso la funzione zione
univoco del giornalista e verifi- PHP getimagesize, registrando Il sito dei commenti è adesso
care lo stato della sua registra- i valori ottenuti (larghezza, al- pronto per essere gestito e ag-
zione bloccando l'accesso ai tezza, tipo e attributi dell'im- giornato, e tutte queste opera-
giornalisti disattivati. magine) in una serie di variabi- zioni non saranno più compiu-
Usiamo allo scopo il file li grazie alla funzione list: te modificando il codice delle
giorn/auth.inc.php (listato 14) pagine. Il compito del WebDe-
introducendo un nuovo con- list($width1, $height1, $type1, $attr1) veloper è finito!
trollo sulla query di accesso e = getimagesize($_FILES
inizializzando una variabile di ['immag']['tmp_name'][0]); Conclusioni
sessione di nome “id_giorn” // l'immagine sarà caricata se Il corso WebDeveloper PHP Il corso Webmaster spiega,
che memorizza il valore della $width1<=120, $height1<=120 e (e MySQL) finisce qui, dopo 5 invece, in 88 pagine
chiave identificativa del gior- $type1=2 (il valore 2 indica un file jpg) lezioni, con questo esempio ap- suddivise in otto lezioni tutto
nalista. plicativo da studiare e riadat- quello che bisogna sapere
Questa nuova variabile ser- Passati questi controlli devo tare secondo le proprie esigen- per costruire un sito
ve ad impedire che un giornali- caricare l'immagine sul server ze. e imparare il linguaggio
sta possa vedere e modificare dandole come nome il codice Lo scopo del corso era far in- HTML 4.01, i CSS (fogli
gli articoli e i dati degli altri del commento cui si riferisce. tuire le potenzialità di un lin- di stile), Java Script e CGI.
giornalisti. Per ricavare il codice identifi- guaggio open-source server si- Il corso è completato da utili
Entriamo nella pagina gene- cativo (chiave) uso la funzione de come PHP, utilizzabile con consigli per promuovere
rale (immagine 11): inseriamo mysql_insert_id che mi resti- profitto sia in modalità stand il proprio sito on line.
come user il nome del giornali- tuisce proprio il codice che alone sia in coppia con un qual-
sta (es: “giuseppe”) e come cerco (estrae il valore del cam- siasi DBMS allo scopo di svi-
password il cognome (es: “ver- po autoincrementale presente luppare siti dinamici. E proprio
de”), entrambi minuscoli. Pro- nell'ultima query di inserimen- in un'ottica di completezza di
viamo poi a vedere cosa succe- to dell'articolo), quindi carico formazione del WebDeveloper,
de usando il giornalista giovan- l'immagine con move_uploa- sono stati approfonditi anche i
ni bianchi che è stato disabili- ded_file e infine rinomino (fun- concetti di base, teorici e pra-
tato. zione rename) l'immagine tici, della creazione di un data-
Riguardo le pagine di gestio- usando la codifica decisa in fa- base.
ne coinvolte, vale la pena spen- se progettuale: Gli esempi trattati sono stati
dere due parole sull'inserimen- presi da esperienze reali “sul
to delle immagini (lezione 3), $percorso="../img/"; campo”, ma, al solito, possono
operazione contestuale all'in- $dir1=$percorso.$_FILES['immag'] essere considerati solo un pun-
serimento del testo di un com- ['name'][0]; to di partenza per raggiungere
mento (file giorn/giornins. $id_c=mysql_insert_id(); nuovi traguardi... il limite, ge-
php). if($_FILES['immag']['name'][0]) { neralmente, è dato dalla nostra
Nel caso decidessi di inseri- move_uploaded_file($_FILES['immag'] fantasia.
re una o due immagini dovrò ri- ['tmp_name'][0], $dir1); Buon lavoro a tutti!