Sei sulla pagina 1di 91

Apprendista

Installazione base - per installare un server in 15 lezioni a cura di Francesco Bonetto


locale
Principianti - per chi vuole imparare da zero
Intermedia - per chi conosce Php
Guida a PhpMyAdmin
Avanzata - per chi vuole perfezionarsi
Php/MySql - per interagire con un database Un breve tutorial per capire com'è strutturato e come funziona questo tool
PhpMyAdmin - per gestire un database Apprendista
13 lezioni a cura di saibal

Questa sezione si rivolge a chi desidera diventare uno sviluppatore per il Web utilizzando la tecnologia PHP.

Percorso consigliato di Saibal


Principiante lorenzoforti@html.it
Guida pratica al PHP
Un modulo aggiuntivo per web servers che permette di creare delle pagine web dinamiche. La guida, scritta da Alberto Mucignat ne spiega le caratteristiche teor Una guida di base che ha come obiettivo l'installazione di Apache 1.3.24, Php 4.1.2, MySql 3.23.49 e PhpMyAdmin per
lezioni. testare gli script in locale
Esperto
15 lezioni a cura di Alberto Mucignat

1. Quali sono gli strumenti necessari per testare Php in locale?


Guida teorica al PHP
Una breve premessa sul perchè installare un webserver sul proprio pc
Questa guida, a cura di Edoardo Valsesia, è indirizzata alla comprensione dei costrutti teorici del linguaggio PHP, con particolare attenzione alla teoria.
Apprendista
48 lezioni a cura di Edoardo Valsesia
2. Prima di tutto il webserver: installiamo Apache

Il primo passo è scegliere un buon webserver su cui far girare le pagine in php
Guida di base Php
Guida introduttiva alle funzioni e alla struttura del modulo Php
3. Apache: come funziona?
Principiante
27 lezioni a cura di Giangiacomo Patteri
Brevissima descrizione delle caratteristiche principali del webserver

Guida su Apache
4. Installiamo Php come modulo
Guida rivolta ad utenti professionisti che hanno la possibilità di gestire il proprio server.
Esperto I sorgenti Php vanno configurati per essere interpretati dal webserver
44 lezioni a cura di Edoardo Valsesia

5. Installiamo Php come modulo - parte II


Php in locale su Windows
Vediamo come configurare il file di installazione
Una guida di base che ha come obiettivo l'installazione di Apache 1.3.24, Php 4.1.2, MySql 3.23.49 e PhpMyAdmin per testare gli script in locale
Principiante
7 lezioni a cura di Saibal
6. Installiamo MySql

Un database è fondamentale per testare le funzioni più avanzate di Php


Guida pratica Php/MySql
Una guida di base per capire i comandi fondamentali di interazione tra Php e MySql
7. Utilizziamo PhpMyAdmin

HTML.IT – Guide PHP 1 HTML.IT – Guide PHP 2


Una comoda interfaccia web per interagire con MySql Perfetto...abbiamo elencato quelli che io definisco "i magnifici 3"; come già detto ci sarebbero altre
possibili configurazioni ma vi assicuro che Apache + Php + Mysql è veramente un'ottima "squadra"
di lavoro.
Quali sono gli strumenti necessari per testare Php in locale?
Prima di tutto il webserver: installiamo Apache

N.B. Questa guida è stata aggiornata alla versione 1.3.24 di Apache con Php 4.1.2. Bisognerà
far riferimento esclusivamente alle versioni indicate. N.B. È buona regola effettuare tutte le modifiche ai file di configurazione (sia di Apache che
del modulo Php) a server spento in modo da essere sicuri che al riavvio del server stesso siano
Personalmente ho sempre ritenuto che la cosa migliore, per imparare nuovi linguaggi di caricate le nuove impostazioni.
programmazione, non sia tanto lo studio di un libro quanto una massiccia dose di pratica.
Di sicuro un buon testo è fondamentale per comprendere le basi di ciò che stiamo trattando ma Adesso che siamo quanto meno entrati nell'argomento possiamo metterci all'opera: la prima cosa da
nessun autore sarà mai in grado di descrivere, astrattamente, tutti i possibili problemi che fare è installare il webserver sul nostro pc.
incontreremo durante la costruzione di un sito...problemi che possono essere risolti solamente con Al momento in cui scrivo è già disponibile la versione 2.0 di Apache. Anche se è una release
l'allenamento "sul campo". dichiarata stabile personalmente ritengo che, con Php 4.1.2, la miglior versione sia proprio la 1.3.24
In questo contesto possiamo dire che alcuni linguaggi non richiedono particolari strumenti per ; se poi aggiungiamo che stiamo in locale, e non abbiamo le giuste pretese di un hoster, direi che
essere testati: javascript, ad esempio, ha bisogno solamente del caro notepad e di un browser non abbiamo raggiunto un ottimo compromesso.
troppo vecchio; in altri casi, però, la situazione è differente: PHP oppure ASP necessitano di alcuni Non vi spaventate...quella che stiamo per affrontare è una fase relativamente facile; infatti, già dalle
componenti da installare sul proprio pc per essere provati in locale. ultime release, Apache viene rilasciato con all'interno una procedura di installazione che facilita
Naturalmente, avendo a disposizione un servizio di hosting adeguato, potremmo anche utilizzare lo enormente tutte le operazioni e non ci sarà bisogno di compilare i sorgenti a mano...ci basterà
spazio remoto per i test ma di sicuro andremmo incontro ad alcuni problemi: cliccare sul file exe.
Andiamo con ordine: colleghiamoci al sito ufficiale del progetto Apache a questo indirizzo e
x una bolletta telefonica da far rabbrividire anche il Sultano del Brunei (in questo caso si potrebbe cerchiamo la versione 1.3.24 disponibile per Windows.
risolvere con una linea adsl) Dato che il sito non brilla certo in quanto ad usabilità (io mi ci sono perso un sacco di volte) vi do
una mano; potete scaricare il software direttamente da qui (versione con installer; vi invito a leggere
x tempi esageratamente lunghi (ogni volta che abbiamo modificato un file dobbiamo fare l'upload qualche riga più sotto per capire di cosa parlo) oppure potete seguire le mie istruzioni.
sul server con un programma FTP e non è detto che le connessioni siano sempre veloci). Una volta caricata la home page cliccate su "HTTP Server" nel menù a sinistra; a questo punto
leggerete la descrizione dell'ultima versione disponibile (la 2.0 appunto); scorrete la pagina fino alla
Per uscire indenni da questa situazione, apparentemente critica, basterà "trasformare" il pc di casa in parte in cui si parla della 1.3.24, cliccate sul link "Apache for Win32" e, se siete curiosi, leggete le
un piccolo server molto simile a quello che ospita le nostre pagine online. informazioni riguardanti il funzionamento del webserver su piattaforme Microsoft altrimenti andate
Dato che ogni linguaggio è diverso da altri, ci sono quindi componenti specifici, in questa guida direttamente al paragrafo intitolato "Downloading Apache for Windows". Il link da seguire è
tratteremo, esclusivamente, l'installazione del modulo Php e degli accessori per il suo questo: http://httpd.apache.org/dist/httpd/binaries/win32/.
funzionamento su sistema operativo Windows. Uff..che fatica...dopo immensi giri siamo finalmente arrivati alla pagina dei download. I file
Nel caso non abbiate ancora compreso cosa sia o a cosa serva Php vi invito a consultare le FAQ di disponibili sono molti ma a noi non interessano le versioni con i sorgenti da compilare...noi
questo sito per poter capire, anche se superficialmente, di cosa stiamo parlando. vogliamo la versione con il file di installazione automatica (che ci permette di installare il tutto
come un normale software).
Torniamo a noi: dicevamo dei componenti...ma quali componenti?
Facciamo una brevissima premessa: il linguaggio Php, per poter funzionare, ha bisogno innanzitutto A questo punto c'è da fare un piccolo excursus: a partire dalla 1.3.22 Apache viene rilasciato sia con
del relativo "pacchetto" contenente i sorgenti che interpretano il codice; abbiamo anche bisogno di un installer incluso nel pacchetto ( potremmo definirlo un "tutto compreso chiavi in mano" (: ), sia
un webserver su cui far "girare" il Php; un webserver non è altro che un software capace di gestire senza l'installer che, invece, dovrà essere scaricato a parte.
tutte le connessioni ad un determinato computer ed inoltre si fa carico di "restituire", al visitatore, la La differenza tra le due versioni è semplice: nel primo caso basterà cliccare sull'icona e procedere
pagina .php richiesta in formato html (così che possa essere "letta" dal nostro browser). con le operazioni; nel secondo caso sarà necessario un componente Microsoft per far partire il file
I webserver che si possono utilizzare sono più di uno, ma noi installeremo Apache che ormai, per .exe (se non avete questo componente aggiuntivo, il file sarà impossibile da aprire). Il piccolo
uso didattico su Windows, ha raggiunto un buon livello di affidabilità anche se era stato concepito accessorio, di serie su Win ME, su WinXp e su Win 2000, si chiama Microsoft Installer e deve
per sistemi UNIX/LINUX (una curiosità: Apache è il webserver più diffuso della rete, non costa essere scaricato dai possessori di Win NT 4.0, Win 95 e 98 a questi indirizzi:
nulla ed è amatissimo da tutti gli estimatori dell'Open Source).
Ultimo componente di cui avremo bisogno è un database per testare gli script più avanzati; pensate x Versione 1.10 per WinNT 4.0
ad un database come ad un grande archivio virtuale in cui, tramite Php, possiamo immagazzinare
tutti i tipi di dati possibile per poi richiamarli in qualsiasi momento. Nel nostro caso utilizzeremo x Versione 1.10 per Win 95-98
Mysql: stabile, veloce e potente.

HTML.IT – Guide PHP 3 HTML.IT – Guide PHP 4


x http://saibal (oppure nome_scelto_da_noi; per comodità, in questa guida, farò riferimento sempre
Quindi a voi la scelta: a http://saibal)

x se non avete l'Installer sul vostro pc (e non volete installarlo) scaricate questa versione Adesso che, molto sommariamente, abbiamo visto come identificare il nostro pc in locale passiamo
http://www.apache.org/dist/httpd/binaries/win32/apache_1.3.24-win32-x86-no_src.exe (5.1 MB). all'installazione vera e propria del server (non vedevate l'ora vero?).
x se, invece, avete già il Microsoft Installer disponibile potete fare il download di questa versione Vediamo i passi da seguire:
http://www.apache.org/dist/httpd/binaries/win32/apache_1.3.24-win32-x86-no_src.msi,
decisamente più leggera (2.0 MB). 1. Clicchiamo sul file .exe; dopo aver accettato i termini della licenza, avremo di fronte una
schermata con tre campi da riempire; anche se non è un'operazione fondamentale per i primi
Ovviamente la presenza o meno dell'installar nel pacchetto (e quindi la diversità di peso in MB) è due (potrebbero essere lasciati vuoti visto che siamo in locale), inseriamo il nome del nostro
l'unica differenza tra le due versioni sopracitate; per il resto sono identiche. pc (quello che abbiamo scelto prima...io inserisco saibal) mentre nel terzo campo (è
fondamentale) scriviamo la nostra email
Ok... prima di procedere, ora che abbiamo tutto il necessario, facciamo un passo indietro per capire
come agiremo: dopo aver attivato il nostro webserver, le pagine locali saranno raggiungibili, 2. Spuntiamo il radiobox relativo a Run as a service for All Users -- (Recommended) e
mediante il browser, all'indirizzo http://localhost oppure http://127.0.0.1. clicchiamo su Next
Localhost e 127.0.0.1 sono gli URL che, in locale, indentificano il nostro pc; detto in parole molto
povere: ogni macchina in rete ha un numero IP che la caratterizza e, generalmente, i server attaccati 3. Selezioniamo Setup Complete e andiamo avanti
ad internet hanno un indirizzo canonico del tipo 123.123.123.123.
Apache, come webserver, ha necessità di essere associato al numero della macchina su cui è 4. Scegliamo la directory dove installare Apache. Per comodità lasciamo quella di default:
installato in modo da poter "rispondere" alle richieste dei visitatori connessi. C:\Programmi\Apache Group (io farò riferimento sempre a questa d'ora in poi)
Teoricamente il problema sorge quando decidiamo di eseguire l'installazione in locale; infatti,
5. Clicchiamo su Install, aspettiamo che finiscano le operazioni e riavviamo il pc
presupponendo che faremo le prove offline, non avremo un IP canonico da inserire. . . in che modo,
allora, associamo il server alla nostra macchina?
La risposta, da quanto detto prima, l'abbiamo già: i pc non connessi ad intenet, ma con un accesso
remoto installato, hanno un indirizzo di default indicato dal numero 127.0.0.1 o, in alternativa,
localhost (che è la stessa cosa). Non ci crederete ma abbiamo finito...non vi fidate? Facciamo una prova: dal menù Start aprite la
Io però sono un tipo estremamente pignolo e aggiungo quindi che, volendo, possiamo raggiungere cartella Apache httpd Server e selezionate Start Apache in Console.
le nostre pagine anche in un altro modo oltre a quell'asettico localhost o 127.0.0.1. Se tutto è andato bene (come spero) si apriranno due finestre del DOS; una verrà richiusa
In questo discorso do per scontato che voi abbiate installata una connessione di accesso remoto sul immediatamente mentre nell'altra, rimasta attiva, ci sarà scritto Apache/1.3.24 <Win32> running...
vostro pc (di qualunque tipo: modem analogico, isdn, adsl etc). L'accesso remoto, infatti, installa dei
"pacchetti di rete" che permettono un'ulteriore identificazione del computer stesso oltre ai nomi di Come potete intuire questo significa che il nostro webserver è acceso e pronto a lavorare. Per
default (i soliti localhost o 127.0.0.1). un'ulteriore conferma apriamo il browser e digitiamo http://localhost o più semplicemente
In pratica possiamo assegnare al nostro pc qualsiasi nome; per fare questo apriamo il pannello di http://saibal: avremo davanti una semplicissima pagina web...ma a noi sembrerà la più bella del
controllo di Windows e clicchiamo sull'icona Rete; selezioniamo il menù Identificazione e avremo mondo perchè riporterà questa scritta:
davanti tre campi di testo: Funziona! Il Server Web Apache e' stato installato su questo sito Web!.
Nel caso, invece, qualcosa sia andato storto vi invito a disinstallare il programma, a non perdervi
x Nome Computer d'animo e a ricominciare da capo....è probabile che abbiate sbagliato qualcosa nella configurazione.

x Gruppo di lavoro Apache: come funziona?

x Descrizione Computer
Vi starete forse chiedendo da dove sia uscita la pagina html che abbiamo appena visto. Ebbene, di
I primi due campi contengono i dati che abbiamo inserito durante la prima installazione del sistema default, Apache "cerca" le pagine da caricare in una cartella (all'interno della directory Apache
operativo, mentre l'ultimo campo generalmente è vuoto e possiamo lasciarlo così. Group\Apache) chiamata htdocs...ed è qui che, in teoria, andranno i nostri lavori in php per essere
Se decidiamo di raggiungere le nostre pagine in locale digitando, ad esempio, il nome saibal basterà visualizzati. È possibile, comunque, variare il percorso di questa cartella e, ad esempio, sceglierne
inserire questa parola nel campo Nome Computer e riavviare il pc. una a piacere dopo averla creata.
Da questo momento, una volta installato, il nostro webserver sarà raggiungibile in tre modi diversi: Mettiamo di voler avere, come directory base, la cartella test; dal menù
START>Programmi>Apache httpd Server>Configure Apache Server, selezioniamo il file Edit the
x http://localhost Apache httpd.conf Configuration File (è il file che gestisce tutte le opzioni del server e si edita
con il Notepad).
x http://127.0.0.1 Una volta aperto, con la funzione Cerca, arriviamo alla riga DocumentRoot (di default dovrebbe
essere "C:/Programmi/Apache Group/Apache/htdocs") e cambiamo htdocs in test.
HTML.IT – Guide PHP 5 HTML.IT – Guide PHP 6
Poco più sotto troveremo <Directory "C:/Programmi/Apache Group/Apache/htdocs">....anche riesco a spiegare bene le cause.
in questo caso dovremo sostituire htdocs in test (affinchè le nuove impostazioni abbiano effetto sarà In pratica, per l'installazione del modulo Php, sono necessarie anche due librerie fondamentali che il
necessario riavviare il server...tra poco spiegherò come fare). mio pc non aveva. Non so, quindi, se fosse un problema solamente del mio SO o fosse un fatto
Per adesso sono finite le modifiche da apportare al file di configurazione del webserver; d'ora in poi generale. Comunque si pone facilmente rimedio scaricando, per sicurezza, questo zip contenente i
la cartella di lavoro sarà quella appena creata e sarà qui che dovremo mettere tutte le pagine da due file di cui parlavo: odbc32.dll e odbcint.dll [Scarica le librerie].
provare. Dopo aver aggiornato il Windows Socket non dovete far altro che copiare le due librerie .dll nella
cartella C:\System.
Per poter lavorare correttamente dobbiamo conoscere i comandi base utilizzati da Apache.
Nelle versioni precedenti, all'interno della cartella Apache httpd Server, c'erano delle icone (per me Installiamo Php come modulo
estremamente comode) che permettevano di far ripartire o fermare il server.
A partire dalla 1.3.20, invece, è presente solo l'icona per lo start mentre le altre operazioni andranno
eseguite tramite DOS (sconsiglio un brusco CTRL + C che chiuderebbe la sessione invece di Ora che Apache è in grado di funzionare correttamente, possiamo installare il modulo php. I link
arrestarla). per i sorgenti sono reperibili su molti siti presenti in rete ma noi faremo riferimento a Php.net,
Apriamo, quindi, il prompt del DOS di Windows e, digitando questa riga, spostiamoci nella cartella ovvero il sito ufficiale degli sviluppatori; queste pagine ci saranno molto utili anche in futuro dato
dove è installato Apache: che contengono tutta la documentazione ufficile, oltre a molti link utili ed interessanti...vi consiglio
di metterlo tra i vostri bookmark.
C:\>cd programmi\apache~1\apache
(la tilde (~) si ottiene premendo il tasto ALT alla sinistra della barra spaziatrice, digitando Nella sezione download si trovano gli zip con i file per l'installazione; al momento in cui scrivo
consecutivamente i caratteri 1 2 6 del tastierino numerico e rilasciando l' ALT). l'ultima release stabile è la 4.2 (maggio '02) ma in questa guida ho preferito scegliere la versione
precedente per motivi di "anzianità" (ho un grosso difetto: non mi piace installare le cose appena
Una volta nella directory di apache possiamo scegliere tra tre operazioni: uscite (: ).
In particolare, a noi interessa la versione Win32 Binaries del "PHP 4.1.2" che possiamo scaricare
x Fermare il server digitando apache -k stop anche da qui.
Una volta terminato il download (circa 5,8 MB) dobbiamo scompattare il file in una qualsiasi
x Far ripartire il server scrivendo apache -k restart directory sul nostro hard disk; anche in questo caso, per comodità, ho scelto C:\Programmi e, d'ora
in poi, farò riferimento sempre ad essa.
x Attivare il server direttamente da DOS digitando apache -k start Una volta scompattato noteremo che la cartella ha nome php-4.1.2-Win32...rinominiamola
semplicemente in Php.
Questi comandi ci saranno molto utili in seguito quando, apportate alcune modifiche per il Php, Apriamo la cartella e cerchiamo il file php.ini-dist; una volta individuato dobbiamo copiarlo ed
dovremo far ripartire la macchina. incollarlo nella cartella C:\Windows (c:\winnt40 o c:\winnt per i possessori di Windows NT/2000)
ricordandoci di rinominarlo in php.ini.
Prima di concludere questa sezione vi do due suggerimenti. Ora che è stato rinominato apriamo il file con un qualsiasi editor di testo (consiglio il
Per non avere sempre in primo piano la finestra del DOS quando avviamo il server, create un Notepad...semplice e veloce); con la funzione Cerca individuiamo la riga contenente questa
collegamento sul desktop dell'icona Start Apache in Console; cliccate con il tasto destro del mouse istruzione:
sul collegamento e scegliete Proprietà; dal menù a tendina del comando Esegui selezionate Ridotto
a icona e date l'OK...in questo modo saranno più veloci le operazioni di avvio e non avrete più il doc_root =
problema del prompt.
in verità questo parametro potrebbe anche essere lasciato in bianco ma, per completezza,
Sempre relativamnete al DOS vi suggerisco di impostare, come directory di lavoro, quella in cui è riempiamolo con il percorso che porta alla cartella base di Apache (quella che contiene i documenti
installato Apache; infatti, se non siete dei grandi "smanettoni", il DOS lo userete spesso solo nei da testare); facendo riferimento a quanto settato prima nel file di Apache, scriveremo:
casi in cui vorrete fermare o far ripartire il server...in questa maniera non dovremo spostarci ogni C:\Programmi\Apache group\Apache\test .
volta ma ci troveremo direttamente nella cartella giusta.
Per fare questo aprite un prompt e cliccate con il tasto destro del mouse sulla barra superiore (quella Installiamo Php come modulo - parte II
blu); selezionate Proprietà e, nel campo Directory di lavoro, scrivete il percorso per arrivare alla
cartella di Apache: in questo caso sarà c:\programmi\apache~1\apache; infine cliccate su Applica.
Pefetto...siamo quasi alla fine. Nella cartella Php dobbiamo cercare un file chiamato "php4ts.dll"
Note per chi possiede Wind95 (Attenzione: se non lo vedete vuol dire che dovete selezionare, nel menù Visualizza>Opzioni
1) - Prima di procedere con l'installazione di tutti i componenti è necessario scaricare Cartella>Visualizza, il ceckbox relativo a Mostra tutti i file).
l'aggiornamento del Windows Socket 2 (sono delle librerie aggiornate per il Sistema Operativo). Il php4ts.dll è fondamentale per il funzionamento del modulo Php...può essere considerato come il
L'update è disponibile sul sito Microsoft a questo indirizzo. motore principale. Una volta trovato dobbiamo copiarlo nella directory C:\Windows\System
(C:\Winnt\System32 per i possessori di Windows NT/2000).
2) - Durante l'installazione di Php (che affronteremo dopo) ho notato anche un particolare di cui non
HTML.IT – Guide PHP 7 HTML.IT – Guide PHP 8
Con i file di configurazione del Php abbiamo finito...adesso dobbiamo modificare nuovamente il Ora che abbiamo Apache e Php funzionanti potremmo anche fermarci qui per i primi test. Infatti,
file httpd.conf di Apache. Vediamo i passaggi da attuare: per apprendere e provare le funzioni base, il materiale installato è più che sufficiente.
Nel caso, invece, volessimo provare, in locale, script più complessi avremmo la necessità di
x Sempre con l'apposita funzione del Notepad cerchiamo la riga installare anche un database...in questo caso ho scelto MySql.
"#LoadModule unique_id_module modules/mod_unique_id.so" e, subito sotto, aggiungiamo MySql, in pratica, sarà il "luogo" in cui potremo riporre i nostri dati in attesa di richiamarli,
quanto segue: manipolarli o leggerli...un database può essere visto come un enorme archivio con cui interagire.
Do per scontato, naturalmente, che abbiate installati Apache e Php in modo corretto.
LoadModule php4_module c:/programmi/php/sapi/php4apache.dll
( se necessario modificare il percorso che porta al file php4apache.dll ) Per iniziare colleghiamoci al sito ufficiale del progetto MySql.
Anche in questo sito ci si potrebbe trovare spaesati, data la mole di informazioni presenti...vi do
delle indicazioni: nella sezione download, scarichiamo l'ultima versione stabile disponibile che, al
x Cerchiamo la riga "AddModule mod_setenvif.c" e sotto aggiungiamo: momento in cui scrivo, è la 3.23.49.
Una volta terminato il download mettiamo da parte lo zip e apriamo nuovamente il file php.ini (sta
AddModule mod_php4.c dentro la cartella C:\Windows ricordate?).
Spostiamoci verso la fine del documento e cerchiamo la sezione che riguarda MySql...basterà
individuare il blocco di testo che inizia così:
x L'ultima fase: cerchiamo "AddType application/x-tar .tgz" e aggiungiamo:
[MySQL]
AddType application/x-httpd-php .php ; Allow or prevent persistent links
AddType application/x-httpd-php .php3

Modifichiamo le seguenti stringhe in modo da impostare questi valori:


Da notare che il riferimento fatto a AddType application/x-tar .tgz è del tutto personale; infatti le
due righe aggiunte potevano essere inserite benissimo in altri punti del file di configurazione. mysql.allow_persistent = On
mysql.max_persistent = -1
mysql.max_links = -1
Per completare l'opera non ci resta che impostare le pagine predefinite da caricare. Mi spiego: di mysql.default_port = 3306
mysql.default_host = localhost
default, digitando http://localhost (o 127.0.0.1), Apache cercherà la pagina chiamata index.html; se mysql.default_user = (potete lasciarlo vuoto)
mysql.default_password = (potete lasciarlo vuoto)
non è presente verrà visualizzato il contenuto della directory test.
Dato che a noi interessa testare le pagine php, può essere comodo indicare al webserver di cercare,
oltre all' index con estensione .html, anche altri tipi di file. Fatto questo possiamo finalmente installare il database. La procedura è molto semplice: una volta
Spostimoci, quindi, fino alla riga "<IfModule mod_dir.c>" e trasformiamo DirectoryIndex scompattato lo zip clicchiamo sull'icona "Setup.exe" e seguiamo le varie fasi del wizard; il mio
index.html in DirectoryIndex index.php index.html index.htm index.php3 index.phtml. unico consiglio è di cambiare la directory di installazione da "C:\mysql" in
In poche parole abbiamo aggiunto, separati da spazi, i nomi delle pagine che Apache deve cercare "C:\Programmi\mysql"...così facendo avremo tutti i nostri componenti nella stessa cartella.
in automatico nella directory principale; ovviamente potremmo anche inserire nomi a Al contrario di ciò che accade normalmente, Mysql non comparirà direttamente nel menù
piacere...penso comunque che possa andare bene anche così. START>PROGRAMMI; per avviare il database dovremo aprire la cartella "Mysql" situata, come
sappiamo, nella directory "Programmi".
E' giunto il momento di vedere se tutto è ok. Per verificarlo apriamo il notepad e scriviamo Non spaventiamoci per il gran numero di file presenti...tutto ciò che a noi interessa si trova nella
semplicemente: cartella "bin" (naturalmente vi invito ad aprirla); più in dettaglio lavoreremo principalmente con un
solo file .exe:
<? phpinfo(); ?>
winmysqladmin.exe
N.B. Attenzione alle estensioni nascoste; se non stiamo attenti salveremo il file come
index.php.txt e non verrà interpretato dal server. Il primo consiglio è quello di creare un collegamento sul Desktop (o dove volete voi) per sveltire le
Salviamo il documento nella cartella test con il nome di index.php; avviamo il nostro webserver e operazioni di attivazione del database.
digitiamo http://localhost (oopure http://saibal, oppure ancora http://127.0.0.1). Fatto questo possiamo provare ad avviarlo: clicchiamo due volte su "wynmysqladmin.exe"; dato
Incrociamo le dita e....se siamo "fortunati" dovrebbe comparire una pagina lunghissima con un che è la prima volta che lo lanciamo ci verrà chiesto di immettere Username e Password;
sacco di dati...ebbene: queste sono tutte le informazioni sul modulo Php...vuol dire che ci siamo riempiamo tutti e due i campi e diamo l'OK (queste saranno i vostri dati di accesso al database...non
riusciti e adesso possiamo testare le pagine in locale. Fantastico no? scordateli. Io ad esempio userò saibal per tutti e due...originale no?).
Se tutto è andato per il verso giusto dovrebbe comparire un piccolo semaforo nella System Tray (in
Installiamo MySql basso a destra nello schermo); naturalmente il semaforo dovrebbe avere la luce verde
accesa...viceversa un bel semaforo rosso starebbe ad indicare che c'è stato qualche intoppo. Se così
fosse vi invito, anche in questo caso, a ripartire con la procedura di installazione non prima di aver

HTML.IT – Guide PHP 9 HTML.IT – Guide PHP 10


rimosso il vecchio Mysql (dal menù Installa Applicazioni). su un'altra piattaforma.
Io sono ottimista e così voglio pensare che sia andato tutto bene...se il nostro semaforo è verde vuol Il problema si risolve facilmente e velocemente: apriamo un qualsiasi altro editor di testo (Word o
dire che Mysql è attivo e pronto a lavorare. addirittura Wordpad vanno benissimo); copiamo il testo illeggibile dal Notepad e incolliamolo nel
Clicchiamo con il mouse sull'icona del semaforo e selezioniamo Show Me in modo da far aprire la nuovo documento... come per magia avremo il testo "in chiaro" e pronto per essere modificato;
finestra del programma con i vari menù a scelta. Il più importante è, forse, il menù "Databases", adesso facciamo l'operazione inversa e riportiamo il tutto nel blocco note.
ovvero la lista di tutti i db presenti e la relativa struttura.
Per chiudere Mysql vi sconsiglio di premere sulla "X"; c'è un modo molto più dolce per dire al N.B.: nel reincollare il testo "pulito" nel Notepad è molto probabile che rimangano uno o due
nostro software che non vogliamo più utilizzarlo: una volta che la schermata è aperta clicchiamo spazi tra la fine del testo stesso e il fondo del documento. Questo non deve assolutamente
con il tasto destro vicino al semaforo e potremo scegliere tra le due azioni principali (selezioneremo accadere...in caso contrario avremo un bell'errore in PhpMyadmin; detto in parole povere tra
il rispettivo sottomenù in base al nostro sistema operativo): la riga

ShutDown this Tool set_magic_quotes_runtime(0);


?>
Ferma e chiude completamente l'applicazione
e la fine della pagina NON ci deve essere nessuna riga vuota.

ShutDown this Server Eravamo rimasti con il file "config.inc.php" aperto; cerchiamo queste righe e accertiamoci che
Ferma momentaneamente l'applicazione e la mantiene in standby pronta per ripartire con l'opzione siano impostate così:
"Start the Server"
$cfgServers[1]['host'] = 'localhost';
A questo punto potrei anche salutarvi e concludere con un augurio di buon lavoro dato che abbiamo
tutto l'occorrente per iniziare... basterà solo imparare i comandi di routine per interagire e creare le $cfgServers[1]['port'] = '';

tabelle in Mysql appena installato. $cfgServers[1]['adv_auth'] = FALSE;


Questa guida, però, non sarebbe completa se non parlassi anche di Phpmyadmin. $cfgServers[1]['stduser'] = '';
$cfgServers[1]['stdpass'] = '';
Utilizziamo PhpMyAdmin
$cfgServers[1]['user'] = 'saibal';
$cfgServers[1]['password'] = 'saibal';

Phpmyadmin non è altro che un'interfaccia grafica, visualizzabile tramite browser, che ci permette $cfgServers[1]['only_db'] = '';
di interagire con Mysql. $cfgServers[1]['verbose'] = '';
Possiamo creare, editare, cancellare e modificare sia le tabelle che i database allo stesso modo di
$cfgServers[1]['bookmarkdb'] = '';
coloro che, sicuramente più bravi di noi, usano le classiche righe di comando...però il nostro metodo
$cfgServers[1]['bookmarktable'] = '';
è più intuitivo e, in pratica, non dovremo mai usare la schermata di Mysql.
La prima cosa da fare è scaricare lo zip dei sorgenti da questo indirizzo
http://phpmyadmin.sourceforge.net/.
Abbiamo a disposizione varie tipoligie di file; è ovvio che possiamo scegliere quella che più ci I campi "cfgServers[1]['user']" e "$cfgServers[1]['password']" devono essere settati con gli stessi
risulta comoda...io personalmente scaricherei la phpMyAdmin-2.2.1-php.zip [Potete anche valori utilizzati nel primo avvio di MySql (e difatti io avevo inserito come Username e Password la
scaricarla da qui]. parola "saibal").
Il file è molto leggero e non ci metteremo molto a completare il download; una volta terminata Questa appena descritta è solamente una delle tante procedure possibili; ad esempio possiamo
questa operazione scompattiamo lo zip e rinominiamo la cartella come vogliamo, ad esempio impostare più utenti per utilizzare il database, oppure si può impostare un maggiore livello di
amministra_mysql oppure admin_mysql...io scelgo un semplice e chiaro phpadmin. sicurezza prima di avere accesso a MySql (utile in quei casi, magari, in cui abbiamo il pc in ufficio
e vogliamo preservare i nostri dati da sguardi indescreti).
Copiamo questa cartella nella directory principale del nostro webserver; in questo caso, quindi, Tuttosommato possiamo dire che la configurazione appena realizzata è sufficiente per lavorare in
dovremo andare nella cartella "test" all'interno di Apache. casa comodamente seduti davanti al nostro pc.
Adesso possiamo iniziare a fare le modifiche; il file su cui concentreremo la nostra attenzione è il
"config.inc.php". Non dimentichiamoci comunque ciò che stavamo per fare: controllare che PhpMyAdmin funzioni.
Apriamolo con il notepad...cosa notiamo prima di tutto? Vi starete sicuramente chiedendo come mai Se ricordiamo bene abbiamo messo la cartella dello script all'interno della directory di Apache; a
ci sono tutti quei quadratini neri...il file è praticamente illeggibile. questo punto assicuriamoci che il webserver e il database siano attivi e apriamo il browser;
Facciamo un breve excursus: il Notepad, come sappiamo, è un'applicazione per documenti di testo ( digitiamo http://localhost/phpadmin e dovremmo trovarci davanti ad una pagina divisa in due
quindi non dovrebbero esserci problemi) ma c'è da aggiungere che il file che abbiamo aperto è stato frames: a sinistra il nome di due database impostati di default (mysql e test) mentre a destra i vari
compilato su un sistema operativo diverso da Windows...probabilmente UNIX o derivati di esso; comandi che ci permettono di interagire per creare, modificare o cancellare tabelle.
ecco quindi il perchè di quei caratteri strani...stiamo facendo eseguire a Notepad un file compilato Il database Mysql non va assolutamente cancellato o modificato... contiene, infatti, alcuni dati per
l'installazione del database stesso. Per i le prove abbiamo a disposizione il db Test o, ancora più
HTML.IT – Guide PHP 11 HTML.IT – Guide PHP 12
semplicemente, possiamo crearne di nuovi. 8. Sintassi generale del linguaggio
Io mi fermo qui; lo scopo di questa guida è stato raggiunto: avere pronti tutti gli strumenti per
testare php in locale; adesso tocca a voi...non vi resta che iniziare a fare le prime prove...magari I tag principali usati da Php
dopo aver letto un buon libro o aver seguito i tutorial di questo sito.
L'unico consiglio che posso darvi è di non avere timore di provare; se qualcosa dovesse andare
storto potete sempre reinstallare tutto...ormai avete imparato come si fa no? 9. I commenti e la loro importanza

Percorso consigliato di Giangiacomo Patteri Quali sono e come si utilizzano, all'interno del codice, i commenti
Principiante info@gp3italia.com
10. Variabili
Guida introduttiva alle funzioni e alla struttura del modulo Php
Le variabili in Php: come sono strutturate e quale la loro importanza

1. Premessa a Mysql 11. Approfondimento: Variabili dinamiche

Che cos'è Mysql e come funziona? Metodi di assegnazione delle variabili dinamiche

2. Chiusura di una connessione Mysql 12. Operatori

Ultima fase per concludere uno script Che cosa sono e come si utilizzano gli operatori in Php

3. Cos'è PHP? 13. Controllo del flusso: nozioni generali

Quando nasce e come si sviluppa questo linguaggio Come controllare l'esecuzione delle variabili

4. Funzionamento del PHP: lato client, lato server 14. Controllo del flusso: if

Cosa significa che Php lavora lato server e non lato client? Sintassi dell'istruzione If

5. Perchè scegliere PHP? 15. Controllo del flusso: while

Perchè molta gente sceglie Php? Sintassi dell'istruzione While

6. Installazione di php4 e Apache sotto Linux 16. Controllo del flusso: for

Installare Apache su sistemi operativi Linux Sintassi dell'istruzione For

7. Configuriamo PHP attraverso il php.ini 17. Gli array

Personalizzare alcuni aspetti di php attraverso il file php.ini Analisi della struttura e sintassi degli Array

18. Personalizziamo il codice: le funzioni

HTML.IT – Guide PHP 13 HTML.IT – Guide PHP 14


Le funzioni come come comando per effettuare un' operazione Mysql è un database relazionale open source.
Prima di spiegare le varie caratteristiche di Mysql occorre anzitutto spiegare cos'è un database e
perchè viene utilizzato nelle appicazioni web.
19. Installazione di Mysql: Linux
Utilizzando la fantasia potremo paragonare i database ad una stanza piena di schedari. In altre
Vediamo come installare un database su SO Linux parole un database ci aiuta a tenere ordinati i nostri dati e poterli raggiungere in ogni momento e da
qualsiasi parte.

20. Installazione di Mysql: Win32 I database naturalmente non vengono utilizzati solo in ambito web ma oggi in ogni azienda
troviamo svariati database per organizzare fatture,ordini,ecc.
Installare Mysql su Windows Per il nostro scopo ( costruire pagine web dinamiche ) i database ci aiutano ad organizzare i tanti
dati che possiamo raccogliere ( si pensi ad una mailing list o un forum ) oppure per ordinare quello
che vogliamo esporre ( si pensi ad un sito di e-commerce ).
21. Mysql: organizzazione interna
Perchè PHP e Mysql?
Analizziamo la struttura di un database
Mysql è un database molto veloce e professionale. Consente il salvataggio di grandi quantità di dati
e l'accesso contemporaneo di molti utenti ( 101 ).
22. Breve introduzione a SQL Il PHP contiene al suo interno numerose funzioni per la connessione dei database Mysql e per
questo motivo che questa accoppiata sta ( sopratutto negli ultimi anni ) avendo un successo enorme.
Storia del linguaggio creato da IBM
Nel corso delle nostre lezioni sulla copia Mysql-PHP vedremo come iniziare a scrivere i nostri dati
all'interno del database Mysql e come inserire i dati presenti nel database all'interno delle nostre
23. Prima Fase: connessione a Mysql pagine.

Come ci si connette ad un database Prima di iniziare una affermazione è d'obbligo.


Molto spesso ( all'inizio ) si confonde SQL con Mysql.
SQL non è una tipologia di database ma il linguaggio utilizzato per connettersi ad essi. Anche
24. Tabelle e dati in Mysql Mysql utilizza SQL per dialogare con il resto del mondo. Utilizzando ancora la fantasia potremo
dire che mentre Mysql rapresenta vari schedari in cui sono presenti i dati, SQL è il veicolo con il
Creazione delle tabelle e tipologia dei dati quali questi dati vengono messi nelle nostre mani.

25. Manipolazione dati: lettura, inserimento Installazione di Mysql: Linux

Impariamo ad inserire i dati nel database


Installare Mysql è molto semplice, sia sotto win32 sia sotto Linux. Potete scaricare i pacchetti per
questi due sistemi direttamente dal sito del mysql ( www.mysql.com ).
26. Manipolazione dati
In Linux, una volta scompattato il pacchetto nella vostra directory ( assicuratevi sempre di essere
Imparare a modificare e cancellare record amministratori di sistema ) non vi resta che far partire lo script che in automatico genera il make
file:

./configure[invio]
27. Altre funzioni PHP-Mysql

Analizziamo altre funzioni di importanza rilevante riguardo ai database Mysql


se volete installare Mysql in una directory diversa da quella di default potete scrivere:

./configure --prefix=[percorso e nome della directory in cui volete installare Mysql]


Premessa a Mysql

HTML.IT – Guide PHP 15 HTML.IT – Guide PHP 16


mysqladmin -u root shutdown

Quando lo script finisce la configurazione automatica potete installare i file con:


Nei sistemi Win32 la configurazione del PHP non va cambiata in quanto le funzioni per il Mysql
make [invio] vengono attivate in automatico durante l'installazione.

e Mysql: organizzazione interna


make install [invio]

Se non avete mai usato o visto un database questa lezione cercherà di spiegarvi in parole semplici
come è organizzato il database Mysql.
Una volta installato inizializzate il database creando delle tabelle di sistema: spostatevi nella
directory in cui avete installato Mysql, accedete alla sottodirectory /bin ed eseguite: Come possiamo vedere dall'immagine:
./mysqk_install_db

Infine non vi resta che far partire il demone del mysql digitando:

./safe_mysqld &

Il simbolo & serve per far eseguire il demone in background.


Se non ricevete errori durante l'avvio del demone Mysql è stato installato ed avviato con successo
nella vostra macchina. Non ci rimane che abilitare le funzioni nel PHP per il Mysql: dobbiamo
ricompilare PHP.

Andiamo nella directory dove si trovano i sorgenti del PHP e riconfiguriamo l'engine in questo
modo:
Un database è organizzato in tabelle che possono avere svariate colonne organizzate in righe.
./configure --prefix-use-mysql=[directory in cui avete installato Mysql] [invio]
I nostri dati vengono inseriti nei campi con una catalogazione ordinata per colonne.
rinstalliamo PHP scrivendo: In una ipotetica Mailing List costruiremo una tabella con una colonna chiamata e-mail ed all'interno
dei campi di quella colonna potremo inserire tutti gli indirizzi dei nostri utenti.
make [invio]

Durante l'inserimento, se la colonna è presente Mysql creerà una nuova riga per ogni dato che noi
e inseriamo.
make install [invio]
Naturalmente questo è un piccolo esempio scolastico. Un database articolato potrà avere più tabelle
organizzate in più colonne collegate tra di loro.
Installazione di Mysql: Win32 Per accedere al database, inserire i dati, modificarli e qualsiasi altra azione utilizzeremo le funzioni
che PHP ci mette a disposizione nel suo corredo di funzioni. Assieme a PHP utilizzeremo SQL che
sarà il linguaggio che utilizzeremo per interfacciare PHP con Mysql.
L'installazione e l'esecuzione di Mysql nei sistemi Win32 è semplificata rispetto all'installazione per
Linux in quanto l'eseguibile che scaricate da www.mysql.com si occupa di installare Possiamo anticipare già da ora come deve essere organizzata una conessione al database.
automaticamente i file. Per poter prendere i dati dal nostro database occorre stabilire anzitutto una connessione con questo,
pensando ancora una volta a Mysql come una stanza contenente tutti i nostri dati quando
Terminata l'installazione ( la cartella di installazione di default è c:/mysql ) per avviare mysql instauriamo una connessione non stiamo facendo altro che aprire la porta di questa ipotetica stanza.
dovremo accedere alla sottodirectory c:/mysql/bin attraverso DOS e digitare quanto segue: Una volta connessi possiamo inserire,modificare,cancellare i dati, le colonne, le tabelle del
start mysqld-opt --skip-name-resolve --skip-grant-tables --language=italian [invio]
database.
Quando finiamo di fare tutte le operazioni dobbiamo chiudere la connessione ed liberare le risorse
Da questo momento Mysql è in esecuzione in Background nel sistema, per terminare l'esecuzione
del sistema per altri utenti.
digitare quanto segue sempre da DOS e sempre al'interno della cartella bin:

HTML.IT – Guide PHP 17 HTML.IT – Guide PHP 18


Nelle precedenti lezioni abbiamo visto come funziona un database Mysql ed abbiamo parlato delle
tre fasi caratteristiche di una lettura delle tabelle: connessione, manipolazione dati e disconnessione.
Queste sono le operazioni che dobbiamo memorizzare. Da ora in poi vedremo come fare questo Nell' ultima lezione abbiamo invece introdotto il linguaggio da utilizzare nella fase della
nella pratica. manipolazione dei dati.

In questa lezione e nelle successive vedremo come unire tutti questi elementi con il nostro PHP.
Breve introduzione a SQL Più volte vi ho detto che PHP contiene molte funzioni specifiche per Mysql, vedremo di esaminare
le più importanti ed impareremo ad inserire modificare i nostri dati.

Quasi tutti i database presenti sul mercato per comunicare con l'esterno utilizzano il linguaggio La prima cosa da fare è la connessione al Mysql. A questo riguardo PHP ci fornisce una funzione
creato dalla IBM molti anni fa che va sotto il nome di SQL. apposita: mysql_connect.

Anche PHP per comunicare e raccogliere i dati di un database Mysql utilizza SQL. Questa lezione La sintassi della funzione di connessione è la seguente:
non vuole addentrarsi nel mondo del SQL ma solo riassumere tutte le funzioni di questo linguaggio
riguardo l'interrogazione dei database. <?php
All'interno di html.it potete trovare una guida molto esaustiva di questo linguaggio molto semplice. mysql_connect(nome_host,nome_utente,password);
?>
SQL raccoglie al suo interno delle istruzioni abbastanza intuitive rivolte al database che risponde
alla richiesta inviando i dati:
Il nome utente e la password sono indispensabili in quanto Mysql è un database molto sicuro e non
Poniamo di avere una tabella chiamata "ordini" formata da 2 colonne denominate rispettivamente si può accedere ad esso senza aver prima creato un account.
"ordini_da_eseguire" e "ordini_eseguiti": Se state provando Mysql in locale potete tranquillamente lasciare vuoti questi 2 campi. Se invece
dovete provare i vostri script nel vostro sito dovete richiedere lo User e la Password ai vostri
con l'istruzione: amministratori di sistema. Per quanto riguarda il nome dell'host esso è quasi sempre localhost, per
SELECT * FROM ordini_eseguiti
maggiore sicurezza potete richiedere anche questo dato ai vostri amministratori di sistema.

Vediamo uno script completo per la connessione:


chiedo al database di inviarmi tutti i dati contenuti della tabella "ordini", il segno * sta per tutti. <?php
Avrei che potuto richiedere i dati di una sola colonna specificando il nome della colonna:
// script per la connessione a mysql

SELECT ordini_eseguiti FROM ordini

$host = 'localhost';
in questo modo. $user = 'vostro_user';
$password = 'vostra_password';

Come potete notare le istruzioni sono molto semplici e concise. Prima di proseguire in questo mysql_connect($host,$user,$password) or die ("Non riesco a connettermi");
nostro viaggio consigliamo comunque una lettura veloce di tutti gli altri comandi SQL come:
print "Connessione eseguita";
CREATE // fine script di connessione
ALTER
INSERT ?>
ORDER BY
JOIN
CROSS JOIN
RIGHT JOIN
INTO La funzione "die" ci permette di stampare a video la scritta compresa tra virgolette nel caso la
WHERE
connessione non vada a buon fine. Nel caso PHP non riesca a connettersi a Mysql vedremo la scritta
"Non riesco a connettermi al database", nel caso contrario vedremo la scritta "Connessione
eseguita".

Prima Fase: connessione a Mysql Abbiamo fatto per metà la prima fase, ora per manipolare i nostri dati dobbiamo selezionare il
database da utilizzare.
Mysql permette, per ogni account, illimitati database.

HTML.IT – Guide PHP 19 HTML.IT – Guide PHP 20


Dobbiamo prima creare una tabella nella quale inserire i dati. A questo scopo utilizzeremo SQL.
Se non abbiamo ancora creato nessun database dobbiamo prima crearlo e poi selezionarlo,
utilizzeremo quindi varie funzioni PHP nel prossimo script: Una premessa è d'obbligo prima di iniziare a creare la nostra tabella: è buona abitudine studiare il
database e l'organizzazione interna delle nostre tabelle a tavolino prima di cominciare a costruire lo
<?php script. Un buon database con una buona organizzazione interna è senz'altro più facile da manipolare
// script per la connessione, creazione e selezione di un database e leggere ed inoltre questo migliora la velocità di connessione e manipolazione dei dati.
// Mysql

Ogni tabella dovrà essere identificata da un nome univoco in quanto non è concepita la presenza di
// Mi connetto a Mysql
due tabelle con lo stesso nome all'interno di un database.
$host = 'localhost'; Per quanto riguarda i campi, nella loro creazione bisogna specificare il tipo di dato che il campo
$user = 'vostro_user';
$password = 'vostra_password'; dovrà contenere, Mysql supporta una moltitudine di tipologie dei campi a seconda dei dati che si
dovranno inserire, vediamo quali sono i tipi più importanti.
mysql_connect($host,$user,$password) or die ("Non riesco a connettermi");
print "Connessione eseguita"; Per quanto riguarda i numeri reali Mysql supporta svariati tipi di archiviazione, la differenza fra i
// Creo il database "prova"
tipi elencati sotto non è nel formato del numero che andrà inserito nel campo ma la grandezza del
numero( più grande è il numero è più è la memoria utilizzata ):
mysql_create_db("prova")or die ("Non riesco a creare il database");
TINYINT 1 byte
SMALLINT 2 byte
// seleziono il database appena creato MEDIUMINT 3 byte
INT 4 byte
BIGINT 8 byte
mysql_select_db("prova") or die ("Non riesco a selezionare il database");
print "Connessione, creazione, selezione del database eseguita";

// Fine script Per quanto riguarda i numeri in virgola mobile abbiamo invece le seguenti tipologie di
archiviazione:
?>
FLOAT 4 byte
DOUBLE 8 byte

Con questo script abbiamo completato la fase di connessione ad un database Mysql.

Abbiamo visto due nuove funzioni PHP: Man mano che utilizzerete Mysql imparete a scegliere il tipo di dato più utilizzato per il campo
della tabella, per i nostri esempi sceglieremo il tipo INT per l'archiviazione dei dati numerici.
mysql_create_db("nome_database");
Per quanto riguarda le stringhe sono due i tipi di campo più utilizzati:

CHAR(numero_caratteri)
e VARCHAR

mysql_select_db("nome_database");

Come possiamo intuire mentre in un campo CHAR la lunghezza è fissa e viene stabilita da noi
durante la creazione della tabella nel campo VARCHAR il numero di caratteri è variabile e non
Notate che in ogni funzione abbiamo inserito l'istruzione die, questo ci aiuta in caso di problemi ad bisogna specificare preventivamente il numero di caratteri massimo che dovrà contenere il campo.
identificare subito il perchè degli errori e la loro risoluzione. Naturalmente i campi di tipo VARCHAR occuperanno più memoria e la lettura al loro interno
Nella prossima lezione analizzeremo la manipolazione dei dati. impiegherà qualche decimo di secondo in più rispetto ai campi CHAR.

Esistono vari altri tipi di campo ma una loro trattazione esaustiva necessiterebbe di svariate pagine,
tutta la documentazione sui tipi di dati supportati da Mysql potete leggerla in italiano nel sito
Tabelle e dati in Mysql www.mysql.com.

Un altro motivo dunque per cui dobbiamo organizzare anticipatamente il database è anche per la
Ora che ci siamo connessi al database da noi scelto possiamo eseguire qualsiasi azione al suo scelta del tipo di campo sapendo che questa influisce sulle prestazioni delle tabelle.
interno: creazione/cancellazione tabelle, creazione/modifica/cancellazione dati all'interno dei campi.
Per capirci: è uno spreco di spazio e di prestazioni dichiarare un tipo di campo VARCHAR se

HTML.IT – Guide PHP 21 HTML.IT – Guide PHP 22


sapete già che quel campo non potrà contenere un numero determinato di caratteri. nome e il cognome dell'utente e la terza serve per l'indirizzo e-mail. Vediamo ora i comandi SQL e
le funzioni PHP per inserire i dati.
Supponiamo di voler costruire una tabella che raccolga una serie di indirizzi e-mail per una
eventuale mailing-list del nostro sito. Dovremo costruire una tabella con 3 colonne: una colonna <?php
raccoglierà un numero identificativo che ci aiuti ad indicizzare i dati, una colonna per il nome e // script per inserire i dati nella tabella mail
// per comodità supponiamo di esserci già connessi al database
cognome degli utenti ed infine la colonna che conterrà le e-mail: il codice sarà questo:

<?php
// voglio inserire 1 nuovi indirizzi, scriveremo:

// script per la creazione di una tabella per la catalogazione delle mysql_query("insert into mail (id_utente, nome_cognome,mail) values ('1','Mario
// e-mail per una mailing list Rossi','mario@suosito.com')");

// per non appesantire il codice supponiamo di esserci già connessi


// al databese con le funzioni viste nelle lezioni precedenti // fine script
?>
// scrivo l'istruzione SQL per la creazione della tabella

$sql= "CREATE TABLE mail (


id_utente INT(10) NOT NULL,
Con questo piccolo script abbiamo inserito un nuovo indirizzo all'interno della tabella mail. Non
nome_cognome CHAR(100) NOT NULL, bisogna specificare a Mysql di creare un nuovo campo in quanto questo avviene in automatico con
mail CHAR(50) NOT NULL)";
l'uso dell'istruzione SQL "insert into".
// Invio l'istruzione SQL a mysql
mysql_query("$sql") or die ("Non riesco a creare la tabella"); Vi voglio riproporre la sintassi dell'istruzione INSERT INTO perchè è una delle istruzioni più
print " La tabella mail è stata creata con successo!";
utilizzate e la più complessa perchè molto articolata:
// fine dello script
INSERT INTO nome_tabella (nome_campi) values ( dati_da_inserire_nei_campi);
?>
Notate che l'elenco dei dati presente nella seconda coppia di parentesi tonde deve corrispondere
all'ordine dei campi che abbiamo inserito nella coppia delle prime parentesi.
In questo modo abbiamo creato la nostra tabella con tre colonne. Vorrei soffermarmi un attimo Ripetermo lo script tutte le volte che dobbiamo inserire un nuovo campo.
sull'istruzione SQL che per comodità abbiamo inserito all'interno di una variabile e vorrei anche
farvi notare forse la funzione per l'invio delle istruzioni SQL al database: mysql_query. Ora che la nostra tabella contiene qualche dato possiamo leggere al suo interno per sapere quali dati
ci sono al suo interno, per far questo utilizzeremo l'istruzione SQL "SELECT":
La sua sintassi è molto semplice:
<?php
mysql_query("istruzioni SQL"); // script per leggere i dati contenuti in un campo della tabella
// mail
// per comodità supponiamo di esserci già connessi al database

Il risultato dipenderà da cio che si chiede di fare al Mysql. $dati = mysql_query("select * from mail");
$array = mysql_fetch_array($dati);

Nelle prossime lezioni vedremo come manipolare i dati all'interno della tabella che abbiamo appena // fine script
creato.
?>

Manipolazione dati: lettura, inserimento L'istruzione SELECT chiede i dati di una riga della tabella che abbiamo selezionato nell'istruzione
FROM ( nel nostro caso la tabella si chiama mail ). Per poter utilizzare i dati che Mysql invia
dobbiamo utilizzare la funzione mysql_fetch_array che crea un array associativo che ha come
Ora che abbiamo creato la nostra tabella possiamo iniziare ad inserire i dati. Ripeto che stiamo indice il nome delle colonne, continuando lo script avremo che per visualizzare i dati che abbiamo
cercando di costruire un database che memorizzi tutti gli indirizzi e-mail di colore che si iscrivono. estrapolato dal database scriveremo:
Nelle precedenti lezioni abbiamo costruito una tabella formata da tre colonne: la prima che
memorizza un numero identificativo per ogni dato che inseriremo, la seconda che memorizza il <?php
// codice per leggere i dati contenuti in un campo

HTML.IT – Guide PHP 23 HTML.IT – Guide PHP 24


print "Contenuto della colonna id_utente: $array[id_utente] ";
Con questo script finchè la tabella mail non sarà vuota PHP creerà l'array associativo contenente i
print "Contenuto della colonna nome_cognome: $array[nome_cognome] "; dati letti dal database.

print "Contenuto della colonna mail: $array[mail] ";

?>
Manipolazione dati

Naturalmente questo script legge una riga per volta e se nella istruzione SELECT non selezionate
nulla Mysql restituirà i dati dell'ultima riga inserita, diversamente potete controllare il flusso dei dati Le ultime importanti nozioni sulla manipolazione dei dati inseriti nel database riguardano la
Mysql con l'istruzione WHERE: modifica e la cancellazione dei dati. A questo scopo, rispetto agli script visti precedentemente
riguardo l'inserimento cambiano solo le istruzioni SQL. Per la modifica utilizzeremo l'istruzione
<?php UPDATE mentre per la cancellazione l'istruzione DELETE.
// Volendo visualizzare i dati dell'utente Mario Rossi avrei scritto
// in questo modo l'istruzione SQL
Consiglio vivamente di utilizzare queste due istruzioni con cautela per non rischiare di cancellare o
modificare tutti i dati che avete inserito all'interno della tabella.
$dati = mysql_query("SELECT * FROM mail WHERE nome_cognome='Mario Rossi");
$array = mysql_fetch_array($dati);
La modifica:

<?php
// fine script

// script per la modifica dei dati nella tabella mail


?>
// supponiamo di essere già connessi al database

$dati = mysql_query ("UPDATE mail SET mail='mario@tiscalinet.it' WHERE nome_cognome='MARIO


Nella nostra lingua l'istruzione SQL risulterebbe così organizzata: ROSSI'");
"Seleziona (SELECT) tutto (*) dalla tabella ( FROM ) mail dove ( WHERE ) il la colonna // fine script
nome_cognome è uguale a Mario Rossi.

Questo script va bene nel caso dovessimo leggere solo una riga della tabella, nel caso in cui ?>
vogliamo invece leggere tutto il contenuto della tabella dovremo aggiungere un ciclo while così
organizzato:
L'istruzione UPDATE è molto semplice, ricordate sempre di specificare il WHERE perchè
<?php altrimenti la modifica verrà eseguita in tutti campi della tabella mail ( per questo consiglio l'uso con
// script per leggere i dati contenutiin tutti i campi della tabella cautela ).
// mail
// per comodità supponiamo di esserci già connessi al database
Vediamo la sintassi dell'istruzione UPDATE:
$dati = mysql_query("select * from mail");

while ( $array = mysql_fetch_array($dati)) {


UPDATE nome_tabella SET nome_colonna='nuovo_valore' WHERE
nome_colonna='identificativo_colonna';
print "Contenuto della colonna id_utente: $array[id_utente] ";
Nella creazione della tabella abbiamo all'inizio previsto una colonna che contiene l'dentificativo
print "Contenuto della colonna nome_cognome: $array[nome_cognome] "; numerico del campo. Questo indice è importantissimo per le istruzioni di modifica e di
cancellazione perchè in questo modo ogni riga ha un numero univoco e non si rischia di
print "Contenuto della colonna mail: $array[mail] "; cancellare/modificare altre righe. Utilizzando l'identificativo avremo scritto:
} <?php

// fine script // script per la modifica dei dati nella tabella mail
// supponiamo di essere già connessi al database
?>

HTML.IT – Guide PHP 25 HTML.IT – Guide PHP 26


$dati = mysql_query ("UPDATE mail SET mail='mario@tiscalinet.it' WHERE id_utente='1'"); approfondite solo sul Mysql:
// fine script
mysql_num_rows()
Restituisce il numero di righe interessate dall'istruzione SQL:
?>
<?php
// mysql_num_rows
Molto più semplice e senza rischio d'errore ( pensate se ci fossero stati due Mario Rossi all'interno
della tabella mail). $dati = mysql_query("SELECT * FROM mail");
$numero_righe = mysql_num_rows($dati);
L'istruzione DELETE permette di cancellare un intera riga dalla tabella. Utilizzate questa istruzione
con molta cautela in quanto Mysql non chiede conferme, neanche per la cancellazione di grosse ?>
quantità di dati:

<?php
mysql_insert_id()
// script per la cancellazione di tutti i dati nella tabella mail Restituisce l'ultimo id ( se presente ) della riga interessata dall' ultima operazione di INSERT:
// supponiamo di essere già connessi al database

<?php
$dati = mysql_query ("DELETE FROM mail");
// mysql_insert_id
// fine script
$dati = mysql_query("INSERT INTO mail (id_utente, nome_cognome, mail values ('2', 'Mario
Rossi', mario@tiscalinet.it') ");
?> $ultimo_id = mysql_insert_id();

?>

Con questo script cancelliamo tutte le righe presenti all'interno della tabella mail. Nel caso
volessimo cancellare una determinata riga inseriremo nell'istruzione SQL l'istruzione WHERE,
come segue: mysql_drop_db
Elimina un database Mysql:
<?php
<?php
// script per la cancellazione di una riga nella tabella mail // mysql_drop_db
// supponiamo di essere già connessi al database
mysql_drop_db("nome_database_da_eliminare");
$dati = mysql_query ("DELETE FROM mail where id_utente='1'");
?>
// fine script

?> mysql_list_dbs
Restituisce la lista dei database presenti nel server Mysql:

<?php
Questo script cancellerà la riga in cui l'id_utente è uguale a 1.
// mysql_list_dbs
$connessione = mysql_connect($host, $user, $password);
mysql_list_dbs("$connessione");
Altre funzioni PHP-Mysql
?>

PHP contiene molte funzioni e, per non confondere troppo le idee, vi proponiamo un semplice
elenco di quelle più importantanti impegnandoci nel breve futuro a proporvi altra guide pià

HTML.IT – Guide PHP 27 HTML.IT – Guide PHP 28


mysql_list_tables print "Contenuto colonna mail: $array[mail]";
Restituisce la lista delle tabelle presenti nel database selezionato:
}

<?php // libero la memoria occupata dall'istruzione SELECT

// mysql_list_tables mysql_free_result($dati);
// chiudo la connessione al server Mysql
mysql_list_tables("nome_database");
mysql_close();

?>
// Fine script

Questo l'elenco delle funzioni più usate, potete trovare l'elenco completo delle funzioni sul sito del
PHP www.php.net nella sezione funzioni per Mysql ?>

Da notare che la funzione mysql_close può non contenere argomenti in quanto Mysql chiuderà
Chiusura di una connessione Mysql automaticamente tutte le connessioni aperte.

Una volta conclusa la fase di manipolazione dei dati è sempre opportuno chiudere tutte le
connessioni al server Mysql e magari liberare la memoria occupata dai risultati della query SQL. Cos'è PHP?

E' buona norma specificare sempre queste due funzioni per non caricare inutilmente il server che sta
eseguendo i vostri script e dare la possibilità a tutti gli utenti di poter accedere al database. Fino a qualche anno fa il web era formato da un certo numero di pagine statiche, ossia HTML puro,
incapaci di aggiornare automaticamente i propri contenuti o consentire al visitatore di interagire con
Com ultimo esempio vi fornisco uno script completo di connessione, manipolazione e la pagina stessa.
disconnessione ad un server Mysql.
L'evoluzione del web, culminata nell'introduzione della dinamicità della pagina, ha avuto come
<?php
protagonisti i linguaggi cosiddetti "lato server" (più avanti spiegheremo il significato di questo
termine) che hanno dato quel qualcosa che ancora mancava in internet e dato la possibilità di
// Mi connetto a Mysql sviluppi che fino a qualche anno fa erano impensati.
$host = 'localhost';
Il PHP dunque è un linguaggio di programmazione (definito anche linguaggio di scripting)
$user = 'vostro_user'; utilizzato per lo sviluppo di pagine web dinamiche, uno dei più recenti in questo campo.
$password = 'vostra_password';

mysql_connect($host,$user,$password) or die ("Non riesco a connettermi"); Il PHP nasce a metà del 1994 e da allora il suo utilizzo è andato via via aumentando (grazie anche
alla sua filosofia free) ed oggi vanta qualcosa come oltre 250.000 siti che implementano questo
print "Connessione eseguita";
linguaggio.
Grazie al PHP (e a tutti gli altri linguaggi "lato server") è possibile consentire agli utenti di
// seleziono il database appena creato interagire con un ampio database, farli muovere in un negozio virtuale, prenotare online un biglietto
aereo e così via.
mysql_select_db("mail") or die ("Non riesco a selezionare il database");
print "Il database è stato selezionato"; Funzionamento del PHP: lato client, lato server
// visualizzo tutti i campi presenti nella tabella mail

$dati = mysql_query("select * from mail");


La differenza tra lato client e lato server sta tutta nel modo e da chi viene interpretata una pagina
Web quando essa viene caricata.
// inizio il ciclo while per la visualizzazione delle righe

Una breve descrizione del funzionamento del PHP può senza dubbio aiutarci a capire questa
while ($array = mysql_fetch_array($dati) {
differenza:
print "Contenuto colonna id_utente: $array[id_utente] <br>";
print "Contenuto colonna nome_cognome: $array[nome_cognome] <br>"; quando un server Web predisposto per il PHP riceve una richiesta dal browser di un client iniziano

HTML.IT – Guide PHP 29 HTML.IT – Guide PHP 30


una serie di operazioni: Il server:
Iniziamo con lo scaricare i sorgenti dai rispettivi siti ( www.apache.org , www.php.net ).
1) Legge ed individua la pagina sul server. Avremo dunque i sue file php-4.0.4pl1.tar.gz e apache_1.3.20.tar.gz.
2)Esegue le istruzioni PHP contenute all'interno della pagina ed esegue tutti i comandi PHP. Questi pacchetti contengono i file sorgente dei due programmi, prima del loro utilizzo dobbiamo
3) Rimanda la pagina risultante al Browser. compilare i vari file, assicuratevi di aver installato il compilatore del C/C++.
Scompattiamo i due file nella nostra directory personale ( ad esempio in /root ): gunzip file php-
Un esempio pratico potrebbe essere quello di una pagina in PHP che si prefigge di leggere una riga 4.0.4pl1.tar.gz ; tar xvf php-4.0.4pl1.tar.gz ; stessa cosa per Apache: gunzip apache_1.3.20.tar.gz ;
di un qualsiasi database, il server Web esegue ed ottiene la riga dal database ed invia il tutto al tar xvf apache_1.3.20.tar.gz
browser del client generando codice HTML. Dopo queste semplici operazioni avremo due nuove cartelle, apache_1.3.20 e php-4.0.4pl1.
Prima di cominciare la compilazione e l'installazione vera e propria alcune premesse sono doverose:
Per questo motivo nella pagina risultante non si può vedere nessuna traccia del codice PHP, esso è
stato già interpretato e "trasformato" in HTML dall'interprete ( il PHP, a differenza di linguaggi - per installare questi due pacchetti dovete avere i permessi di amministratore ( ossia accedere al
come il C o il C++ è un linguaggio interpretato e non compilato ). sistema come "root" );
- installeremo il php direttemente all'interno dell'Apache e non come modulo;
Come fa il server a capire quando una pagina contiene del codice PHP? Molto semplice, dal - Se avete un pc datato abbiate un pochino di pazienza e non interrompete mai la compilazione una
formato della pagina. volta iniziata;
- Tutte queste operazioni devono essere eseguite dalla riga di comando;
Ogni pagina che contiene PHP deve avere un formato opportuno ( .php o .php3 o .php4 ), più avanti
vedremo come nel file di configurazione di Apache vi sia una riga che indica al server stesso come Cominciamo: entriamo nella cartella dell'apache e scriviamo:
trattare questo tipo di pagine.
./configure -prefix="path/in/cui/vogliamo/installare/apache" [invio]

Perchè scegliere PHP?


Attendiamo che il file di configurazione crei il Makefile.
Andiamo ora alla cartella del php e scriviamo:
Come abbiamo visto nella prima lezione il PHP non è l'unico linguaggio interpretato presente nel
./configure -with-apache="path-dei-sorgenti-di-apache" -enable-track-vars-
mondo Web con cui si possono eseguire pagine dinamiche, perché dunque scegliere questo prefix=path/in/cui/vogliamo/installare/php [invio]
linguaggio per soddisfare le proprie esigenze?
Varie risposte possono essere date: in primo luogo PHP è un linguaggio molto semplice da Quando il makefile è stato creato scriviamo:
utilizzare, a cominciare dalla sintassi derivata direttamente da veri linguaggi di programmazione
come C/C++, Perl, Java. make [invio];
In secondo luogo, nonostante esso sia un linguaggio interpretato può vantare prestazioni notevoli
ulteriormente migliorate nella versione 4. e
Terzo, il PHP è un linguaggio molto flessibile che ci consente di fare davvero tutto, dalla creazione
di immagini alla manipolazione e creazione di documenti in pdf, dalla gestione dei cookies alla make install [invio];
elaborazione dei form HTML e il supporto di molteplici tipologie di database.
Se l'operazione di compilazione non da nessun errore dovreste aver installato con successo il PHP.
Forse la vera forza del PHP sta senz'altro nella gestione dei database, con poche righe di codice è
possibile accedere qualsiasi database, estrapolare i dati che ci interessano e inserirli nella pagina Ora occorre tornare nella cartella dei sorgenti di apache per ultimare la compilazione del Web
Web. server, anche qui scriviamo:
Un altro punto a favore del PHP è la sua natura OpenSource, quindi gratuita. Infine possiamo far
rilevare l'alta portabilità del PHP; esso gira su tutti in principali Web server ed in linea di massima ./configure -enable-track-vars [invio]
non dobbiamo apportare nessuna modifica al codice quando lo spostiamo da un Web server ad un
altro ( la differenza è tra le piattaforme Microsoft e quelle Linux/Unix ). dopo aver riconfigurato Apache possiamo passare alla sua compilazione ed installazione:

Installazione di php4 e Apache sotto Linux make [invio]


make install [invio]

Alla fine della compilazione ( se tutto è andato bene ) dovreste avere un messaggio di successo.
L'installazione sotto Linux è anch'essa molto semplice ( a mio parere più semplice dell'installazione
sotto Win32 ).
Fate partire Apache entrando nella sua sottocartella "bin" e digitando:
Chiunque avesse poca familiarità con questo sistema operativo consigliamo di seguire
scrupolosamente queste le istruzioni di seguito descritte. ./apachectl start

HTML.IT – Guide PHP 31 HTML.IT – Guide PHP 32


Vi consiglio di copiare questo file ( apachectl ) nella vostra directory "/bin" in modo da poter far Affinché l’interprete PHP riesca a distinguere all’interno del codice il linguaggio da interpretare ed
partire l'apache da qualsiasi posizione all'interno di Linux. eseguire ( PHP ) dall’HTML occorre utilizzare dei TAG particolari:
Vediamo un piccolo esempio:
Configuriamo PHP attraverso il php.ini
<table>
<tr>
<td>
Prima di proseguire il nostro viaggio nell'immenso mondo del PHP occorre fermarsi un attimo per <?php print “ Ciao”; ?>
descrivere il funzionamento del file che lo configura: php.ini. </td>
</tr>
</table>
Attraverso questo file potete personalizzare alcune importanti impostazioni o abilitare/disabilitare
molte funzioni del PHP. Queste righe di codice stamperanno in una tabella la parola “Ciao”. In rosso possiamo distinguere il
In questa lezione descriveremo solo le voci più importanti del file lasciando a voi il compito di codice PHP delimitato dai tag <?php e ?>.
esplorare le altre sezioni presenti quando avrete una maggiore dimestichezza con il linguaggio. L’interprete PHP sa che tutto ciò che si trova all’interno di questi delimitatori deve essere
La prima voce che troviamo è "Language Options", interpretato ed eseguito.
nella prossima lezione spiegheremo il significato e l'uso di questa parte. Tutto ciò che si trova al di fuori dei tag PHP viene normalmente eseguito dal browser.
Altra parte molto interessante è quella intitolata "Resource Limits". Per tutti coloro che intendono avvicinarsi al mondo del PHP è comunque indispensabile una ottima
Nella prima voce possiamo settare il numero di secondi per l'expired di uno script ( 30 secondi di conoscenza dell’HTML in quanto, una volta che lo script viene interpretato, il PHP restituisce
default ), nella seconda voce potete scegliere la quantità di memoria RAM da riservare al PHP. semplice codice HTML.
Nella parte successiva, "Error Handing and logging", potete personalizzare i messaggi di errore in Esiste anche la possibilità di utilizzare altri tag per distinguere il codice dall’html:
caso di sbagli nel codice.
Vi consiglio di lasciare tutto com'è per ora, man mano che capirete gli sbagli che farete durante la <? …… ?>
scrittura del codice potete personalizzare i messaggi d'errore.
Nella sezione "Paths e Directories" ci sono varie voci molto interessanti da personalizzare: doc_roor Questa sintassi è molto simile alla precedente ma il suo uso deve essere abilitato all’interno del
à La cartella che contiene le pagine in php. PHP3.ini.
extension_dir à la directory in cui si trovano le estensioni per altri servizi del PHP ( solo per Win32 Nella sezione “Language Option” dovete modificare il parametro “short_open_tag” ed inserire
). “On”.

Nella sezione "File Upload" potete settare tutti i valori per l'upload dei file direttamente dalle pagine <Script language=”php” ………</script>
web: File Upload à Settato su "ON" permette l'upload dei file , diversamente per vietare questa
possibilità scrivere "OFF". Questi tag sono attivi di default e possono risultare molto utili in quegli editor HTML visuali che
non conoscono le estensioni PHP.
Upload_tmp_dir setta la cartella in cui riversare i file che arrivano dall'esterno, lasciate questo
valore vuoto se volete settare all'interno dello script il nome di questa cartella. <% ……. %>

Upload_max_filesize setta la grandezza massima dei file permessa nell'upload in mega. Per tutti Questa è la sintassi utilizzata dall’ASP e deve essere attivata per poter essere utilizzata. Sempre nel
coloro che hanno installato PHP sotto Win32 nella sezione "Windows Extension" si possono PHP3.ini nella sezione “Language Option” dovete modificare il parametro “asp_tags” su “On”.
abilitare/disabilitare i file dll che regolano alcuni servizi. Altra regola fondamentale che voglio accennarvi ( ma che riprenderemo più volte nel corso della
Troverete all'interno dell'elenco i file per abilitare l'IMAP, la manipolazione/ creazione dei pdf, la guida ) è il segno di fine comando composto dalle “;”.
manipolazione delle gif e vari altri servizi. Uno degli errori più diffusi per tutti coloro che si avvicinano per la prima volta al PHP è la
Per abilitare il servizio occorre cancellare il punto e virgola iniziale, per disabilitarlo aggiungere il dimenticanza del segno di fine comando che, generando un errore, non fa concludere l’esecuzione
punto e virgola all'inizio. della pagina.
Nel php.ini sono presenti vari altri parametri: gestione della posta; direttive per mysql; direttive per
msql; gestione dei cookies; gestione dei log; Consiglio inizialmente di lasciare inalterato questo file Anche in presenza di errori di questo tipo ( chiamati errori di sintassi ) il PHP ci viene incontro
( pena il non funzionamento del PHP ) e di modificare certe voci solo dopo una discreta conoscenza fornendoci un determinato messaggio di errore. Se trovate un "parse error" molto probabilmente
del linguaggio. avete fatto un errore di sintassi come quello della dimenticanza del ; alla fine dell'istruzione.
Nelle lezioni dedicate al MySQL vi elencherò le voci che potete modificare per rendere ancora più
efficiente questo servizio. I commenti e la loro importanza

Sintassi generale del linguaggio


Vi chiederete perché iniziamo la trattazione del linguaggio proprio parlando dei commenti.

HTML.IT – Guide PHP 33 HTML.IT – Guide PHP 34


Semplicemente perché credo che siano importantissimi, sia per chi inizia a programmare, sia per i Le variabili in PHP vengono indicate con il segno “ $ “ prima del nome, vediamo altri esempi:
programmatori esperti.
I commenti rendono il codice più leggibile e modificabile, anche dopo tempo. I commenti non Somma di due numeri:
vengono eseguiti dall’interprete per cui non risparmiatevi in quanto una riga in più non cambierà la
velocità di esecuzione dello script e nello stesso tempo vi aiuta a seguire il codice passo passo in <?php
// Programma per la somma di due numeri
tutte le operazioni che eseguite. $a = 5;
$b = 5;
Il PHP supporta vari tipi di commenti: $c = $a + $b;
print $c;
?>
quelli in stile C++:

// Il risultato di questo script sarà 10, vediamo di commentarlo assieme.


Nelle prime 2 righe definisco rispetivamente che il contentuto delle variabili $a e $b sia 5, nella
commento in PHP terza riga definisco che il valore della variabile $c sia uguale alla somma di $a e $b ed infine
stampo a video il contenuto di quest’ultima.
i L’uso delle variabile è molto semplice grazie anche ad alcune particolarità del PHP che ad esempio
non ci obbliga a dichiarare preventivamente le variabili che intendiamo utilizzare all’interno del
commenti in stile C: programma ma quest’ultima avviene in contemporanea con l’assegnazione dei valori alla variabile
stessa.
/* Oltre a contenere numeri ( come già detto ) una variabile può benissimo contenere caratteri e frasi:

<?php
Commento in PHP // Programma per la stampa di una stringa
$a = “Ciao Mondo”;
*/ print $a;
?>

ed i commenti in stile Perl: Questo script stamperà la frase “Ciao Mondo”.


#
Approfondimento: Variabili dinamiche
Variabili
Il PHP pemette vari utilizzi per quanto riguarda le variabili, nelle prossime lezioni parleremo degli
array mentre in questa lezione introduciamo le variabili dinamiche.
Le variabili possono essere viste come dei contenitori di dati ( numeri o lettere ) che vengono Partiamo dall'assegnazione tradizionale di una variabile:
memorizzate all’interno di uno script per essere poi riprese durante l’esecuzione dello stesso. Le
variabili sono alla base di tutti i linguaggi di programmazione ed il loro buon utilizzo ci aiuta a $variabile = "Ciao";
rendere lo script più leggero ed efficiente.
Ad ogni variabile ( individuata con il suo nome ) corrisponde un certo valore attribuito da noi stessi. Poniamo ora il caso di avere l'esigenza di creare una nuova variabile che abbia come nome il valore
Quindi la riga: della variabile sopra assegnata ( $variabile ).
E' possibile fare questo utilizzando le variabili dinamiche, scriveremo:
$a = 5;

$$variabile = "mondo";
ci mostra la variabile a il cui contenuto è il numero 5. Graficamente potremo anche definire così una
variabile: Con questa operazione il PHP esegue diverse operazioni: interpreta $$variabile partendo dalla parte
interna dell'espressione ( $variabile ) ed in questo modo crea una nuova variabile il cui nome è
uguale a "Ciao" ed il valore è uguale a "Mondo".
Nel PHP si possono annidare le variabili all'interno di altre variabili fino a livelli infiniti ma è
vivamente consigliato non spingersi oltre il secondo livello per non rendere il codice illeggibile ad
altre persone oltre che a noi stessi.

Operatori

HTML.IT – Guide PHP 35 HTML.IT – Guide PHP 36


Per spiegare cosa sono gli operatori ed il loro utilizzo occorre introdurre alcuni nuovi termini che
senz’altro molti di voi già hanno visto in campo matematico. Controllo del flusso: nozioni generali
In una espressione aritmetica 3 + 5 i numeri 3 e 5 sono detti operandi mentre il segno + è
l’operatore.
Gli operatori sono dei segni che ci permettono di svolgere le principali funzioni all’interno dei Fino a questa lezione ci siamo occupati delle caratteristiche generali del PHP. Abbiamo visto le
programmi PHP ( in tutti i linguaggi di programmazione sono presenti gli operatori ). variabili, gli operatori in generale ed alcune altre piccole regole su cui si basa il linguaggio.
Per esempio, il segno = ci permette di attribuire un valore ad una stringa come abbiamo visto negli Tutte le nozioni viste sinora sono basilari per iniziare a scrivere qualche semplice script ma senza il
esempi delle lezioni precedenti, ( operatore di assegnamento ) oppure il segno + ci permette di controllo del flusso non potremo mai rendere una pagina veramente dinamica.
sommare due o più numeri e così via. Vi chiederete, cosa significa controllare il flusso?
Nel PHP esistono vari tipi di operatori, vi forniamo di seguito un breve elenco che sarà oggetto di Ebbene, per rispondere a questa domanda occorre sapere che l’interpretazione e la codifica del PHP
studio e approfondimento in tutte le nostre altre lezioni. avviene seguendo un preciso ordine generale, dall’alto verso il basso e da sinistra verso destra (
nello stesso modo in cui voi state leggendo questa lezione ).
Operatori Aritmetici: In molti casi ( molto spesso ) abbiamo bisogno di controllare questa interpretazione e dirigere il
Sono gli operatori più semplici che ci permettono di svolgere le operazioni matematiche all’interno flusso a nostro piacere.
degli script. Supponiamo che si voglia eseguire un comando solo se si verifica una certa condizione oppure
ripetere un comando finché noi lo vogliamo e tante altre azioni.
$a + $b // ( + ) La somma di $a e $b
$a - $b // ( - ) La sottrazione fra $a e $b Tutte queste operazioni richiedono un controllo che va sotto il nome appunto di controllo del flusso
$a * $b // ( * ) Il prodotto di $a e $b e man mano che leggerete le prossime lezioni vi accorgerete quanto questo controllo sia utile per
$a / $b // ( / ) Il rapporto di $a e $b
$a % $b // ( % ) Il resto della divisione di $a e $b realizzare pagine realmente dinamiche.

Operatori di confronto Controllo del flusso: if


Gli operatori di confronto sono quelli che consentono di mettere in relazione tra loro due o più
espressioni:
Tutte le varie formule che troverete all’interno delle lezioni sul controllo del flusso vengono definiti
$a == $b ( == ) costrutti.
Il costrutto if permette di eseguire delle determinate operazioni solo se si verificano determinate
Confronta l’uguaglianza del valore tra $a e $b ( stesso valore ); condizioni.
Vediamo un piccolo esempio pratico.
$a != $b Poniamo il caso di voler confrontare due variabili, solo se queste due variabili sono uguali
stamperemo a video il loro valore, scrivere così:
( != ) $a e $b sono diversi;
<?php
$a=5; $b=5;
$a < $b if( $a == $b) {
print ” Il valore di a è uguale a $a”;
print ” Il valore di b è uguale a $b”;
( < ) $a è minore di $b; }
?>

$a <= $b
Prima di commentare il nostro piccolo esempio vediamo di vedere la struttura del costrutto if:
( <= ) $a è minore o uguale di $b;
if (condizione) {
blocco-istruzioni da eseguire nel caso la nostra istruzioni risulti vera.
$a > $b }

( > ) $a è maggiore di $b; Potremo quindi commentare l’esempio pratico in questo modo:
Se ( la variabile $a è uguale alla variabile $b ) allora {
$a => $b Stampami a video il valore della variabile $a e $b
}
( => ) $a è maggiore o uguale di $b; Il costrutto if risulta molto semplice a parte qualche nuova regola; come potete notare non bisogna
inserire alla fine della parentesi graffa di chiusara il segno di fine istruzioni in quanto il costrutto if
Utilizzeremo e spiegheremo nella pratica gli operatori di confronto quando affronteremo il controllo non è una vera istruzione ma solo uno strumento di controllo alle istruzioni inserite al suo interno.
del flusso e le espressioni condizionali, in quella stessa sede introdurremo anche gli operatori logici Ma cosa succede se $a e $b fossero state diverse?
che ci permettono di unire più condizioni. La risposta è alquanto semplice, poiché la condizione non risulta vera il codice compreso nelle

HTML.IT – Guide PHP 37 HTML.IT – Guide PHP 38


parentesi graffe non verrà eseguito.
Il costrutto if ci offre delle ottime varianti per controllare ancora più il nostro codice, il costrutto
else : Molto spesso, in alcune pagine vi è l’esigenza di ripetere l’esecuzione di determinate funzioni fino a
Vediamo un altro esempio: quando non si verifica una determinata condizione.
I due costrutti che vedremo in questa e nella prossima lezione servono a questo scopo e vengono
<?php
$a=5;
chiamati costrutti di iterazione, in questo capitolo inizieremo con il costrutto while.
$b=5; Se avete già studiato il costrutto if non avrete senz’altro problemi ad assimilare la semantica del
if ( $a == $b) {
print ” I valori $a e $b sono uguali”; costrutto while in quanto presentano molte somiglianze:
} else {
print ” I valori $a e $b sono diversi”;
} While( condizione ) {
?> Istruzioni da eseguire
}

Tradotto nella nostra lingua: se ( if ) $a è $b sono uguali allora stampa ( print ) a video la frase ” I Traducendo while nel nostro linguaggio potremo definirlo così: finchè una determinata condizione
valori $a e $b sono uguali” altrimenti ( else ) stampa ( print ) a video la frase ” I valori $a e $b sono non diventa vera esegui le istruzioni comprese all’interno delle parentesi graffe.
diversi”. Il costrutto while è utilizzato soprattutto nella navigazione degli array ( che vedremo nelle prossime
Il costrutto else quindi ci consente di eseguire un secondo blocco di istruzioni nel caso la condizione lezioni ) ma anche in moltissime altre occasioni.
risulti falsa. A scopo puramente didattico vediamo come possiamo ricavarci la tabellina del 2 con il costrutto
Esistono molte altre opportunità con il costrutto if, supponiamo di avere molte condizioni da while:
eseguire una dietro l’altra.
Supponiamo di voler stabilire se, sempre date due variabili $a e $b, $a è maggiore, minore o uguale <?php
a $b, potremo scrivere in questo modo: // definisco una variabile di comodo che chiameremo $a che rappresenterà uno dei
// due membri della moltiplicazione ( l’altro è il 2 )
// poiché la tabellina parte dal numero 1
If ($a<$b) { $a = 1;
print “$a è maggiore di $b; // introduciamo il costrutto while
} while ( $a != 10 ) {
// voglio sapere la tabellina del 2 fino a 10
If ($a>$b) { /* tradotto sarà così: finchè ( while ) $a è diverso ( != ) da 10( quindi finchè la condizione
print “$a è minore di $b; tra parentesi risulterà vera ) esegui l’operazione che sarà */
} print “( $a * 2 ) “;
// prima di uscire dal costrutto while incrementiamo di una unità la variabile $a altrimenti
If ($a==$b) { // incorreremo nel più frequente errore nell’uso di questo ciclo, ossia un giro infinito
print “$a è uguale di $b; // che finirà solo dopo il timeout del PHP
} // Nel costrutto while, finchè $a è diverso da 10 eseguirà sempre l’istruzione
// che avete inserito nelle parentesi graffe, una volta che $a sarà uguale a 10 si
// uscirà dal ciclo e lo script continuerà ad eseguire le istruzioni presenti dopo
$a++;
Questo metodo senz’altro funziona ma è troppo macchinoso e porterebbe a grosse difficoltà qualora // Il ++ è un altro operatore del PHP, questo è una forma abbreviata del classico:
le condizioni risultassero più di tre. In questo caso il PHP ci viene incontro con un’altra vaiante : il // $a = $a + 1;
} ?>
costrutto elseif:
vi propongo la soluzione:
comodo no?
If ($a<$b) { print “$a è maggiore di $b”; L’output di questo semplicissimo programma sarà: 2 4 6 8 10 12 14 16 18 20.
} Inutile dire che questo esempio è stato fatto solo per farvi capire il funzionamento del while,
elseif ($a>$b) { print “$a è minore di $b”;
} elseif ($a == $b) { print “$a è uguale di $b”; vedremo script più complessi quando analizzeremo Mysql e l’estrapolazione dei dati da un
} database.
Anche nel costrutto prestate particolare attenzione alla chiusura delle parentesi graffe ed
In questo modo abbiamo utilizzato un nuovo costrutto che ci ha permesso di unire i tre cicli if visti assicuratevi che il ciclo non diventi infinito.
poco sopra. Per il costrutto while esiste una piccola variante che si differenzia da quella vista sopra per la
Sempre traducendo nella nostra lingua avremo che : modalità di esecuzione delle istruzioni comprese tra parentesi graffe.
se ( if ) $a è maggiore di $b stamperemo ( print ) a video “$a è maggiore di $b” Nella sintassi tradizionale prima viene valutata la condizione e solo se vera viene eseguito il blocco
altrimenti se ( elseif ) $a è minore di $b stamperemo ( print ) a video “$a è minore di $b” istruzioni, nella variante do/while invece:
altrimenti se ( elseif ) $a è uguale di $b stamperemo ( print ) a video “$a è uguale di $b”
Il ciclo if è forse uno dei costrutti più utilizzati all’interno di qualsiasi script in PHP. do
{
Nel suo uso date particolare attenzione alla apertura e chiusura delle parentesi graffe, molti blocco-istruzioni
programmatori utilizzano un piccolo trucco per evitare questa dimenticanza, aprire e chiudere }
while ( condizione )
subito le parentesi e scrivere l’istruzione al loro interno successivamente.

Controllo del flusso: while

HTML.IT – Guide PHP 39 HTML.IT – Guide PHP 40


Potremmo a questo punto chiederci, come facciamo a visualizzare i valori della variabile $colori?
viene prima eseguito un blocco istruzioni e poi viene valutata l'istruzione, per i restanti cicli il Per rispondere a questa domando occorre entrare ancora più in profondità e dire che nel PHP
funzionamento è identico a quello del costrutto tradizionale. esistono due tipi di array: gli array ad indice numerico e gli array associativi.
Nel nostro caso l’array $colori è un array ad indice numerico poiché il PHP assegna un numero
Controllo del flusso: for univoco ai valori dell’array in base al loro inserimento.
Per cui:
$colori[0] sarà uguale a “rosso”
Un' altro ciclo per effettuare una ripezione è il costrutto for. La sua sintassi è quasi uguale a quella $colori[1] sarà uguale a “verde”
del while a parte la modalità di funzionamento che presenta alcune interessanti varianti: $colori[2] sarà uguale a “blu”
e così via se avessimo altri valori all’interno dell'array.
for ( condizione1, condizione2,condizione3 ) {
blocco-istruzioni
} Ricordate che il primo valore nel PHP è sempre lo 0.
Nel PHP l’utilizzo dell’array è molto semplice in quanto non occorre dichiarare preventivamente
Il costrutto for si differenzia dal costrutto whil per via del fatto che il for viene utilizzato quando noi quanti elementi saranno contenuti al suo interno ma anzi è possibile aggiungere elementi anche
conosciamo il numero di ripetizioni da eseguire. durante l’esecuzione dello script. Volendo aggiungere un 4° elemento all’interno del nostro array
Il for ha un funzionamento particolare, come potete voi stessi notare le condizioni tra parentesi sono $colori basterebbe scrivere:
3 e non una come nel ciclo while. Analiticamente può essere spiegato in questo modo: per prima
$colori[]= “viola”;
cosa viene valutata la condizione1 ( una solo volta ), generalmente questa prima condizione è una
espressione, da qui inizia l'iterazione vera e propria: viene valutata la condizione 2, se falsa si esce
dal ciclio, se vera si esegue il blocco istruzioni. Il PHP accoderà in automatico il valore viola agli altri presenti nell’array e possiamo visualizzare il
Al termine di ogni operazione viene infine valutata la condizione3. suo valore scrivendo:
Per non creare troppa confusione per coloro che per la prima volta si trovano di fronte ad un ciclo di print $colori[3];
iterazione for vi ripropongo l'esempio fatto con il while per la tabellina del 2.
Un confronto diretto tra questi due costrutti vi farà senz'altro aprrezzare maggiormente le differenze
tra questi cicli di ripetizione: Concludiamo il discorso sugli array ad indice numerico fornendo un piccolo esempio di come poter
scorrere gli elementi contenuti all’interno di un array, impiegheremo il costrutto for:
<?php
for ($a = 1; $a < 10; $a++ ) { <?php
print “( $a * 2 ) “; // visualizzeremo i valori dell’array $colori precedentemente creato
?> $numero_elementi = count($colori);
// la funzione count conta il numero di elementi presenti all’interno di un array
for ($a = 0; $a< $numero_elementi; $a++) {
print $colori[$a]
Come detto sopra: viene prima ( una solo volta ) valutata la condizione1 ( $a = 1 ), dopo parte // inizialmente $a sarà uguale a 0, quindi visualizzeremo il valore di $colori[0], poi
l'iterazione e viene valutata la condizione2, se $a è minore di 10 si eseguono le istruzioni altrimenti // $colori[1] e così di seguito finchè non arriveremo alla fine dell’array
}
si esce dal ciclo. ?>
Inoltre alla fine di ogni ripetizione viene valutata la condizione 3 che nel nostro caso incremente la
variabile $a di 1 unità. L’output di questo script sarà: rosso , verde, blu, viola . Per quanto riguarda invece gli array
associativi il discorso si semplifica ulteriormente perché in questo caso siamo noi a scegliere il
Gli array nome dell’indice dei valori presenti all’interno dell’array.
Utilizzando l’esempio dei colori potremo scrivere in questo modo il nostro array associativo:

Non poteva non mancare in questa nostra guida una trattazione particolareggiata sugli array o $colori[primo_colore] = “rosso”;
$colori[secondo_colore] = “verde”;
vettori.
Ho voluto parlarli di queste variabili appositamente dopo le lezioni sul controllo del flusso perché
per poter utilizzare gli array occorre avere una certa dimestichezza con i costrutti while e for. e così via….
Questo non significa che gli array non possano essere utilizzati senza questi costrutti ma raramente In questo caso per visualizzare il secondo colore ci basterà rischiare l’indice che noi stessi abbiamo
incontrerete degli array senza trovare il while o il for. attribuito al secondo valore, ossia:
Cos’è un array? Un array è una variabile che contiene più valori. Ecco un piccolo esempio:
print $colori[secondo_colore];

$colori = array (“rosso”, “ verde”, “blu”);


L’output sarà: verde.
Con questa riga di codice abbiamo appena creato un array ( $colori ), il quale non è altro che una
variabile con più valori al suo interno. Gli array, man mano che faremo degli script sempre più complessi fungeranno da veri e propri
magazzini per i nostri dati.
HTML.IT – Guide PHP 41 HTML.IT – Guide PHP 42
Pensate alla realizzazione di una rubrica personale, invece di definire una variabile per ogni voce laboriose e scoprirete subito il vantaggio di poter creare delle vostre funzioni.
della rubrica potremo semplicemente fare un array associativo che le comprenda tutte e dopo La nostra funzione sarà così:
maneggiare i dati attraverso gli indici che noi stessi abbiamo attribuito alle varie voci.
Ricordate che in PHP un array può contenere vari tipi di dato nello stesso array: lettere, numeri function somma ($a,$b) {
$c = $a + $b;
reali, numeri in virgola mobile ecc. ecc. print $c;
}
Il PHP gestisce le stringhe di caratteri come veri e propri array ad indice numerico; se noi
scriviamo:
Una volta dichiarata la funzione per eseguire la somma di due numeri e visualizzare il risultato sarà:
$stringa =“ Il mondo è bello “; somma(5,5); l’output del programma sarà 10.
Come potete notare abbiamo creato una funzione che è identica a quella vista poco sopra (strlen).
potremo raggiungere qualsiasi singolo carattere contenuto nella variabile $stringa. Esaminiamo la sintassi della funzione: con la parola function diciamo all’interprete PHP che stiamo
Per cui: creando una nuova funzione, subito dopo function deve essere definito il nome della funzione ( nel
nostro caso somma ) che verrà poi utilizzato per richiamare la funzione stessa all’interno del nostro
$stringa[0] sarà uguale al carattere I programma.
$stringa[1] sarà uguale al carattere I Dopo il nome seguono le parentesi tonde ( obbligatorie ), al loro interno dobbiamo inserire le
$stringa[2] sarà uguale al carattere “spazio” variabili da passare alla funzione in modo che possa eseguire su di esse le istruzioni che abbiamo
e così via fino alla fine della stringa. inserito tra le parentesi graffe.
Attenzione, mentre le parentesi tonde sono obbligatorie, non è obbligatorio inserire delle variabili
Queste funzioni sono molto utili per eseguire il parsine di una stringa che potrete approfondire in da passare alla funzione in quanto magari è la funzione stessa che ha la funzione ( scusate il gioco
lezioni più complesse. di parole ) di creare altre variabili.
Prendete ad esempio una funzione per la generazione di un numero random compreso tra 10 e 20,
Personalizziamo il codice: le funzioni scriveremo:

<?php
function random () {
In determinati script complessi ( Forum, mailing list ) vengono compiute varie volte le stesse $a = rand(10,20);
return $a;
operazioni. }
?>
La semplice connessione ad un database costituisce un operazione che va ripetuta in ogni pagina ed
ogni qual volta dobbiamo fare un operazione sulle nostre tabelle.
Le funzioni ci aiutano ad evitare questi inutili sprechi di tempo fornendoci il modo di personalizzare Questa funzione non neccessità di nessuna variabile esterna ma l’abbiamo costruita solo per
il codice con delle funzioni fatte da noi. generare a sua volta una variabile.
Il comando return indica alla funzione di restituire il valore che noi vogliamo che ci restituisca, in
Già nel PHP ci sono varie funzioni che possiamo utilizzare per gli scopi più comuni, ad esempio la questo caso $c.
funzione strlen() calcola quanti caratteri sono presenti in una stringa, la funzione time() calcola l’ora Capisco che all’inizio la pratica di creare nuove funzioni potrà senz’altro risultare complessa ma
e così via…. sarà un utilissimo strumento per programmi. La logica delle funzioni personalizzate stimola la
Una funzione può essere definita come un comando per effettuare una operazione: se $a contiene la programmazione modulare ( ogni funzione è uguale ad un modulo ) in cui ogni problema viene
stringa “Il mondo è bello” la funzione ( comando ) strlen($a) ci fornirà il numero di caratteri della suddiviso in problemi più piccoli per poi assemblare il tutto.
stringa contenuta in $a. Un’altro indiscutibile vantaggio delle funzione è che potete utilizzarle in tutti i vostri programmi
Tutti i comandi, una volta impartiti devono restituirci qualcosa e nell’esempio sopra riportato la qualora abbiate bisogno di risolvere determinati problemi.
risposta dello script sarà 16.
Il PHP ci offre delle funzioni di carattere generale ma nel contempo ci permette di poter creare delle Percorso consigliato di Edoardo Valsesia
nostre funzioni. Apprendista webmaster@cgipoint.it
Poniamo che per ipotesi io debba fare in continuazione la somma di due numeri e visualizzare il
risultato. Nel modo tradizionale dovrei fare in questo modo: Questa guida, a cura di Edoardo Valsesia, è indirizzata alla comprensione dei costrutti teorici del linguaggio PHP, con
particolare attenzione alla teoria.
<?php
$a = 5;
$b = 5;
$c = $a + $b ;
print $c;
?> 1. Introduzione al linguaggio

Certo lo script non è molto lungo ma provate ad immaginare operazioni più complesse e più Cenni introduttivi di PHP e finalità di questa guida

HTML.IT – Guide PHP 43 HTML.IT – Guide PHP 44


Gli Integers, o interi, possono assumere diversi valori numerici esprimibili in differenti
notazioni
2. Origini e tipologia di linguaggio

Cos'è il PHP, come funziona e quali database consente di interrogare 12. Floating point number

Questo tipo di dati sono semplicemente i numeri in virgola mobile


3. CGI e PHP: fondamentali differenze

Differenze e diversi utilizzi tra il PHP ed i CGI 13. Strings

Sulle strings c'è molto più da dire rispetto ai tipi di dati precedenti. Passiamo ad analizzarle
4. Creazione delle pagine e sintassi di base

Panoramica generale sui fondamenti del PHP, come la sintassi di base 14. Array

Il PHP supporta sia gli array scalari che gli array associativi
5. Variabili

Introduzione alla possibilità di utilizzare le variabili con PHP 15. Objects

In PHP si possono utilizzare anche gli oggetti; vediamo per iniziare un esempio
6. Variabili di Apache

La serie di variabili di cui parleremo in seguito sono generate da Apache; vediamo quali 16. Operatori

Gli operatori utilizzabili con PHP sono simili a quelli utilizzati con gli altri linguaggi di
7. Variabili d'ambiente programmazione

Anche con PHP, come con altri linguaggi, è possibile specificare ed utilizzare le variabili
d'ambiente 17. Operatori aritmetici

Gli operatori aritmetici sono i più semplici


8. Variabili PHP

Per finire, vediamo le variabili che PHP stesso ci mette a disposizione 18. Assegnazione

L'operatore di assegnazione è il simbolo dell'uguale (=) che attribuisce ad una variabile un


9. Costanti valore

PHP mette a disposizione degli sviluppatori anche delle costanti, ovvero l'opposto delle
variabili 19. Altri operatori

Gli operatori che il PHP ci mette a disposizione sono molti, e vedremo in questa pagina i più
10. Tipi di dati importanti che non abbiamo ancora avuto modo di esaminare

Il PHP supporta diversi tipi di dati che sono automaticamente assunte dal motore
20. Strutture di controllo

11. Integer Permettono al programmatore di far compiere delle azioni al programma nel caso si
verifichino (o non si verifichino) determinate condizioni

HTML.IT – Guide PHP 45 HTML.IT – Guide PHP 46


Le funzioni each, echo, ereg_replace, ereg, eregi_replacem eregi, error_log, escapeshellcmd,
21. ELSE exec, exit, exp, explode

Else viene in "completamento" di if: con if


31. Le funzioni con iniziali F e G

22. ELSEIF Le funzioni fclose, feof, file_exists, filegroup, filesize, filetype, flock, fopen, get_browser,
get_cfg_var, get_current_user, get_meta_tags, getenv
Elseif permette di specificare casualità non definite da "if"

32. Le funzioni con iniziali H, I, J, K e L


23. WHILE
Le funzioni header, hexdec, implode, in_array, is_array, isset, join, key, link, list
La condizione

33. Le funzioni con iniziali M, O, P e R


24. FOR
Le funzioni mail, max, mkdir, opendir, phpinfo, phpversion, popen, print, rand, range,
Anche "for" si comporta esattamente come avviene in C o in Perl rename, rmdir, round

25. SWITCH 34. Le funzioni con iniziali S, T e U

"Switch" permette di sostituire una serie di "if" sulla stessa espressione Le funzioni shuffle, sin, sizeof, sleep, split, sqrt, strcmp, system, tan, unset, usleep

26. Le funzioni con iniziale A 35. Introduzione alle altre funzioni

Le funzioni abs, acos, array, asin, atan apache_lookup_uri, getallheaders, virtual

27. Le funzioni con iniziale B 36. Funzioni legate ad Apache

Le funzioni base64_decode, basename, bcadd, bccomp, bcdiv, bcmult, bcpow, bcsqrt, Apache_lookup_uri, getallheaders, virtual
bcsub, bin2hex

37. Funzioni relative alla crittazione


28. Le funzioni con iniziale C
PHP offre agli sviluppatori una serie di funzioni relative alla crittatura, legate alla libreria
Le funzioni ceil, chdir, checkdate, chgrp, chmod, chmop, chown, chr, chunk_split, closedir, mcrypt
copy, cos, count, crypt, current

38. Funzioni legate al protocollo FTP


29. Le funzioni con iniziale D
Una vasta libreria di funzioni legate al protocollo FTP (FILE TRANSFER PROTOCOL),
Le funzioni debugger_off, date, debugger_on, dechex, decoct, define, defined, die, dirname, per il trasferimento di file da un computer all'altro in una rete
diskfreespace

39. Funzioni relative al networking


30. Le funzioni con iniziale E

HTML.IT – Guide PHP 47 HTML.IT – Guide PHP 48


Questa famiglia di funzioni, che vedremo per sommi capi, è relativa al lavoro in rete e tratta
soprattutto di protocolli, indirizzi ecc Gestire le pagine protette senza i file .htaccess o comunque le autorizzazioni del server

40. Standard POSIX Introduzione al linguaggio

Tali funzioni ci permetteranno di innestare una completa interazione con il sistema, per un
ottimale scrittura dei nostri script In questa guida non vogliamo certo ripercorrere quanto è stato detto nel tutorial di Alberto
Mucignat, ma vogliamo solamente iniziare un approccio più teorico e meno pratico al linguaggio.
Visto l'affermarsi, a partire dalla versione 3, del PHP è importante per chiunque voglia considerarsi
41. Le estensioni un programmatore web conoscerne più delle basi, in modo da saper creare applicazioni per
determinati scopi e dando sfogo alla propria fantasia.
Le funzioni presenti in librerie aggiuntive che devono essere installate sul sistema e
richiamate in maniera particolare Origini e tipologia di linguaggio

42. Il perchè delle estensioni PHP è l'acronimo di "PHP: Hypertext Preprocessor", ossia un "preprocessore dell'ipertesto" che si
basa su una sintassi simile al C, al Java ed al Perl, ovviamente con alcune aggiunte specifiche.
A questo punto, ci sarà sicuramente chi si chiederà il perchè di questa librerie aggiuntive Nasce nel 1994 come progetto "personale" e la prima versione pubblicamente utilizzabile risale al
1995 con il nome di "Personal Home Page". Il resto, è storia: come ogni buon progetto che attira
l'attenzione di utilizzatori e sviluppatori, il linguaggio si sviluppa come progetto open-source tanto
43. Introduzione a PHP e database che, nel 1996, già circa 15.000 siti web lo utilizzano; al momento della release 3 (metà del 1999) il
numero di server che utilizzano PHP si è decuplicato.
Le funzioni presenti in librerie aggiuntive che devono essere installate sul sistema e
richiamate in maniera particolare Il PHP è un linguaggio di scripting server-side; si tratta di un linguaggio "embeeded" nelle pagine
che lo contengono come, per citare un esempio, il linguaggio Javascript; la fondamentale differenza
è che il PHP viene eseguito dal server anzichè direttamente dal client: quindi non servono
44. Configurazioni prima di iniziare particolari compatibilità o standard definiti da terze parti (come l'esempio più classico del
Javascript). Il meccanismo di esecuzione degli script, per chi li conosca, è simile al linguaggio ASP.
Prima di tutto, dobbiamo essere sicuri di aver installato sul sistema la libreria PHP che
permette l'interazione con il database, installando il pacchetto Ad esempio, se in una pagina fosse presente il codice:

45. Funzioni <html><body>


<? phpinfo(); ?>
</body></html>
L'analisi delle funzioni che ci possono tornare utili nei nostri script
se voi richiamaste la pagina dal browser, non vedreste la linea di codice compresa fra <? e ?> (i tag
propri del PHP), bensì il risultato che tale comando produce: in pratica, il server HTTP, una volta
46. E a questo punto? che gli viene richiesta una pagina del genere, la riconosce (poichè opportunamente configurato) e ne
esegue la parte "dinamica"; quello che arriva al vostro browser è l'elaborato di tale codice e voi
Conclusioni sull'argomento funzioni negli script PHP potrete capire che si tratta di una pagina scritta in linguaggio PHP solo per la sua estensione
(tipicamente .php3).

47. Gestione dei Cookies Le potenzialità del linguaggio PHP sono molto buone, tanto che è possibile creare in PHP tutte le
applicazioni che si potrebbero creare con degli script CGI: la differenza principale fra PHP e CGI è
Gestire i cookies, piccoli file di testo contenenti informazioni utili e non dannose per la che il primo rende molto più semplice la connessione e l'interrogazione con i database; il PHP3
gestione delle sessioni sul web supporta questi database:

1. Adabas D
48. Autenticazione con PHP 2. InterBase
3. Solid

HTML.IT – Guide PHP 49 HTML.IT – Guide PHP 50


4. dBase si può dire che, a partire dalla versione 4, le potenzialità del PHP sono praticamente identiche a
5. mSQL quelle dei CGI in Perl, ma non del Perl stesso, comunque.
6. Sybase
7. Empress Creazione delle pagine e sintassi di base
8. MySQL
9. Velocis
10. FilePro Come visto nel brevissimo esempio riportato sopra e come probabilmente molti avranno letto nel
11. Oracle resto del corso precedentemente pubblicato, la sintassi del PHP va inserita fra i tags:
12. Unix dbm
13. Informix
14. PostgreSQL <?php

e
Come i CGI, poi, con il PHP è possibile utilizzare i più noti protocolli di rete come IMAP, SMTP,
POP3 e persino HTTP oppure utilizzare i socket.
?>

CGI e PHP: fondamentali differenze


Ma è possibile inserire il codice in altri modi:

E' noto che gli script CGI scritti in Perl e gli script PHP sono i più utilizzati per la generazione di
<? ?> /* short tags*/
pagine dinamiche, lasciando per un attimo da parte il linguaggio ASP che, ricordiamo, è
proprietario e può essere utilizzato (quasi) solamente su webserver NT con IIS. <script language="php"> </script> /* default insieme a <?php e ?> */
<% %> /* ASP-like tags */
Il PHP, specialmente in questi ultimi periodi, si sta affermando come linguaggio principe di
scripting per la generazione di pagine dinamiche; in primo luogo perchè è multipiattaforma, ossia è Ad esempio, è equivalente scrivere:
possibile trovare il motore PHP per le più diffuse piattaforme.
Ma il PHP, lentamente ma inesorabilmente, sta superando in complessità i CGI; questo si può
giustificare in parecchi modi: <?echo ("Io sono uno script PHP\n"); ?>
<?php echo ("Io sono uno script PHP\n"); ?>
x PHP è un linguaggio embeeded nel codice HTML delle pagine, e non necessita quindi di <script language="php">
ulteriori file esterni per essere eseguito; echo ("Io sono uno script PHP\n");
</script>
x uno script PHP, di fatto, non ha bisogno di installazione come avviene per uno script CGI: <% echo ("Io sono uno script PHP"); %>
chi abbia qualche volta letto qualche recensione presente su www.cgipoint.it, avrà
sicuramente visto come ogni script debba essere caricato sul server in determinate directory sebbene per gli esempi che qui riporteremo verrà utilizzata la sintassi <? ?>
con determinati permessi e via dicendo. Con il PHP questo non succede più: oltre a non aver
più bisogno di una directory cgi-bin, essendo il codice inserito direttamente nelle pagine, Ricordiamo che i tag riconosciuti di default sono <?php ?> e <script>. Per abilitare gli short tags e
una volta che la pagina sia caricata di fatto lo script può dirsi pronto per l'uso, a patto che sia gli ASP-like tags occorre modificare il file di configurazione alle prime righe, dove è possibile
stato correttamente configurato; leggere qualcosa del tipo:
x con il PHP non si ha più bisogno di particolari configurazioni del webserver in modo da
abilitare directory cgi-bin oppure abilitare l'esecuzione di determinati file con determinate short_open_tag = On ; allow the <? tag.
asp_tags = On ; allow ASP-style <% %> tags
estensioni. Una volta istruito il webserver, ogni script (o meglio, pagina con all'interno il
codice dello script) potrà essere eseguito in OGNI directory esso si trovi. Immaginate la
comodità di questa caratteristica del PHP. E' possibile poi, come per tutti i linguaggi di programmazione, inserire dei commenti nel codice: il
PHP supporta tre tipi di commenti:
Ovviamente, queste sono solamente alcune delle caratteristiche che permettono al PHP di superare i
CGI, e possono peraltro essere soggette a critiche dai fanatici dell' "altra fazione". Ovviamente, /* */ -> come nel linguaggio C;
anche i CGI hanno i loro lati positivi, e la scelta fra l'uno o l'altro linguaggio (oppure entrambi, a // -> come nel linguaggio C++;
volte!) cade sulla scelta personale del programatore. A livello di "cosa sia possibile fare con PHP" # -> come nello scripting di shell e nel Perl.

Affinchè il codice venga eseguito dal server per l'invio al client, poi, è necessario dare alle pagine
HTML.IT – Guide PHP 51 HTML.IT – Guide PHP 52
una determinata estensione e rendere il webserver capace di interpretare tali pagine e richiamare il
motore per la loro interpretazione. Per Apache, ad esempio, sarà necessario caricare il modulo
relativo al PHP3 nel file di configurazione e definire un'appropriata estensione per le pagine PHP. La serie di variabili di cui parleremo in seguito sono generate da Apache; se si utilizzano altri
Per caricare il modulo, decommentate nel file httpd.conf la direttiva: webserver, alcune variabili saranno ovviamente differenti.
Prima di vederle in dettaglio, ricordiamo che è possibile leggere il valore di ogni variabile o con la
funziona phpinfo() oppure con un semplice
LoadModule php3_module /usr/lib/apache/1.3/libphp3.so

ovviamente con la corretta locazione delle libreria libphp3.so. echo "NOME_DELLA_VARIABILE";


Per quanto riguarda poi l'estensione, sarà necessario aprire il file srm.conf ed inserire (o
decommentare, nel caso sia già presente con un commento davanti) la direttiva: Inoltre, i valori di esempio sono tratti o direttamente dalla documentazione del PHP o dal valore che
esse assumono nel server utilizzato per scrivere queste pagine.
AddType application/x-httpd-php3 .php3 x GATEWAY_INTERFACE: la versione delle specifiche CGI utilizzate dal server, ad esempio
"CGI/1.1";
A questo punto, dopo aver riavviato Apache, potremo effettuare le prime prove. Basterà caricare le x SERVER_NAME: il nome del server, quello che in Apache si definisce in "ServerName" in
pagine con codice php nella DocumentRoot del server e controllare che tutto sia andato per il verso httpd.conf, ad esempio "myhost.com";
giusto. x SERVER_SOFTWARE: il nome del software utilizzato per il webserver, ad esempio
"Apache/1.3.9 (Unix) Debian/GNU PHP/3.0.15 mod_perl/1.21_03-dev";
Variabili x SERVER_PROTOCOL: il nome e la versione del protocollo tramite il quale è stata richiesta la
pagina, ad esempio "HTTP/1.0";
x REQUEST_METHOD: utilizzato nelle form, può essere "GET", "POST", "HEAD", "PUT";
Come per tutti i linguaggi di programmazione anche con il PHP è possibile utilizzare le variabili, x QUERY_STRING: se presente, la stringa tramite la quale la pagina è stata richiesta;
che sono rappresentate dal simbolo del dollaro ($) seguito dal nome della variabile. x DOCUMENT_ROOT: la DocumentRoot del server, come configurata in httpd.conf, ad esempio
"/var/www";
$variabile = 1;
x HTTP_ACCEPT: il contenuto dell'header Accept, ad esempio "text/*, image/*, audio/*,
$Variabile = "Questa è una variabile"; application/*";
x HTTP_ACCEPT_CHARSET: il charset accettato, ad esempio "iso-8859-1";
Queste sono variabili, e sono differenti non tanto per il valore loro assegnato quanto per il loro x HTTP_ENCODING: l'encoding della richiesta, se presente; ad esempio, "gzip";
nome: infatti, in PHP le variabili sono case-sensitive. x HTTP_ACCEPT_LANGUAGE: il linguaggio, ad esempio "en";
x HTTP_CONNECTION: il contenuto dell'header Connection, ad esempio "Keep-alive";
Scegliere i nomi delle variabili serve soprattutto per capire e ricordare il ruolo di una variabile x HTTP_HOST: il nome dell'host, ad esempio "localhost";
all'interno del codice, e quindi per ogni variabile può essere scelto qualsiasi nome; alcuni nomi, x HTTP_REFERER: il nome della pagina dalla quale si proviene;
però, sono per così dire "riservati" e non possono (o meglio, non dovrebbero) essere utilizzati. x HTTP_USER_AGENT: il contenuto dell'header User_Agent, ad esempio "Mozilla/4.72 [en]
Questa variabili possono essere sommariamente divise in tre gruppi: le variabili di Apache (o del (X11; I; Linux 2.2.14 i586)";
server), le variabili d'ambiente e le variabili PHP. Premettendo che molte di queste variano da x REMOTE_ADDR: l'indirizzo IP dell'utente connesso alla nostra pagina;
macchina a macchina e da server a server, cerchiamo di fare una panoramica su questa variabili, che
x REMOTE_PORT: come sopra, ma riferito alla porta; ad esempio, le due variabili potrebbero
peraltro potete leggere con una semplice pagina del tipo:
avere un output del tipo: "127.0.0.1 1275";
x SCRIPT_FILENAME: il nome dello script richiesto al server, ad esempio "prova.php3";
<html><body> x SERVER_ADMIN: il nome dell'amministratore di sistema;
<? phpinfo(); ?> x SERVER_PORT: la porta sulla quale il server è in ascolto, ad esempio la porta 80;
</body></html>
x SERVER_SIGNATURE: l'eventuale "signature" del server;
Oltre a quanto detto, vanno inoltre ricordate altre variabili, alcune delle quali non dipendono x PATH_TRANSLATED: il percorso per lo script richiamato, ad esempio
direttamente dal PHP; le divideremo in tre classi: "/var/www/php/prova.php3";
x SCRIPT_NAME: il path, a partire dalla DocumentRoot, dello script; ad esempio,
x Variabili di Apache; /php/prova.php3";
x Variabili d'ambiente; x REQUEST_URI: l'URI richiesto per accedere alla pagina;
x Variabili PHP.
Variabili d'ambiente
Variabili di Apache
HTML.IT – Guide PHP 53 HTML.IT – Guide PHP 54
PHP_OS
Anche con PHP, come con altri linguaggi, è possibile specificare ed utilizzare le variabili
d'ambiente; dipendendo però esse dalla shell utilizzata, è inutile specificarle. Per leggerle, provate a Il nome del sistema operativo su cui è fatto girare lo script;
richiamarle all'interno di uno script PHP come, ad esempio:

TRUE
echo "Il mio path è $PATH";
Un valore sempre vero;
che visualizzerà il vostro path sul sistema.

Variabili PHP FALSE

Un valore sempre falso;


Per finire, vediamo le variabili che PHP stesso ci mette a disposizione:

x argv: un array contenente i parametri passati allo script; E_ERROR

x argc: come sopra, ma se lo script è eseguito dalla linea di comando;


x PHP_SELF: il nome dello script attualmente in esecuzione; Un errore, differente dal solito errore di parsing (ossia, scrittura del codice), non recuperabile;
x HTTP_COOKIE_VARS: un array associativo contenente le variabili passate allo script tramite i
cookies HTTP; E_WARNING
x HTTP_GET_VARS: un array associativo contenente le variabili passate allo script tramite una
richiesta GET;
Come sopra, ma in questo caso il PHP può continuare l'esecuzione del codice;
x HTTP_POST_VARS: come sopra, ma riferito al metodo POST.

E' da ricordare che le ultime tra variabili hanno senso solamente se, nel file di configurazione E_PARSE
(track_vars=On) oppure all'interno dello script con la direttiva "php_track_vars", è stato abilitato il
tracking delle variabili. Un errore del parser (ossia di sintassi del file);
Costanti
E_NOTICE

Oltre ai tipi di dati visti sopra, PHP mette a disposizione degli sviluppatori anche delle costanti, Qualcosa che potrebbe essere come non essere un errore; l'esecuzione non viene interrotta;
ovvero l'opposto delle variabili: ad un nome è associato un valore che il programmatore può
utilizzare ma che non può modificare. Vediamo quali sono: La domanda, a questo punto, sarà: come si utilizzano tali costanti? La risposta è abbastanza
semplice: utilizzate un codice come:
__FILE__
<?
echo "Linea ", __LINE__ . " del file " ,__FILE__;
Il nome dello script che è sottoposto al parsing; ?>

__LINE__
che vi restituirà: Linea XX del file NOMEFILE. Provatelo! E' da aggiungere inoltre che, se queste
sono le costanti "di default" del linguaggio, è possibile definire all'interno di uno script le proprie
costanti in maniera molto semplice, come avremo modo di vedere quando andremo a parlare delle
La linea dove è presente questo statement;
funzioni interne al linguaggio.

PHP_VERSION Tipi di dati

La versione di PHP in uso;


Il PHP supporta diversi tipi di dati, che non devono essere impostate dal programmatore ma sono
automaticamente assunte dal motore a meno che il programmatore stesso ne forzi il tipo (con la

HTML.IT – Guide PHP 55 HTML.IT – Guide PHP 56


funzione settype() ). Come in tutti i linguaggi, comunque, anche con il PHP ci sono i caratteri speciali che vanno fatti
precedere da un simbolo di escape; ad esempio, provate il seguente esempio:
I dati possono essere:

x Integer; $num = 10;


$string = "Il numero è "$num"";
x Floating Point number;
x String;
Chi pensa che l'output di tale codice sia 'Il numero è "10"' si sbaglia: a parte il fatto che, così come è
x Array; scritto, lo script darebbe un errore di compilazione, le virgolette sono caratteri speciali, ma non per
x Object. questo non è permesso utilizzarle; la sintassi corretta per il comando riportato sopra è:
Vediamoli uno ad uno.
$num = 10;
Integer $string = "Il numero è \"$num\"";

Altri caratteri speciali sono:


Gli Integers, o interi, possono assumere diversi valori numerici esprimibili in differenti notazioni.
\n -> newline
\r -> carriage return
$a = 18; # decimale \t -> tabulazione
$a = -18; # decimale negativo \\ -> backslash
$a = 022; # notazione ottale; equivalente a 18 decimale \$ -> simbolo del dollaro
$a = 0x12; # notazione esadecimale, equivalente a 18 decimale

L'alternativa ai caratteri di escape, quando non ci siano contenuti da espandere, sono gli apici (''); ad
Probabilmente, almeno per iniziare, utilizzerete soprattutto i numeri decimali, ma sappiate che il esempio:
linguaggio accetta anche altre notazioni rispetto a quella decimale.

Floating point number $string = '$ è il simbolo del dollaro';

visualizzerà proprio ciò che è contenuto fra gli apici. Attenzione a non cadere nel più consueto degli
Questo tipo di dati sono semplicemente i numeri in virgola mobile, ad esempio 9.876; la sintassi per errori:
utilizzarli è anche qui alquanto semplice:

$num = 10;
$a = 9.876; $string = 'Il numero è $num';
$a = 9.87e6;

che non visualizzerà "Il numero è 10" bensì "Il numero è $num"! Quindi possiamo affermare che,
Strings con gli apici, il contenuto della string viene riportato letteralmente, ossia com'è effettivamente
scritto al suo interno.

Sulle strings c'è molto più da dire rispetto ai tipi di dati precedenti. La sintassi di base per le Array
stringhe è:

Il PHP supporta sia gli array scalari che gli array associativi.
$string = "Io sono una stringa";

In PHP, un array di valori può essere esplicitamente creato definendone gli elementi oppure la sua
Se vengono utilizzate le virgolette (""), il contenuto della stringa viene espanso (o, tecnicamente, creazione può avvenire inserendo valori all'interno dell'array, ad esempio:
"interpolato") , come nell'esempio successivo:

$a = array ("abc", "def", "ghi");


$num = 10;
$string = "Il numero è $num";
crea l'array definendo esplicitamente gli elementi dell'array, al contrario dell'esempio che segue:
che visualizzerà "Il numero è 10".

HTML.IT – Guide PHP 57 HTML.IT – Guide PHP 58


$a[0] = "abc"; Objects
$a[1] = "def";
$a[2] = "ghi";

In questo caso, l'array viene creato con tre elementi; ricordiamo che il primo elemento di un array In PHP si possono utilizzare anche gli oggetti; vediamo per iniziare un esempio:
viene identificato dal numero "0": se ad esempio la lunghezza di un array è "5", esso conterrà sei
elementi; l'elemento contrassegnato dall'indice "0", infatti, è il primo dell'array.
class visualizza {
Se invece, per aggiungere elementi ad un array (supponiamo che sia quello precedentemente creato) function esegui_visualizza () {
si utilizzano le parentesi quadre vuote, i dati vengono accodati all'array; ad esempio: echo "Visualizza un messaggio";
}
}

$obj=new visualizza;
$a[] = "lmn"; $obj->esegui_visualizza();
$a[] = "opq";

Iniziamo definendo la classe "visualizza", che contiene la funzione "esegui_visualizza" che non fa
In questo caso, l'array si allunga di 2 elementi e risulta:
altro che visualizzare un semplice messaggio a video.
Con lo statement "new" inizializziamo l'oggetto "$obj" e richiamiamo la funzione visualizza con
$a[0] = "abc"; l'operatore -> su $obj.
$a[1] = "def"; Come vedete, anche utilizzare gli oggetti non è particolarmente difficile sebbene, per desciverli più
$a[2] = "ghi";
$a[3] = "lmn"; a fondo serva molto di più di quanto detto in questa sede.
$a[4] = "opq";

Operatori
Questo esempio è molto utile quando si vogliano accodare degli elementi all'array senza ricorrere a
specifiche funzioni e senza dover andare a leggere il numero di elementi contenuti nell'array: tutto
sarà accodato automaticamente e correttamente. Gli operatori utilizzabili con PHP sono simili a quelli utilizzati con gli altri linguaggi di
programmazione; per comodità, li divideremo in differenti "famiglie": gli operatori aritmetici, gli
Gli array associativi si basano invece su coppie "name-value"; un esempio potrebbe essere: operatori di assegnazione a, in generale, tutti gli altri operatori.

Operatori aritmetici
$a = array(
"nome" => "Mario",
"cognome" => "Rossi",
"email" => "mario@rossi.com",
); Gli operatori aritmetici sono i più semplici, e sono:

E' interessante la possibilità della funziona array di annidare le entries, come nell'esempio che
segue: $a + $b
-> addizione

$a = array( $a - $b
"primo" => array(
"nome" => "Mario", -> sottrazione
"cognome" => "Rossi",
"email" => "mario@rossi.com",
), $a * $b
"secondo" => array(
"nome" => "Marco",
-> moltiplicazione
"cognome" => "Verdi",
"email" => "mario@verdi.com", $a / $b
)
); -> divisione

Eseguire su questo array un comando del tipo: $a % $b


-> resto della divisione

<? echo $a["secondo"]["email"]; ?> Fermiamoci per un attimo sugli ultimi due:

visualizzerà "mario@verdi.com".

HTML.IT – Guide PHP 59 HTML.IT – Guide PHP 60


x il risultato della divisione non è approssimato all'intero più vicino, ma riporta tutto il numero quelli matematici e quelli di incremento-decremento:
risultante; il numero dei caratteri dopo il punto da considerare è definito nel file php3.ini alla riga:
$a & $b
precision = 14
operatore "And" ($a e $b);
Quindi, verranno riportati "solo" 14 numeri dopo la virgola, a patto che ci siano: nell'esempio:
$a && $b
$a = 12;
$b = 5;
$c = $a / $b; come sopra, ma con una precedenza più alta;
echo $c;

il risultato è 2.4 e verrà visualizzato proprio come 2.4, non come 2.40000000000000 ! Quindi, i 14 $a | $b
decimali vengono visualizzati solamente se esistono, e non indiscriminatamente come inutili zeri.
operatore "Or" ($a oppure $b);
x il resto della divisione viene riportato da solo, senza il risultato della divisione stessa: se
nell'esempio precedente avessimo utilizzato "%" al posto di "/", il risultato sarebbe stato "2".
$a || $b
Assegnazione
come sopra, ma con una precedenza più alta;

Spesso, purtroppo, gli operatori di assegnazione vengono confusi con l'operatore di uguaglianza;
$a ^ $b
l'operatore "=" ha un suo significato, che non va confuso con quello di "==".
L'operatore di assegnazione è il simbolo dell'uguale (=) che attribuisce ad una variabile un valore;
ad esempio operatore "Xor" ($a oppure $b ma non entrambi);

$a = 2; !$a

imposta per "$a" il valore "2". operatore "Not" (vero se $a non è vera);
L'errore che si fa più spesso è scrivere qualcosa del tipo:
$a == $b
if ($a=2) {
do_something;
} operatore di uguaglianza, vero se $a ha lo stesso valore di $b;

che, letto da occhi inesperti, potrebbe sembrare un'espressione per affermare che, se $a è UGUALE $a != $b
a 2 deve venire eseguito il codice fra parentesi graffe. Ebbene, non è assolutamente così: se
avessimo voluto scrivere ciò che è appena stato detto, avremo dovuto utilizzare:
l'opposto di quanto sopra;

if ($a == 2) {
do_something; $a < $b;
}

$a è minore di $b;
Altri operatori

$a <= $b
Gli operatori che il PHP ci mette a disposizione sono molti, e vedremo in questa pagina i più
importanti che non abbiamo ancora avuto modo di esaminare, in particolari gli operatori booleani, $a è minore o uguale a $b;

HTML.IT – Guide PHP 61 HTML.IT – Guide PHP 62


$a > $b echo "\$a è uguale a \$b e valgono $a.\n";
}

$a è maggiore di $b;
If può anche essere utilizzato in maniera differente da quella appena esposta: eccone un esempio:

$a >= $b
<? $a = 2; $b = 2; if ($a == $b) : ?>
$a è uguale a $b.
$a è maggiore o uguale a $b; <? endif; ?>

il cui operato è identico a quello esposto sopra.


$a ? $b : $c
"if" può essere utilizzato anche senza le parentesi graffe, utilizzando "endif" quando si intende
questo, da utilizzarsi più con le espressioni che con le variabili, valuta $b se $a è vera, e valuta $c se terminare il blocco "if"; ad esempio:
$a è falsa;
if ($a == $b)
echo "\$a è uguale a \$b e valgono $a.\n";
++$a endif;

incrementa di uno $a e la restituisce; ELSE

$a++ restituisce $a e la incrementa di uno


Else viene in "completamento" di if: con if, infatti, stabiliamo che succeda qualcosa all'avverarsi di
una condizione; con else possiamo stabilire cosa accade nel caso questa non si avveri. Un esempio
--$a
potrebbe essere:

$a--
$a = 2;
$b = 3;
if ($a == $b) {
come i due precedenti, ma il valore è decrementato; echo "\$a è uguale a \$b e valgono $a.\n";
} else {
echo "\$a è diversa da \$b.\n\$a vale \"$a\" mentre \$b vale \"$b\".\n";
Strutture di controllo }

ELSEIF
Non possono mancare in un linguaggio di programmazione le strutture di controllo, che permettono
al programmatore di far compiere delle azioni al programma nel caso si verifichino (o non si
verifichino) determinate condizioni. Elseif permette di specificare casualità non definite da "if"; un esempio potrebbe essere: "Se $a è
uguale a $b visualizza $a, se $a è diversa da $b visualizza un messaggio d'errore, avvisa se $a non
esiste, avvisa se $b non esiste". Con i soli if ed else non si potrebbe fare, ma con elseif diventa
IF semplice:

If permette di eseguire un blocco di codice se avviene (o non avviene) una determinata condizione;
la sua sintassi è: if ($a == $b) {
echo "\$a è uguale a \$b.\n";
} elseif ($a != $b) {
echo "\$a è diversa da \$b.\n";
} elseif (!$a) {
if (condizione) echo "\$a non esiste.\n";
statement } elseif (!$b) {
echo "\$b non esiste.\n";
}
Ad esempio, vogliamo che uno script ci indichi se due variabili sono uguali:
Notate due cose: possono esserci, in un blocco, tutti gli elseif di cui avete bisogno e, per chi conosca
$a = 2;
il Perl, attenzione a non scrivere "elsif" al posto di "elseif": il significato è lo stesso ma "elsif" non
$b = 2; viene riconosciuto dal PHP così come elseif non viene riconosciuto dal Perl!
if ($a == $b) {

HTML.IT – Guide PHP 63 HTML.IT – Guide PHP 64


WHILE switch ($i) {
case 0:
echo "\$i vale 0";
break;
case 1:
La condizione "while" si comporta esattamente come in C; la sintassi di base è: echo "\$i vale 1";
break;
}
while (espressione) statement
Abbiamo qui introdotto qui "break" che permette di uscire da un blocco nel caso si avveri una
Come "if", inoltre, "while" può essere utilizzato con o senza parentesi graffe, aggiungendo nel determinata condizione.
secondo caso lo statement "endwhile". I due esempi che seguono si equivalgono:
Le funzioni con iniziale A

/* Primo esempio: */
/* $a viene incrementato e visualizzato */
/* finchè il suo valore non supera "5" */ Passiamo ora, dopo aver visto cosa e quali sono le variabili, come si opera con esse e come si
$a = 1;
while ($a <= 5) { gestiscono i blocchi, alle funzioni; le funzioni sono una delle parti più importanti di un linguaggio
print $a++;
}
di programazione, perchè permettono di eseguire determinate operazioni all'interno di uno script.
/* Secondo esempio */
Le funzioni messe a disposizione dal PHP sono moltissime, e vederle tutte sarebbe inutile; ci
$a = 1; soffermeremo invece su quelle più importanti ordinate alfabeticamente.
while ($a <= 5)
print $a++;
endwhile; x abs: restituisce il valore assoluto di un numero:

Tradotte, queste espressioni fanno in modo che, finchè (while) $a è minire o uguale a "5", $a viene $num = -3.4;
$aa = abs($a);
incrementato di un'unità e visualizzato. echo $aa, "\n";

FOR restituirà 3.4

x acos: restituisce l'arcocoseno dell'argomento:


Anche "for" si comporta esattamente come avviene in C o in Perl; dopo il "for", devono essere
inserite tre espressioni che, finchè restituiscono "TRUE" permettono l'esecuzione dello statement
che segue: considerate questo esempio: $arg = 1;
$arc_cos = acos($arg);
echo "$arc_cos\n";

for ($a = 0 ; $a <=10 ; $a++) {


print $a; restituirà 0.
}
x array: si veda la precedente spiegazione riguardo i tipi di dati;
che visualizzerà i numeri da "0" a "10". Nelle tre espressioni fra parentesi abbiamo definito che:
x asin: restituisce il seno dell'argomento;
x $a ha valore "0";
x $a è minore o uguale a "10"; x atan: restituisce l'arcotangente dell'argomento;
x $a è incrementata di un'unità.
Le funzioni con iniziale B
Quindi, per ogni valore di $a a partire da "0" fino a "10" $a viene visualizzato.

SWITCH
x base64_decode: decodifica una stringa codificata in MIME base64 (vedi sotto);

"Switch" permette di sostituire una serie di "if" sulla stessa espressione e, ovviamente, di agire x base64_encode: codifica dati in MIME base64; ad esempio con:
dipendentemente dal valore di questa:
$str = "Ciao, io sono pippo\n";
echo "$str\n";

HTML.IT – Guide PHP 65 HTML.IT – Guide PHP 66


$enc_str = base64_encode($str); $pot = bcpow(2.3, 3, 2);
echo "$enc_str\n"; echo "$pot\n";
$dec_str = base64_decode($enc_str);
echo "$dec_str\n";
eleverà 2.3 alla terza potenza, approssimando il risultato alla seconda cifra decimale;
si passa allo script la stringa "$str" che viene prima codificata e visualizzata, poi decodificata e
nuovamente visualizzata; x bcsqrt: calcola la radice quadrata di un numero, con la possibilità di approssimare il numero di
cifre dopo la virgila aggiungendo un secondo elemento alla funzione (come avveniva per altre
x basename: restituisce, dato un percorso, la componente di questo identificata da un nome di file; funzioni matematiche viste sopra;
ad esempio:
x bcsub: sottrae un numero da un altro, anche qui con la possibilità di approssimare le cifre dopo la
virgola:
$path = "/var/www/php/index.php3";
$base = basename($path);
echo "$base\n";
$num = bcsub(2, 5);
echo "$num\n";
restituirà "index.php3";
restituirà "-3";
x bcadd: somma due numeri;
x bin2hex: converte una stringa di dati dal formato binario a formato esadecimale;
$num = bcadd(1.334, 4.44554, 2);
echo "$num\n"; Le funzioni con iniziale C

restituirà 5.77; la funzione "bcadd" prende come primi due argomenti due numeri e, come terzi
argomento opzionale, il numero di cifre da visualizzare dopo la virgola;
x ceil: restituisce il valore intero più alto riferito al numero passato come argomento alla funzione:
x bccomp: compara due numeri: la funzione prende come argomento due numeri e, opzionalmente,
un ulteriore numero che determina il numero di decimali da considerare dopo la viegola per
$num = ceil(3.22112);
considerare i due numeri uguali; restituisce "0" nel caso i due numeri siano uguali, "+1" se il echo "$num\n";
numero di sinistra è maggiore di quello di destra e "-1" nel caso opposto. Considerate il seguente
esempio: restituisce "4";

x chdir: cambia la directory di lavoro:


$comp = bccomp(0.334, 0.301, 2);
echo $comp;

$dir = "/var/www/";
che restituirà "1"; ma se, al posto del "2" avessimo inserito uno oppure non avessimo inserito chdir($dir);
niente, il risultato sarebbe stato "0".
restituisce TRUE se l'operazione ha sucesso, FALSO in caso contrario, ad esempio nel caso la
x bcdiv: divide due numeri, con le stesse modalità descritte per "bcadd" e "bccomp"; directory non sia leggibile;
x bcmult: moltiplica due numeri, ed è possibile aggiungere un ulteriore parametro per limitare il x checkdate: controlla che una data sia valida; per considerarsi valida, una data deve avere:
numero di cifre dopo la virgola:
- l'anno compreso fra "0" e "32767";
- il mese compreso fra "1" e "12";
$molt = bcmul(2.31, 3.21, 2);
echo "$molt\n"; - il giorno è compreso fra "0" ed il numero relativo al numero di giorni del mese a cui si fa
riferimento;
restituirà 7.41;
x chgrp: tenta di cambiare il gruppo di un file a "gruppo"; la funzione accetta come argomenti il
x bcpow: eleva a potenza due numeri, con la possibilità di spceificare il numero di cifre dopo la nome del file a cui si vogliono cambiare i permessi ed il nuovo gruppo di appartenenza:
virgola:
chgrp(filename, gruppo);

HTML.IT – Guide PHP 67 HTML.IT – Guide PHP 68


x copy: crea la copia di un file:
Nei sistemi Windows non funziona ma restituisce sempre vero.

x chmod: è equivalente al comando di sistema Unix "chmod" ed ha la stessa sintassi di chgrp; $file = "prova.txt";
copy($file, "$file.bak");

x chmop: rimuove i "whitespaces" da una stringa; spesso è utilizzato per eliminare i caratteri "\n"
quando si riceve un argomento dallo standard input; il carattere eliminato può essere letto con: x cos: restituisce il valore del cosino dell'argomento;

x count: conta gli elementi in una variabile; ad esempio:


$carattere = chop($string);
echo "$carattere\n";
$arr[0] = "abc";
$arr[1] = "def";
x chown: cambia l'owner di un file, come l'analogo comando di sistema Unix. Accetta come $arr[2] = "ghi";
argomento il nome del file ed il nome del nuovo proprietario: $count = count($arr);
echo $count;

$file = "prova.txt"; restituirà "3", visto che all'interno dell'array "$arr" sono presenti 3 elementi ($arr[0], $arr[1],
chown($file, $user); $arr[2]);

Nei sistemi Windows, non fa niente e restituisce sempre vero (ed è peraltro inutile inserire questa x crypt: critta una stringa; la sintassi della funzione crypt() è:
funzione all'interno di uno script che non supporta il comando "chown");

x chr: restituisce il carattere ASCII specificato dal rispettivo numero; immagino sappiate, ad crypt(string, salt);

esempio, che la combinazione "Alt + 0126" restituisce la tilde (~); lo si può vedere con il seguente
codice: In pratica, dovremo passare alla funzione la stringa che dovrà essere crittata e, opzionalmente, il
seme con sui crittarla; se questo non è passato alla funzione, sarà generato in maniera random dal
PHP stesso. Un esempio di crittazione di una stringa potrebbe essere il seguente:
$ascii= "0126";
$char = chr($ascii);
echo "$char\n";
$var = "Questa è una variabile";
$crypt = crypt($var, "aa");
echo $crypt;
x chunk_split: divide una stringa in parti di "n" caratteri; il numero è passabile alla funzione dopo
la stringa da dividere. Se non impostato, di default è assunto come 76; l'esempio
che restituirà la stringa crittata;

$string = "Questo è un corso per imparare il linguaggio php": x current: restituisce il primo elemento di un array:
$split = chunk_split($string, 5);

restituirà: $arr[0] = "abc";


$arr[1] = "def";
$arr[2] = "ghi";
$current = current($arr);
Quest echo $current;
o è u
n cor
so pe visualizzerà "abc";
r imp
arare
il l
ingua
Le funzioni con iniziale D
ggio
php

La funzione è utile per l'encoding MIME base64 visto precedentemente con la funzione x date: visualizza la data in formato che è possibile definire; la funzione riconosce come validi i
"base64_encode"; seguenti formati:
x closedir: chiude una directory precedentemente aperta con la funzione opendir() - vedi;
a: am/pm;

HTML.IT – Guide PHP 69 HTML.IT – Guide PHP 70


A: AM/PM x defined: controlla che una certa costante esista: un esempio potrebbe essere:
d: giorno del mese in due cifre, da "0" a "31";
D: giorno del mese in formato testo, ad esempio "Mon";
F: mese, in formato testuale, ad esempio "March";
h: ora nel formato "01", "12";
H: ora nel formato "00", "23"; define("COSTANTE", "Questa è una costante");
g: ora nel formato "1", "12"; if (defined("COSTANTE")) {
G: ora nel formato "0", "23"; echo "La costante è definita\n";
i: minuti, nel formato "00", "59"; } else {
j: giorno del mese nel formato "1", "31"; echo "La costante non è definita\n";
l: giorno della settimana, ad esempio "Monday"; }
L: specifica se l'anno è bisestile o meno ("1" oppure "0");
m: mese nel formato "01", "12";
n: mese nel formato "1", "12"; che visualizza un messaggio a seconda che la costante sia o meno definita;
M: mese in formato testuale corto, ad esempio "Jan";
s: secondi da "00" a "59";
S:
t:
suffisso inglese per gli ordinali, "st", "nd", "rd", "th";
numero di giorni nel mese corrente, da "28" a "31";
x die: visualizza un messaggio ed esce dal programma:
w: giorno della settimana in formato numerico ("0"=domenica);
Y: anno in quattro cifre, ad esempio "2000";
y: anno in due cifre, ad esempio "00";
if (defined($num)) {
echo "\$num è definito\n";
} else {
Ad esempio, si potrebbe scrivere: die ("\$num non è definito; impossibile proseguire\n");
}

echo (date("l d F y H:i:s a"));


x dirname: quando si specifica un path, riporta il path senza il nome del file finale: se ad esempio
il path è "/home/yourname/public_html/index.php3" la funzione restituirà solamente
per avere la data corrente, che ad esempio potrebbe essere: "/home/yourname/public_html":

Friday 23 June 00 11:45:48 am $path = "/home/yourname/public_html";


echo(dirname($path));

x debugger_off: disabilita il debugger PHP;


Avrete notato che questa funzione fa l'esatto contrario della funzione "basename()"; combinando le
x debugger_on: abilita il debugger PHP; due funzioni, si può avere il path completo di un file, compreso il suo nome;

x decibin: converte un numero da decimale a binario; ad esempio, il numero "10" decimale è x diskfreespace: restituisce lo spazio di disco libero; se volessimo ad esempio vedere quanto
"1010" in formato binario, e con del semplice codice PHP potremo scrivere: spazio rimane nella directory root della macchina, potremo scrivere:

$bin = decbin(10); echo(diskfreespace("/"));


echo $bin, "\n";

Le funzioni con iniziale E


che restituirà appunto "1010";

x dechex: converte un numeor da decimale a esadecimale; la sintassi è identica a quella utilizzata


per "decbin()"; x each: restituisce il primo valore di un array utilizzando le keys 0, 1, key e value; se l'array è
associativo, si può scrivere:
x decoct: converte un numero da formato decimale a formato ottale; la sintassi è la stessa utilizzata
per "decbin()";
$array = array ("nome" => "valore", "nome2" => "valore2");
x define: definisce una costante; come abbiamo visto nel capitolo sulle costanti, queste sono simili while (list($key, $val) = each ($array)) {
echo "$key => $val\n";
alle variabili solamente che non hanno il simbolo del dollaro davanti; per definire una costante si }
utilizza la seguente sintassi:
che restituirà:
define("COSTANTE", "Questa è una costante");
echo COSTANTE;
nome => valore
nome2 => valore2
L'esempio riportato sopra visualizzerà "Questa è una costante";

HTML.IT – Guide PHP 71 HTML.IT – Guide PHP 72


x eregi_replace: funziona esattamente come "ereg_replace()", solamente che in questo caso
Se invece l'array non è associativo, il codice sarà: l'espressione regolare è sostituita in maniera "case insensitive", ossia ignorando i caratteri maiuscoli
e minuscoli;
$array = array ("nome", "valore", "nome2", "valore2");
while (list($key, $val) = each ($array)) {
x eregi: funziona esattamanete come "ereg()", solamente che in questo caso l'espressione regolare è
echo "$key => $val\n"; sostituita in maniera "case insensitive";
}

x error_log: invia un messaggio di errore al file di log del webserver, direttamente alla porta TCP
ed il risultato: dalla quale è arrivata la richiesta o in un file.
La sintassi è:
0 => nome
1 => valore
2 => nome2 error_log(message, mesage_type, destination);
3 => valore2

Message_type è un numero che specifica dove deve arrivare il messaggio. Può essere:
Come avrete certamente notato, la funzione "each()" viene spesso utilizzata insieme a "list()", che
vedremo in seguito; 0: il messaggio è inviato al logger del PHP o nel file specificato da "error_log";
1: il messaggio è inviato per email al parametro (probabilmente un valido indirizzo email)
x echo: visualizza una o più stringhe; non penso ci sia molot da dire su questa funzione, vista sia la specificato in "destination"; 2: il messaggio è inviato al debvugger;
sua semplicità sia el numerose implicazioni in cui l'abbiamo vista in uso. 3: il messaggio è inserito in append al parametro specificato in destination";
x ereg_replace: sostituisce un'espressione regolare con deteminati valori; alla funzione devono x escapeshellcmd: se si richiama un comando esterno da una shell, con questo comando si fa in
essere passati tre argomenti: il primo indica il testo da sostituire, il secondo è il testo utilizzato per modo che i metacaratteri della shell vengano fatti precedere da un caratere di escape per evitare che
la sostituzione ed il terzo è la stringa da modificare; ad esempio: il comando produca degli errori;

x exec: esegue un programma esterno;


$stringa = "Questo è un corso su ASP";
echo ereg_replace("ASP", "PHP", $stringa);
x exit: esce da uno script; il comando "exit()" è utile nei casi si voglia fermare uno script in caso
Notate che si sarebbe potuto scrivere anche: qualcosa non soddisfi determinate condizioni, ad esempio:

echo ereg:replace("ASP", "PHP", "Questo è un corso su ASP"); if (condizione) {


esegui il blocco;
} else {
exit;
che non avrebbe avuto molto senso, comunque. }

x ereg: esegue il matching di un'espressione regolare. L'esempio fornito con la documentazione è Ricordate che "exit()" non riporta un messaggio di errore come fa "die()": se vi interessa dare
alquanto eloquente: "spegazioni" sul perchè lo script termina, utilizzate "die()", ma ricordate che non è possibile
scrivere:
if (ereg("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $date, $regs)) {
echo "$regs[3].$regs[2].$regs[1]";
} else { exit "Esco dal programma\n";
echo "Invalid date format: $date";
}
o meglio, è possibile ma non ha alcun effetto se non quello di uscire;
Tutto questo ciclo è fatto per controllare che una data sia in formato corretto. Vediamo il significato
di "[0-9]{4})-([0-9]{1,2})-([0-9]{1,2}". Per chi conosca le espressioni regolari, non sarà difficile x exp: eleva "e" (2.71828.....) alla potenza riportata come argomento della funzione:
tradurre quanto sopra con "un numero da 0 a 9 ripetuto quattro volte seguito da un '-', da un numero
da 0 a 9 ripetuto una o due volte, da un '-' e da un numero da 0 a 9 ripetuto una o due volte".
echo exp(3);
Come spesso accade, leggere un'espressione regolare è molto più semplice che tradurla nel
linguaggio parlato.
restituirà: 20.0855369...

HTML.IT – Guide PHP 73 HTML.IT – Guide PHP 74


x explode: divide una stringa secondo un determinato pattern. Ad esempio, volendo dividere una
stringa contenente tre nomi separati da virgole possiamo scrivere: Ovviamente, la funzione è implementata nei soli sistemi multiuser;

x filesize: restituisce la grandezza di un file:


$nomi = "Tizio,Caio,Sempronio";
list ($nome1, $nome2, $nome3) = explode (",", $nomi);
echo "$nome1\n$nome2\n$nome3\n";
$filename = "/tmp/ptova.txt";
$size = filesize($filename);
che restituirà: echo "$filename -> $size\n";

x filetype: determina il tipo di file; i valori possibili sono: fifo, char, dir, block, link, file e
Tizio unknown;
Caio
Sempronio
x flock: applica il locking ad un file; specificamente, flock() opera su un puntatore ad un file
Explode() è una versione semplificata di "split(), che vedremo in seguito. Entrambe le funzioni, precedentemente aperto e le operazioni possibili sono:
inoltre, sono molto utili nel caso ci sia la necessità di leggere determinati file contenenti delle liste;
1: per il lock in lettura;
Le funzioni con iniziali F e G 2: per il lock in scrittura;
3: per rimuovere il lock, di qualsiasi tipo sia;
4: per impedire che flock() blocchi un file mentre applica il lock;

Ad esempio, per applicare flock() ad un puntatore "$file" precedenemente definito occorrerà


x fclose: chiude un puntatore ad un file precedentemente aperto con fopen(). Si veda fopen() per
scrivere:
maggiori informazioni;

x feof: testa un puntatore ad un file per vedere se si è alla fine dello stesso; flock($file, 2);
/* Per impedire che il file sia letto*/
.....
x fgetc: restituisce il primo carttere del puntatore precedentemente aperto con fopen(); se ad /* Codice per lavorare sul file */
esempio il puntatore $file punta al file "/tmp/prova.txt" che contiene solamente la riga "Ciao", un flock($file, 3);
/* Per rimuovere il flock */
codice come il seguente:

x fopen: apre un file oppure un'URL. La sintassi è:


$char = fgetc($file);
echo "$char\n";
fopen(filename, mode);
restituirà "C" (ovviamente senza virgolette!);
Ovviamente a "filename" corrisponde il nome del file o l'URL dello stesso, ed a "mode" la modalità
x file_exists: controlla se un file esiste, riportanto TRUE in caso positivo o FALSE in caso con il quale questo deve essere aperto: si ha qui la possibiltà di scegliere fra:
negativo; ad esempio:
r -> apre il file in sola lettura;
r+ -> apre il file in lettura ed in scrittura;
if (file_exists($file)) {
print "$file esiste; w -> apre il file in sola scrittura;
} w+ -> apre il file in lettura e scrittura;
a -> apre il file in sola scrittura e inserisce il puntatore alla fine del file ("w" lo inserisce alla fine)
Può essere molto utile utilizzare questa funzione nel caso sia necessari oagire su uno o più file, in a+ -> apre il file in lettura e scrittura inserendo il puntatore alla fine del file;
modo da agire sullo stesso solo nel caso quesot esista senza rischiare di incorrere in inspiegabili
"anomalie" dello script; Ad esempio, per aprire un file locale in sola lettura scriveremo:

x filegroup: restituisce il gruppo al quale appartiene il file:


$file = fopen("/tmp/prova.txt", "r");

$filename = "/tmp/prova.txt";
$group = filegroup($filename);
Per un URL, invece:
echo "$filename appartinene al gruppo $group\n";

HTML.IT – Guide PHP 75 HTML.IT – Guide PHP 76


$file = fopen("http://www.myhost.com/index.html", r"); - is_string;
- is_writeable.
Per tutte le successive operazioni sul file, poi, dovremo agire direttamente sul puntatore ($file) e
non direttamente sul file; x isset: restituisce TRUE nel caso la variabile esista, falso nel caso opposto; ad esempio, per vedere
se esiste o meno una variabile, è possibile scrivere:
Le funzioni con iniziali H, I, J, K e L
$a = 10;
echo isset($a), "\n";
echo isset($b), "\n";

x header: invia un qualsiasi header HTTP; ad esempio:


che restituirà 1 e 0; ricordiamo che 1 è considerato valore di successo (TRUE), 0 di insuccesso
(FALSE);
header("Pragma: no-cache");
x join: unisce gli elementi di un array con una determinata stringa; l'uso è identico a quello di
Questa funzione è molto utile in dieversi casi: ad esempio, per forzare un'autorizzazione, si può implde();
inviare un "401" o via dicendo;
x key: prende una chiave da un array associativo; un semplice esempio potrebbe essere:
x hexdec: restituisce il valore decimale di un numero esadecimale;

x implode: come risulta dal nome, questa funzione non è che l'opposto di "explode": la sintassi è $array = array("1" => "uno");
$chiave = key($array);
identica, ma in questo caso restituisce una stringa con i valori separati dal primo argomento della echo "$chiave\n";
funzione;
che restituirà "1". Questa funzione è utile per estrarre tutte le chiavi di array associativi complessi;
x in_array: restituisce valore vero se in un array è presente un determinato valore; un esempio
potrebbe essere: x link: crea un hard link; la sintassi è:

$numeri = array("1", "2", "3", "4", "5"); link(target, link);


$num = 2;
if (in_array($num, $numeri)) {
print "$num è presente nell'array \$numeri\n";
} Le informazioni sui link (a proposito dell'eseitenza del file a cui punta il link stesso) possono essere
visualizzate con linkinfo();
x is_array: controlla se una data variabile è un array:
x list: assegna delle variabili come se fossero parti di un array; riprendiamo l'esempio fatto con
each:
if (is-array($var)) {
echo "\$var è un array\n";
} $array = array ("nome" => "valore", "nome2" => "valore2");
while (list($key, $val) = each ($array)) {
echo "$key => $val\n";
La stessa cosa viene fatta, con ovviamente la differenza dell'argomento, dalle funzioni: }

- is_dir; In questo caso, list() è utilizzato per "stilare" una lista di variabili che verranno estratte dall'array,
- is_double; senza ovviamente dare loro un valore ma lasciando alle parti successive del codice l'assegnazione
- is_executable; dei loro valori. E' inoltre utile notare che le variabili create da list() non assumono un solo valore,
- is_file; ma per ogni chiamata assumono un diverso valore, a seconda degli elementi presenti nell'array.
- is_float;
- is_int; Le funzioni con iniziali M, O, P e R
- is_integer;
- is_link;
- is_long;
- is_object; x mail: funzione per l'invio di email; la funzione ha sintassi:
- is_readable;
- is_real;

HTML.IT – Guide PHP 77 HTML.IT – Guide PHP 78


mail(To, Subject, Message, Altri_headers); x range: crea un array contenente un range di valori interi specificato; ad esempio, per creare un
array con valori da 1 a 10 sarà necessario scrivere:
Supponendo di voler inviare un'email a "nome@host.com" con subject "Prova" e volendo
specificare il nome del mittente, possiamo scrivere:
$array = range(1, 10);

mail("nome@host.com", "Subject", "Questo è il corpo dell'email", x rename: rinomina un file: ad esempio, si usa:
"From: mittente <mittente@host.net>);

rename("oldname", "newname");
Come vedete, inviare delle email tramite script PHP ed utilizzando la funzione "mail" è molto
semplice.
Ovviamente, nel file di configurazione, dovrete aver specificato la locazione di sendmail (o analogo per rinominare "oldname" come "newname";
programma per l'invio delle email);
x rmdir: come l'analogo somando unix, rimuove una directory; questo può essere fatto solo se:
x max: restituisce il valore più alto di una serie di variabili:
- la directory è vuota;
- i permessi sulla directory lo consentono.
$num = 1;
$num2 = 23;
$num3 = 0.3; x round: arrotonda un numero:
$max = max($num, $num2, $num3);
echo $max, "\n";

$numero = round(2,3); /* restituisce 2 */


restituirà "23"; $numero = round(2.5); /* restituisce 3 */
$numero = round(2.6); /* restituisce 3 */
Opposto a max() è min(), che adotta la stessa sintassi di max();
Come avrete notato, i decimali da 0 a 4 sono approssimati all'intero precedente, da 5 a 9 all'intero
x mkdir: crea una directory, di cui si deve specificare il percorso ed i permessi:
successivo

mkdir("/tmp/prova", 0777); Le funzioni con iniziali S, T e U

creerà la directory "/tmp/prova" con permessi impostati a 0777;

x opendir: apre una directory, della quale sarà possibile leggere gli elementi con readdir() e, x shuffle: ordina in modo casuale gli elementi di un array; ad esempio, per poter visualizzare gli
successivamente, chiuderla con closedir(); elementi di un array in manuera casuale si potrebbe scrivere:

x phpinfo: è la funzione più "rappresentativa" del PHP, in quanto visualizza moltissime


$num = range(0,10);
informazioni sul PHP stesso: l'uso dovrebbe essere noto: shuffle($num);
while (list(,$numero) = each($num)) {
echo "$numero ";
}
phpinfo();

x sin: restituisce il seno dell'espressione;


x phpversion: visualizza la versione di PHP che si sta utilizzando;
x sizeof: calcola il numero di elementi presenti in un array. Se ad esempio si volesse calcolare il
x popen: apre un puntatore ad un processo che deve essere chiuso con pclose(); numero di elementi in un array ed agire di conseguenza, si potrebbe scrivere:
x print: visualizza una stringa a video come echo();
x rand: genera un valore numerico in maniera casuale; se si volesse un valore compreso fra 10 e $array = array("1", "2", "3", "4", "5");
20, si potrebbe scrivere: $size = sizeof($array);
if ($size <= 10) {
echo "L'array contiene meno di 10 elementi\n";
} else {
echo "L'array contiene più di 10 elementi\n";
$random = rand(10, 20); }

HTML.IT – Guide PHP 79 HTML.IT – Guide PHP 80


x sleep: mette lo script in pausa per un determinato numero di secondi, specificato come argomento Per comodità, divideremo tali funzioni per "famiglia di appartenenza": ci saranno funzioni dedicate
della funzione; adesempio, "sleep(10)" farà in modo che lo script venga sospeso per 10 secondi, per ad Apache, alla crittazione, al protocollo FTP e molto altro.
poi continuare normalmente;
Funzioni legate ad Apache
x split: divide una stringa a seconda di un determinato pattern; ad esempio:

$linea = "tizio||caio||sempronio";
list ($uno, $due, $tre) = split("\|\|", $linea, 3); apache_lookup_uri
print "1 => $uno\n2 => $due\n3 => $tre\n";
Questa funzione esegue una richiesta per un determinato URI (Uniform Resource Identifier: lo
Notate che è stato necessairo inserire un carattere di escape (\) prima di ogni "|" nell'espressione da definiremo più semplicemente un indirizzo web) e riporta i risultati di tale richiesta: i risultati sono
utilizzare per splittare la riga; contenuti in un array e la sintassi è:

x sqrt: restituisce la radice quadrata dell'argomento;


$array = apache_lookup_uri($url);
x strcmp: esegue una comparazione su due stringhe: ad esempio:
Con questa funzione avremo informazioni su:

$cmp = strcmp("Ciao", "Ciao a tutti"); x status (che è poi un codice numerico);


if ($cmp == "0") {
print "Le stringhe sono identiche\n"; x the_request: il tipo di richiesta, il metodo, il file richiesto ed il protocollo utilizzato;
} elseif ($cmp < 0) {
print "La seconda riga è più lunga della prima\n"; x method: il metodo utilizzato;
} elseif ($cmp < 0) { x uri: l'uri relativo alla richiesta;
print "La prima riga è più lunga della prima\n";
} x filename: il nome del file con il path locale;
x path_info: informazioni sul path;
restituisce "La seconda riga è più lunga della prima". La funzione, infatti, restituisce "0" se le x no_cache;
stringhe sono uguali, un valore minore di zero se la seconda è più lunga della prima e maggiore di x no_local_copy;
zero se la prima è più lunga della seconda; x allowed;
x sent_bodyct;
x system: esegue un programma di sistema, ne restituisce l'output e ritorna allo script; x bytes_sent;
x byterange;
x tan: restiruisce la tangente dell'argomento;
x clenght;
x unset: elimina il valore di una variabile; x unparsed_uri;
x request_time.
x usleep: come sleep(), ma questa funziona blocca lo script per N microsecondi.
Ad esempio, utilizzando un codice come il seguente:
Con questo, abbiamo terminato di vedere quali sono le funzioni più utili del PHP, senza addentrarci
in argomenti come database e simili.
$uri = "http://localhost";
Ovviamente, la lista delle funzioni non termina qui ma, essendocene altrettante meno utili almeno $array = apache_lookup_uri("$uri");
per chi inizia a programmare con questo linguaggio, abbiamo preferito fermarci a questo punto. while ( list ( $header, $valore ) = each( $array ) ) {
echo "$header: $valore<br>\n";
}
Introduzione alle altre funzioni
si potrebbe ottenere qualcosa di simile a:

Fino a questo punto, abbiamo visto le funzioni principali del linguaggio, quelle che si potrebbero
definire "essenziali" per la creazione dei nostri script. status: 200
the_request: GET /php/prova.php3 HTTP/1.0
Ma il PHP, complice anche la sua diffusione a macchia d'olio, non si limita a questo: mette a method: GET
disposizione altre famiglie di funzioni con le quali si possono affrontare altri problemi e creare uri: /php/localhost
filename: /var/www/php/localhost
nuove soluzioni, senza dover ricorrere a sotterfugi come il richiamo delle funzioni di sistema o path_info:
no_cache: 0
simili. no_local_copy: 1
allowed: 0
sent_bodyct: 0

HTML.IT – Guide PHP 81 HTML.IT – Guide PHP 82


bytes_sent: 0 x DES
byterange: 0
clength: 0 x TripleDES
unparsed_uri: /php/localhost
request_time: 965150868 x Blowfish
x 3-WAY
getallheaders x SAFER-SK64
x SAFER-Sk128
con questa funzione è possibile richiedere tutti gli headers relativi ad una richiesta: questi headers x TWOFISH
con molti altri possono essere letti anche con la funzione "phpinfo()". La sintassi è: x TEA
x RC2
x GOST
$array = getallheaders();
x RC6
x IDEA
e, utilizzando un codice come:
Per funzionare con tale libreria, il PHP deve essere stato compilato con l'opzione "--with-mcrypt".
$headers = getallheaders();
while (list($header, $value) = each($headers)) { I comandi fondamentali sono quattro, tutti con la medesima sintassi:
echo "$header: $value<br>\n";
}
x mcrypt_cfb(): cipher feedback; codifica byte per byte;
si può ottenere qualcosa di simile a: x mcrypt_cbc(): cipher block chaining: utile per l'encoding dei file con un grande margine di
sicurezza;
x mcrypt_ecb(): electronic codebook: utilizzata per dati random, dove il livello di sicurezza non è
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* altissimo;
Accept-Charset: iso-8859-1,*,utf-8
Accept-Encoding: gzip x mcrypt_ofb(): output feedback: simile a cfb, ma è data maggiore attenzione agli errori.
Accept-Language: en
Connection: Keep-Alive
Host: localhost La sintassi in generale è:
Pragma: no-cache
User-Agent: Mozilla/4.72 [en] (X11; I; Linux 2.2.14 i586)

$encrypted = mcrypt_XXX(algoritmo, chiave, input, encode/decode)


virtual
dove:
virtual() è l'equivalente di <!--# include virtual="/file.txt"-->, chiamata relativa ai Server Side
Includes. Con questa funzione, potremo includere un qualsiasi file in una pagina generata x XXX è il metodo che si intende utilizzare (cfb, cbc, cfb o ofb);
dinamicamente con il PHP. x algoritmo è l'algoritmo che si intende utilizzare, con la sintassi:
La sintassi è semplice:
MCRYPT_ALGORITMO

virtual(file);
Ad esempio, si potrebbe utilizzare
Il file da specificare può essere qualunque file di testo e, di norma, p riferito alla directory radice MCRYPT_BLOWFISH
dell'host; quindi, se abbiamo un file visibile via web con "http:/www.dominio.com/file.txt", la
sintassi da utilizzare con "virtual()" è: oppure
MCRYPT IDEA

virtual("/file.txt");
x chiave altro non è che la chiave con cui si andranno a crittare i dati;
x input sono i dati da crittare;
Funzioni relative alla crittazione
x encode/decode indica alla funzione se si devono crittare o decrittare i dati; per questo, si usano
rispettivamente:
PHP offre agli sviluppatori una serie di funzioni relative alla crittatura, legate alla libreria mcrypt; MCRYPT_ENCRYPT
tale libreria supporta moltissimi algoritmi di crittazione, alcuni più utilizzati ed altri meno. Gli
algoritmi sono:

HTML.IT – Guide PHP 83 HTML.IT – Guide PHP 84


connessione. La sintassi della funzione è:
e
MCRYPT_DECRYPT
$login = ftp_login(stream, username, password);

Vediamo ora un esempio: volendo crittare una semplice stringa di testo con chiave di crittatura "La
mia chiave" utilizzando CFB con l'algoritmo IDEA, dovremo scrivere: Se ad esempio in precedenza ci eravamo collegati all'host "ftp.host.com", utilizzando la variabile
"$stream", adesso potremo procedere al login vero e proprio con:

$stringa = "Una semplice stringa di testo";


$chiave = "La mia chiave"; $login = ftp_login($stream, "utente", "password");
$encrypted = mcrypt_cfb(MCRYPT_IDEA, $chiave, $stringa, MCRYPT_ENCRYPT);

Chiunque voglia poi leggere i nostri dati crittati ($encrypted) dovrà ovviamente conoscere la chiave, La variabile $login ci servirà per capire se il login è andato o meno a buon fine e conterrà il valore
il metodo e l'algoritmo utilizzati; quindi potrebbe scrivere qualcosa del tipo: "1" per il successo, "0" altrimenti. Ad esempio, per vedere se continuare lo scambio di dati in
seguito all'autorizzazione potremo utilizzare il valore assegnato a tale variabile e scrivere:

$chiave = "La mia chiave";


$stringa = mcrypt_cfb(MCRYPT_IDEA, $chiave, $encrypted, MCRYPT_DECRYPT); if ($login == "1") {
... # Fai il resto delle operazioni
} else {
La sua variabile "$stringa", quindi, conterrà "Una semplice stringa di testo". echo "Autorizzazione non riuscita\n";
}

Funzioni legate al protocollo FTP Una volta connessi, potremo sapere su che macchina stiamo lavorando con la funzione
"ftp_systype()" che ha sintassi:
Fra i vari protocolli, PHP ci mette a disposizione una vasta libreria di funzioni legate al protocollo
FTP (FILE TRANSFER PROTOCOL), per il trasferimento di file da un computer all'altro in una $system = ftp_systype($stream);
rete. Vediamone le principali.
ftp_pwd
ftp_connect
Questa funzione invoca il comando "pwd", ovvero "Print work directory", che potremo tradurre
Questa è la funzione "principale" nel senso che ci permette di stabilire una connessione FTP fra la
come "Visualizza la directory corrente". Per vedere a che directory veniamo connessi dopo il login,
nostra macchina ed il server FTP remoto. La sua sintassi è:
potremo scrivere:

$stream = ftp_connect(host, port);


$directory = ftp_pwd($stream);

dove host è il nome del server a cui intendiamo connetterci e port (opzionale) è la porta alternativa dove $stream è sempre la variabile che abbiamo utilizzato per la connessione con "ftp_connect()".
alla quale ci si vuole connettere; se questa non è specificata, viene utilizzata la porta di default per il
ftp_cdup e ftp_chdir
protocollo FTP, ossia la 21. Nella variabile $stream, inoltre, viene immagazzinato appunto lo
stream di dati che il client (in questo caso il PHP) riceve dal server, ossia i messaggi di connessione Queste due funzioni servono rispettivamente a muoversi alla directory superiore e a muoversi in una
accettata (con i vari dettagli) o di connessione rifiutata. determinata directory all'interno del server.
La prima si utilizza con sintassi:
Ad esempio, per connetterci alla porta di default del server FTP "ftp://ftp.host.com" utilizzeremo:

$var = ftp_cdup($stream);
$stream = ftp_connect("ftp://ftp.host.com");

La seconda invece:
ftp_login

Dopo la connessione, abbiamo bisogno di identificarci in modo che il server ci permetta lo scambio $newdir = ftp_chdir($stream, "nuova_directory");
dei dati. molti saranno abituati a non vedere tale fase visto che, con i più diffusi client FTP grafici
essa è svolta in automatico utilizzando le informazioni di login (username e password) inseriti come Se ad esempio al login siamo nella directory "/" e volessimo spostarci in "/var/wwwdata" potremo
opzioni per il collegamento, ma sappiate che questa è una fase di vitale importanza per la

HTML.IT – Guide PHP 85 HTML.IT – Guide PHP 86


scrivere: scriveremo:

$newdir = ftp_chdir($stream, "/var/wwwdata"); $file = ftp_get($stream, "/tmp/file.txt", "data.txt", FTP_ASCII);

ftp_mkdir e ftp_rmdir Per vedere se l'operazione ha avuto o meno successo, possiamo operare in due modi: controllare se
effettivamente il file c'è nel nostro disco oppure controllare il valore della variabile $file: se ha
Queste due funzioni invocano il comando "mkdir "(crea una directory) e "rmdir" (rimuovi una valore "1" allora l'operazione è stata completata, se ha valore "0" nessun file sarà stato scaricato sul
directory). La prima restituisce il nome della nuova directory, la seconda solamente i valori true o nostro disco.
false. Potremo creare un piccolo loop e scrivere:
ftp_put

$mydir = ftp_chdir($stream, "/var/wwwdata/");


# Posizioniamoci in "/var/wwwdata".
$newdir = ftp_mkdir($stream, "prova") Questa funzione fa esattamente il contrario di "ftp_put()", ossia carica un file sul server. La sua
# Creiamo la directory "prova" come sottodirectory di "/var/wwwdata"
$deleted_dir = ftp_rmdir($stream, $newdir);
sintassi è:
# Cancelliamo la directory appena creata!
# Possiamo ora controllare il tutto con:
if ($deleted_dir == "1") {
print "Operazione completata con successo.\n"; $file = ftp_put($stream, remote_filename, local_filename, mode);
} else {
print "Qualcosa non è andato per il verso giusto.\n";
} Le opzioni sono identiche alle precedenti, quindi possiamo fare l'esempio contrario del precedente:
carichiamo il file locale "/tmp/file.txt" nella directory remota (siamo già in questa directory) con il
Ovviamente l'esempio non ha molto senso in una vera connessione (perchè creare una directory e nome "data.txt". Tutto in ASCII mode, ovviamente:
subito cancellarla?), ma è stato proposto per comprendere come utilizzare al meglio queste due
funzioni.
$file = ftp_put ($stream, "data.txt", "/tmp/file.txt", FTP_ASCII);
ftp_nlist
Anche qui, possiamo controllare in due modi: valutando il valore di $file oppure invocando la
Questa funzione è analoga al comando "dir", ossia il comando utilizzato per vedere i nomi dei file funzione "ftp_nlist()" per vedere se fra i file c'è anche "data.txt".
presenti in una directory. La sua sintassi è:
ftp_sise

$list = ftp_nlist($stream, directory); Restituisce le dimensioni di un dato file. La sintassi è:

Ad esempio, possiamo portarci nella directory "/var/wwwdata" e leggerne i file con:


$size = ftp_size($stream, remote_filename);

$newdir = "/var/wwwdata";
$list = ftp_nlist($stream, $newdir);
Per tornare agli esempi precedentemente fatti, vediamo di conoscere la grandezza del file "data.txt",
che si trova nella directory in cui siamo al momento; basterà scrivere:
I risultati sono contenuti in un array, quindi un 'echo "$list"' non avrebbe alcun senso.
$size = ftp_size($stream, "data.txt");
ftp_get
in modo che la variabile $size contenga le dimensioni del file "data.txt".
Funzione che richiama il comando GET, per scaricare un file dal server remoto. Dobbiamo
specificare per la funzione, oltre al solito stream, il nome del file locale, il nome del file remoto e la ftp_mdtm
modalità di trasferimento (FTP_ASCII o FTP_BINARY); la sintassi completa è:
Restituisce la data di ultima modifica di un file, restituendola come Unix timestamp. La sintassi è:
$file = ftp_get($stream, local_filename, remote_filename, mode);

$date = ftp_mdtm($stream, remote_filename);


Ad esempio, volendo scaricare dal server il file "data.txt" (supponiamo di essere già all'interno della
directory che lo contiene) inserendolo nella directory "/tmp" con nome "file.txt" in ASCII mode,

HTML.IT – Guide PHP 87 HTML.IT – Guide PHP 88


Ad esempio, volendo sapere la data di ultima modifica del file "data.txt" possiamo scrivere:
Questa famiglia di funzioni, che vedremo per sommi capi, è relativa al lavoro in rete e tratta
soprattutto di protocolli, indirizzi ecc. Certamente non è fondamentale per gli script di semplice
$date = ftp_mdtm($stream, "data.txt"); creazione di pagine dinamiche ma può essere utile conoscerla.

Anche in questo caso, la variabile "$data" conterrà la data di ultima modifica del file oppure il gethostbyaddr e gethostbyname
valore "-1" in caso di insuccesso (file inesistente o casi del genere).
Queste due funzioni permettono, rispettivamente, di ricavare il nome di un host partendo dal suo
ftp_rename e ftp_delete indirizzo IP e di ricavare l'indirizzo IP associato ad un nome di dominio.
Le sintassi per entrambe le funzioni sono:
Come apparirà chiaro dai nomi, queste due funzioni servono per rinominare un file e per
cancellarlo. La prima ha sintassi:
$hostname = gethostbyaddr(IP_address);
$hostaddress = gethostbyname(hostname);

$name = ftp_rename($stream, oldname, newname);


Ad esempio, poniamo che "www.server.com" abbia indirizzo IP 123.456.78.9 che noi sappiamo:
dove "oldname" è il nome originario del file e "newname" è il nuovo nome che vogliamo assegnare ma vogliamo che sia uno script PHP a dircelo.
al file. Scriveremo quindi:
Ad esempio, per rinominare il file "data.txt" in "dati.dat" possiamo scrivere:
$hostname = gethostbyaddr("123.456.78.9");
$hostaddress = gethostbyname("http://www.host.com");
$name = ftp_rename($stream, "data.txt", "dati.dat"); print "$hostname ha indirizzo IP $hostaddress.\n";

La variabile $name conterrà "1" se l'operazione ha avuto successo, "0" altrimenti (file inesistente o Ovviamente uno script del genere è inutile, visto che sappiamo già i dati, ma lo si è proposto
casi simili). solamente per evidenziare le caratteristiche delle due funzioni.

La funzione "ftp_delete(),invece, si utilizza con sintassi: getservbyname

Questa funzione ci permette di ricavare il numero della porta alla quale è associato un determinato
£delete = ftp_delete($stream, file); servizio. La sintassi delle funzione è:

Ad esempio, per eliminare il file "dati.dat" presente nella "current-directory" possiamo scrivere:
$porta = getservbyname(service, protocol);

$delete = ftp_delete ($stream, "dati.dat"); Ad esempio, volendo sapere a che porta è associato il protocollo ftp, possiamo scrivere:

Anche in questo caso la variabile può contenere valore "1" (il file è stato eliminato) o "0" (qualcosa
non è andato per il verso giusto). $ftp_port = getservbyname("ftp", "tcp");

ftp_quit che con grande probabilità ci restituirà la porta 21 (quella di default per il FTP).

A questo punto, il nostro lavoro sul server è terminato e possiamo disconnetterci utilizzando la Standard POSIX
funzione "ftp_quit()" che ha la semplice sintassi:

Il PHP mette a disposizione molte funzioni POSIX-compliant, come definito nello standard
$quit = ftp_quit($stream).
document IEEE 1003.1; tali funzioni ci permetteranno di innestare una completa interazione con il
sistema, per un'ottimale scrittura dei nostri script. Vediamo quali sono le funzioni più significative
E' sempre consigliato invocare questa funzione invece di chiudere il programma in esecuzione, più di questo gruppo.
che altro per una questione di rispetto verso il server.
posix_kill
Funzioni relative al networking

HTML.IT – Guide PHP 89 HTML.IT – Guide PHP 90


x Effective GID del processo.
Invia un segnale ad un determinato PID, restituendo FALSE in caso il PID non sia associato ad
alcun processo, vero nel caso opposto. La sua sintassi è: Possiamo vedere un esempio che le visualizzi tutte:

posix_kill(PID, SIG) $UID = posix_getuid();


echo "UID = $UID\n";
$EUID = posix_geteuid();
dove PID è il pid del processo a cui vogliamo inviare il segnale e SIG è, appunto, il segnale. Ad echo "EUID = $EUID\n";
$GID = posix_getgid();
esempio, volendo inviare un segnale di kill a Netscape (pid 1234), potremo scrivere: echo "GID = $GID\n";
$EGID = posix_getegid();
echo "EGID = $EGID\n";

$pid = "1234";
$signal = posix_kill($pid, KILL); posix_getlogin

Maggiori riferimenti si possono ritrovare nella manpage di kill(2). Questa funzione ci permette di recuperare il nome di login dell'utente che esegue lo script; ad
esempio, potremo scrivere:
posix_getpid

Utilizzare la funzione sopra descritta lavorando da uno script è assai duro per un semplice motivo: $login = posix_getlogin("/usr/sbin/apache");
echo $login;
non avendo accesso alla shell, non possiamo sapere il PID associato ad una determinata
applicazione. Ma il PHP ci viene incontro anche in questo con la funzione posix_getpid, che
per fare in modo di aver visualizzato a video il nome dell'utente che esegue lo script.
permette di inserire in una variabile il PID di un processo. La sintassi è:

posix_uname
$pid = posix_getpid($application);

Questa funzione è simile ad "uname" dei sistemi Posix-compliant e restituisce informazioni sul
dove application è ovviamente l'applicazione delle quale ci interessa il PID. Utilizzando questa
sistema. Tali informazioni sono organizzate in un array che contiene le keys:
funzione con la precedente, potremo scrivere qualcosa del tipo:
x sysname
$pid = posix_getpid("netscape"); x nodename
$signal = posix_kill($pid, KILL); x release
x version
posix_getppid x machine

La funzione posix_getppid() restituisce il padre del processo in uso; ad esempio, scrivendo un paio Ad esempio, lanciando uno script del tipo:
di righe di codice come le seguenti:

$uname = posix_uname();
$parent = posix_getppid(); while (list($key, $value) = each ($uname)) {
echo $parent; echo "$key -> $value\n";
}

avremo visualizzato a video il padre del processo che abbiamo appena lanciato: nel nostro caso, si otterrà come risultato:
visto che abbiamo lanciato il comando da una shell, il PID sarà proprio legato alla shell.

posix_getuid, posix_geteuid, posix_getgid, posix_getegid sysname -> Linux


nodename -> scatolinux
release -> 2.2.14
Queste quattro funzioni sono molto simili e restituiscono rispettivamente: version -> #11 mar lug 4 00:06:07 CEST 2000
machine -> i586
x Real user ID del processo;
x Effective user ID del processo; posix:getpwname
x Real GID del processo;
Questa funzione ci permette di avere determinate informazioni su un utente del sistema partendo dal

HTML.IT – Guide PHP 91 HTML.IT – Guide PHP 92


suo ID; allo stesso modo, la funzione "posix_getpwuid()" riporta le stesse informazioni partendo dal a vedere è sostanziale: le prime sono presenti direttamente all'interno del motore (built-in), le
suo ID. Un esempio potrebbe essere qualcosa del tipo: seconde sono presenti in librerie aggiuntive che devono essere installate sul sistema e richiamate in
maniera particolare.

$user = posix_getpwnam("edo");
while (list($info, $value) = each($user)) {
Prima di tutto, vediamo di capire il meccanismo di caricamento dinamico di queste librerie: aprendo
echo "$info -- $value\n"; il file "php3.ini" vedremo un paragrafo dedicato alle "Extension", ossia estensioni nel linguaggio
}
stesso: per spiegarci meglio, potremo dire che queste sono un insieme di librerie che vengono
richiamate al momento dell'esecuzione di uno script come avviene, in maniera analoga, per il
che restituisce: caricamento dei moduli con un webserver.
La sintassi per il caricamento di queste estensioni di linguaggio è molto semplice: una volta che
avremo installato la libreria sul sistema, non ci resta che aggiungere nel file php3.ini la riga:
name -- nome_utente
passwd -- x
uid -- NUM
gid -- NUM
gecos -- ,,, extension=libreria
dir -- /home/nome_utente

E' qui necessario un discorso mirato per i sistemi Unix ed i sistemi Windows: per entrambi la
dove "nome_utente" è il nome dell'utente e "/home/nome_utente" è la sua home directory, NUM sintassi è identica, ma ovviamente il nome delle librerie e la loro estensione no! Nei sistemi
sono i due attributi numerici associati all'UID ed al GID e gecos sono informazioni addizionali Windows, una libreria si riconosce dall'estensione ".dll", mentre per Unix questa è ".so": quindi, a
sull'utente, se inserite (ad esempio il nome completo ecc.). seconda del sistema, dovremo utilizzare il corretto nome per la libreria e, soprattutto, la corretta
estensione. Ovviamente, per chi abbia entrambi i sistemi installati e riesca da uno dei sistemi a
posix_getrlimit vedere l'altro è chiaro che le dll non possono essere caricate su un sistema Unix e viceversa.
Nello scrivere il nome della libreria che ci interessa caricare, non dobbiamo soffermarci sul
Questa funzione restituisce un array contenente i limiti delle risorse del sistema: senza vedere le percorso completo, ma è necessario solamente il nome della stessa, ad esempio "pgsql.so" per i
voci che riporta, vediamone un esempio: database Postgres. Questo perchè, nello stesso file, è presente un'altra linea di configurazione che
definisce in quale directory sono presenti queste librerie: leggendo il file php3.ini potrete trovare la
$resources = posix_getrlimit(); riga "extension_dir = directory" che istruirà il motore sulla locazione standard delle librerie. Quindi,
while (list($key, $value) = each ($resources)) { quando specifichiamo con "extension" una libreria che vogliamo sia caricata per l'esecuzione di uno
echo "$key -> $value\n"; script, vengono di fatto uniti "extension_dir" e "extension": se ad esempio "extension_dir" è
} "/usr/lib/php3" e abbiamo impostato "extension=pgsql.so", il PHP saprà che per caricare la libreria
"pgsql.so" dovrà cercarla in "/usr/lib/php3/pgsql.so".
che restituirà un output del tipo:
Inoltre, con "extension= ...." è possibile specificare non solo una libreria ma tutta la seri di librerie
che ci possono fare comodo: ad esempio possiamo avere qualcosa del tipo:
soft core -> 0
hard core -> unlimited
soft data -> unlimited
hard data -> unlimited
soft stack -> 8388608 extension=pgsql.so
hard stack -> unlimited extension=mysql.so
soft totalmem -> unlimited extension=gd.so
hard totalmem -> unlimited extension=imap.so
soft rss -> unlimited extension=ldap.do
hard rss -> unlimited extension=xml.so
soft maxproc -> 256
hard maxproc -> 256
soft memlock -> unlimited e via dicendo; come noterete dalla seconda riga, poi, è possibile specificare anche due o più librerie
hard memlock -> unlimited
soft cpu -> unlimited per uno stesso "campo" in questo caso, ci sono due librerie per due database (Postgres e mySQL)
hard
soft
cpu -> unlimited
filesize -> unlimited
che, oltre a non entrare in conflitto l'una con l'altra, potrebbero teoricamente anche essere utilizzate
hard filesize -> unlimited contemporaneamente, a patto che questo abbia un'utilità.
soft openfiles -> 1024
hard openfiles -> 1024
Nel caso si cerchi di richiamare una funzione non built-in all'interno di uno script, lo script
Le estensioni visualizza una messaggio d'errore che ci avverte che stiamo cercando di utilizzare una funzione non
riconosciuta: ad esempio, per i database, devono essere caricate le estensioni come detto prima e,
solo dopo aver compiuto questo passo, sarà possibile utilizzare le funzioni ad essi relativi senza
incorrere in messaggi d'errore, sempre che queste siano utilizzate in maniera corretta, ovviamente.
Nei precedenti capitoli abbiamo visto le principali funzioni legate al linguaggio per la creazione
delle nostre pagine dinamiche. La differenza fra quelle funzioni e la famiglia di quelle che andremo

HTML.IT – Guide PHP 93 HTML.IT – Guide PHP 94


Il perchè delle estensioni
Prima di tutto, dobbiamo essere sicuri di aver installato sul sistema la libreria PHP che permette
l'interazione con il database, installando il pacchetto ed, eventualmente, istruendo il motore sulla
A questo punto, ci sarà sicuramente chi si chiederà il perchè di questa librerie aggiuntive (a volte locazione nella quale andare a cercare tale libreria.
molto importanti o addirittura essenziali) che devono essere scaricate, installate e richiamate Per quanto riguarda il pacchetto, esso è chiamato sui sistemi Linux "php3-pgsql", ma potrebbe
indirettamente: la spiegazione è semplice: per non appesantire inutilmente il motore. Di per sè, avere altri nomi per altri sistemi: in linea di massima, dovrete cercare (teoricamente anche sul sito
questo ha già un grande numero di funzioni built-in, che potremo definire le funzioni "principali" PHP) il package che permette di connettersi a database PostgreSQL direttamente da script PHP.
per il linguaggio, sebbene alcune possano sembrare di poca utilità. Immaginate ora che il motore Una volta installato, dovrete localizzare la libreria scritta per questo scopo, che nel mio sistema
avesse al suo interno anche tutte le funzioni relative a tutti i database che supporta: avrebbe un altro viene caricata in:
centinaio (abbondante) di funzioni al suo interno; e questo non sarebbe un male se il 95% di queste
non fosse inutilizzato! Chi, infatti, ha la necessità di lavorare con il PHP ed una decina di database
/usr/lib/php3/apache/pgsql.so.
differenti? E' sicuramente meglio installare l'estensione per il database che si deve utilizzare e non
appesantire il motore con funzioni che certamente non utilizzeremo mai. Inoltre, pensate anche alle
funzioni della libreria GD: senza dubbio sono interessanti per i risultati che permettono di ottenere, Ovviamente, questa cambierà non solo da architettura ad architettura, ma probabilmente anche da
ma quanti in realtà le utilizzano? E' più semplice fornire tutte queste funzioni in un file separato e sistema a sistema, quindi massima attenzione a non dimenticare questo passaggio o, ad ogni
lasciare che questo venga installato ed utilizzato da chi ne ha veramente bisogno. connessione con un database, verrete avvertiti che avete chiamato una funzione non implementata
in PHP (il messaggio di errore è qualcosa di simile a "Call tu unsupported function
Se ci pensate, è quello che avviene per tutti i linguaggi di programmazione: esistono le primitive nome_funzione()"). Apriamo a questo punto una parentesi: se avete dato un'occhiata al manuale
(che, in linea di massima, possiamo definire come le funzioni essenziali e built-in in un sistema) e le PHP, avrete certamente visto che esistono moltissime funzioni (alcune delle quali viste nelle
funzioni in qualche modo esterne che vengono richiamate all'occorrenza. Rimanendo nei linguaggi precedenti pagine), fra le quali anche le funzioni proprie per l'interazione con i database; ma molte
di scripting, un paragone può essere fatto ad esempio con il Perl: anch'esso ha una nutrita schiera di di queste funzioni non sono implementate direttamente all'interno del motore per ovvi motivi e
funzioni built-in nell'interprete, alle quali si aggiungono la quasi infinità di moduli che il devono essere caricate in runtime seguendo determinate direttive. Con "ovvi motivi" intendiamo un
programmatore può utilizzare all'interno delle proprie creazioni. inutile appesantimento del motore, che dovrebbe altrimenti contenere direttamente tutte le funzioni
per tutti i database supportati che, con grandissima probabilità, non utilizzeremo mai.
Introduzione a PHP e database
Detto questo, possiamo passare al file di configurazione del php, aggiungendo in esso la directory
dove è presente la libreria appena caricata in modo che il motore la possa utilizzare. Per fare questo
Come credo molti sapranno, uno dei campi nei quali il PHP da il meglio di sè stesso è l'interazione sarà semplicemente necessario localizzare la linea che inizia con:
con database SQL. Nelle guide pratiche precedentemente pubblicate su queste pagine, avete visto
come interagire con un database mySQL: vedremo qui le basi teoriche, con esempi dove lo si
extension_dir
necessiti, per la connessione e l'interazione con un database PostgreSQL.

Analizzeremo quindi tutte le funzioni che il PHP ci mette a disposizione per poter lavorare in rete Come dalla sua descrizione, capiamo subito che in questa directory sono presente i moduli da
con un database e non come creare un database: a questo scopo, può tornarvi utile il tutorial di utilizzare. Modifichiamola quindi come:
Lucio Benfante pubblicato sulle nostre pagine.
extension_dir = /path/perl/i/nuovi/moduli
Supponiamo di aver creato il database "rubrica", con al suo interno la tabella "indirizzi"; lanciando
"SELECT * FROM indirizzi" otteniamo:
che ad esempio nel mio sistema sarà:

extension_dir = /usr/lib/php3/apache

A questo punto, siamo sicuri che riusciremo ad utilizzare le funzioni legate ai database senza
problemi di esecuzione degli script. Iniziamo quindi la panoramica su di esse, utilizzando esempi
dove necessario e rimandando alle guide pratiche al PHP per ulteriori esempi.

Questi sono i dati con cui andremo a lavorare, ma prima vediamo una panoramica delle funzioni Funzioni
messe a disposizione del PHP per l'interazione con il database PostgreSQL.

Configurazioni prima di iniziare Iniziamo con un piccolo avvertimento: tutte le funzioni relative al database PostgreSQL hanno il

HTML.IT – Guide PHP 95 HTML.IT – Guide PHP 96


nome che inizia con "pg_": questo ovviamente per distinguerle dalle funzioni simili utilizzate per
altri database: sarebbe stato poco sensato utilizzare una funzione con il nome generico "connect()" che riporterà valore vero (1) nel caso la connessione sia stata precedentemente stabilita e, con
per la connessione ad un database: troverete quindi la funzione "pg_Connect()" e la funzione, ad questo comando, chiusa, falso (0) nel caso opposto.
esempio, "mysql_connect()" e molte altre il cui nome termina con "connect" ma riferite a differenti
database. pg_DBname

Possiamo ora iniziare l'analisi delle funzioni che ci possono tornare utili nei nostri script. Questa funzione restituisce il nome del database al quale siamo connessi, oppure il valore falso nel
caso non sia stata stabilita una connessione; la sintassi per utilizzare tale comando è:
pg_connect

Apre la connessione con un database Postgres; la sintassi delle funzione accetta come argomenti $dbname = pg_DBname($connessione);
echo "$dbname\n";
l'host, la porta, determinate opzioni (opzionali), la tty (opzionali) ed il nome del database: ognuno di
questi valori deve essere racchiuso fra virgolette. La connessione da un database PostgreSQL può
pg_ErrorMessage
anche essere effettuata con:
Restituisce una stringa contenente un messaggio d'errore proveniente dal database.
pg_connect("dbname=... port=... host=... tty=... options=... user=... password=...");
pg_Exec
Ovviamente, al posto dei puntini vanno sostituiti i valori necessari alla connessione; per la
-------- Di base, questo comando esegue una query sul database. Ci si aspetterebbe che tale funzione
connessione al nostro neo-creato database locale, possiamo semplicemente scrivere:
riportasse i campi interessati dalla query ma non è così: se ad esempio scriviamo:

$connessione = pg_connect("dbname=rubrica");
$query = pg_Exec($connessione, "SELECT * FROM indirizzi");

Con questa semplice sintassi ci siamo quindi connessi al nostro database; per verificarlo, comunque,
non possiamo visualizzare direttamente il valore di $query, o meglio non ha senso farlo. Dovremo
possiamo semplicemente aggiungere:
servirci di altre funzioni che vedremo in seguito, ad esempio pg_Numrows, pg_Fetch_Array ecc.

$connessione = pg_connect("prova_db");
pg_Fetch_Array
if ($connessione) {
print "Connesso\n";
} Esegue il fetch di una riga inserendo i valori all'interno di un array. Abbiamo precedentemente
parlato di pg_Exec e del fatto che molte funzioni siano "complementari" ad essa: è proprio il caso di
In questo modo, se si riesce a stabilire una connessione (e quindi se la variabile $connessione è pg_Fetch_Array: possiamo esemplificare il tutto con:
definita), apparirà una riga di conferma. Uno degli errori più usuali è pensare che $connessione, in
questo caso, possa essere letta per vedere i valori inseriti nel database: inserire "echo $connessione" $query = pg_Exec($connessione, "SELECT * FROM indirizzi");
non ha alcun senso perchè lo script riuscirebbe solamente a restituirci un "1" nel caso la $query_result = pg_Fetch_Array($query, 0);
echo "<b>Nome:</b> ";
connessione sia effettuata e uno "0" in caso contrario. Quindi, $connessione e, più in generale echo $query_result[0], "<br>";
qualsiasi variabile che associamo alla funzione pg_connect (e, in generale, a tutte le funzioni di echo "<b>Cognome:</b> ";
echo $query_result[1], "<br>";
connect relative ad altri database) è solamente lo stato della connessione, non qualcosa da utilizzare echo "<b>Indirizzo:</b> ";
echo "$query_result[2], $query_result[3] <br>";
per leggere i dati del database. Vedremo in seguito come leggere i dati e visualizzarli in una pagina
web.
Vediamo più da vicino cosa abbiamo fatto: intanto, con pg_Exec_Query abbiamo impostato la
pg_Close query da eseguire sul database; con il successivo pg_Fetch_array abbiamo specificato che la prima
riga della query (la riga il cui numero indice è zero) venisse memorizzata nella variabile
Come si potrà immaginare, la funzione pg_Close chiude una connessione precedentemente aperta $query_result; in seguito, abbiamo visualizzato tutti i dati formattandoli per una pagina HTML.
con pg_Connect. Notate che pg_Fetch_Array accetta come parametri la query (nel nostro caso $query) e la riga a cui
Per chiudere la connessione che abbiamo aperto con il codice sopra presentato, basterà utilizzare la fare riferimento; noi, in questo caso, abbiamo scelto la prima, ma con una sintassi più "mirata"
sintassi: avremo potuto creare la stessa pagina con tutti i dati inseriti nel database:

$disconnessione = pg_Close($connessione); $query = pg_Exec($connessione, "SELECT * FROM indirizzi");


$righe=pg_numrows($query); // vedremo la funzione pg_numrows più avanti
for ($num=0;$num<=$righe-1;$num++) {

HTML.IT – Guide PHP 97 HTML.IT – Guide PHP 98


$query_result=pg_fetch_array($query, $num); ma troverete sempre OCIExecute, OCIRowcount ecc; si saranno poi delle funzioni con un nome
echo "<b>Nome:</b> ";
echo $query_result[0], " leggermente differente ma allo stesso tempo autoesplicativo: con Oracle8 non avrete la funzione
";
ecc. ecc.
OCIConnect ma OCILogon e via dicendo. Insomma, partendo da quanto letto sopra si può lavorare
} con la grande maggioranza dei database supportati dal PHP.

In questo modo, con un semplice "for" e sapendo il numero totale delle righe interessate dalla Gestione dei Cookies
query, abbiamo fatto in modo che tutte vengano processate e visualizzate.

pg_Fetch_Object Come ogni buon linguaggio legato alla generazione dinamica di pagine web, anche il PHP consente
di gestire i cookies, piccoli file di testo contenenti informazioni utili e non dannose per la gestione
Questa funzione esegue le stesse operazioni della precedente con la differenza che in questo caso delle sessioni sul web.
viene creato un oggetto con i risultati della query e non un array di dati; in questo modo, non Essendo il PHP un linguaggio nato per l'interazione con il WWW, le funzioni relative ai Cookies
dovremo più richiamare i dati all'interno dell'array con i numeri indice, ma potremo utilizzare il sono interne al PHP stesso, differentemente da come avviene per altri linguaggi, Perl su tutti (a
nome del campo: ed esempio: questo proposito, si veda il tutorial sui Cookies in Perl pubblicato su CGIpoint, nonchè la
recensione di cookie-lib presente nello stesso sito).
$query = pg_Exec($connessione, "SELECT * FROM indirizzi");
$query_result = pg_Fetch_Object($query, 0); La funzione che ci interessa è solo una: setcookie(). La sua sintassi di base è:
echo "Nome: ", $query_result->nome;
echo "Cognome: ", $query_result->cognome, "\n";
echo "Indirizzo:", $query_result->indirizzo, "\n"; setcookie(Nome, Valore, Espirazione, Percorso, Dominio, Secure);

Anche in questo caso avremo potuto inserire un blocco "for" per visualizzare tutti i dati presenti nel Vediamo di chiarire le opzioni che si possono passare alla funzione:
database.
x Nome è il nome del cookie, che può essere arbitrariamente scelto;
pg_NumFields e pg_NumRows x Valore è il valore, anch'esso arbitrario, da assegnare al cookie;
x Espirazione è la data di espirazione del cookie;
Queste due funzioni restituiscono, rispettivamente, il numero di campi e di righe interessate dalla x Percorso è la directory, a partire dal dominio (vedi sotto) per la quale il cookie è valido;
query; abbiamo visto la funzione pg_NumRows precedentemente, ma possiamo sintetizzare l'uso di x Dominio è il dominio per il quale il dominio è valido;
entrambe le funzioni con: x Secure è un valore che imposta se il cookie debba essere inviato tramite una connessione HTTPS.

$query = pg_Exec($connessione, "SELECT * FROM indirizzi WHERE nome LIKE


Poniamo di voler inviare dalla nostra pagina un cookie chiamato "Test", con valore "Prova per il
'Ma%' OR cognome LIKE 'Ro%'"); cookie Test", con espirazione di un minuto dal momento dell'invio, per la directory "/nomeutente"
$righe = pg_NumRows($query);
$campi = pg_NumFields($query); del dominio "http://www.dominio.com" senza utilizzare una connessione HTTPS: i parametri da
echo "La query interessa $righe righe e $campi campi.\n"; passare a setcookie sono:

Come vedete, abbiamo reso più complicata la query ma il resto del codice è molto semplice da
comprendere! setcookie("Test", "Prova per il cookie Test", time()+60, "/nomeutente", ".dominio.com", 0);

E a questo punto? Le cose interessanti da esaminare sono due: il tempo di espirazione e la connessione HTTPS. Per la
seconda, impostiamo con "0" che la connessione deve essere una normale connessione HTTP; se
volessimo utilizzare il protocollo sicuro HTTPS, dovremo inserire il valore "1". Il tempo di
Con questo speriamo di avervi dato una buona veduta d'insieme delle funzioni del PHP utilizzabili espirazione non può essere impostato come "Tre tre minuti", poichè la cosa non ha tempo:
con il database Postgres. Non sono state trattate le funzioni meno importanti per un semplice dobbiamo invece impostare il momento di espirazione a partire dal momento in cui il cookie è
motivo: si ritiene più opportuno, per il momento, iniziare con un'infarinatura sull'argomento che vi inviato all'utente; per questo, utilizziamo la funzione interna time() alla quale aggiungiamo il
possa già comunque rendere operativi; se l'argomento poi è tale da suscitare ulteriore interesse, sta numero di secondi dopo i quali il cookie deve scadere. Ad esempio, se il cookie viene inviato alle
al lettore approfondirlo. 13:20:00 e vogliamo che esso espiri dopo 30 minuti (60x30=1800 secondi) possiamo scrivere come
espressione di expire:
Un'altra questione è quella della scelta del database: chi scrive lavora con Postgres, quindi la scelta
è stata d'obbligo; per chi utilizzi altri database, sappia che le funzioni, sebbene con nomi differenti,
time()+1800
fanno al 90% dei casi quanto qui descritto: la sintassi è la stessa, i risultati sono gli stesso e ciò che
cambia è solo il nome delle funzioni; ad esempio, per Oracle8 i nomi delle funzioni saranno OCI...

HTML.IT – Guide PHP 99 HTML.IT – Guide PHP 100


dall'utente nella maschera di autorizzazione coincidono con questi, l'autorizzazione riesce,
In questo modo, time() riporta le 13:20:00 e time()+1800 sarà 13:50:00 altrimenti fallisce.

Fra i sei valori da passare come argomento al cookie, solamente il primo è obbligatorio: gli altri Ma come avviene tutto questo?
possono essere lasciati bianchi se non sono di particolare interesse. Inoltre, per l'invio di un cookie, Vediamo come funziona lo script appena presentato.
è necessario cheto venga inviato al browser prima di qualsiasi output: è quindi necessario inserire la Prima di tutto, questo controlla se sia impostata la variabile PHP_AUTH_USER, ossia l'username
funzione prima di ogni tag <HTML> o <HEAD>. dell'utente che accede alla pagina protetta. Se questa esiste, probabilmente l'utente si è
precedentemente autorizzato e, per questo motivo, essa viene "ricordata"; In ogni caso, sia che
Per finire, vediamo come leggere un determinato cookie da uno script: ricordando che un cookie l'utente si sia precedentemente autorizzato sia che sia la sua prima visita alla pagina, viene
viene inviato come un array di dati, possiamo ricorrere alle funzioni relative agli array: quindi controllato che l'username e la password precedentemente inserite o inserite al momento nella
potremo scrivere ad esempio: maschera di autorizzazione siano esattamente $username e $pwd: se combaciano, è possibile
visualizzare l'output per l'avvenuta autorizzazione (quello che abbiamo impostato come
"Autorizzazione riuscita per $username"); nel caso contrario, viene visualizzato un messaggio
if (isset ($HTTP_COOKIE_VARS) )
{ while (list ($nome, $valore) = each ( $HTTP_COOKIE_VARS ) )
d'errore (nel nostro caso "Autorizzazione fallita). Se invece non esiste $PHP_AUTH_USER, viene
{ echo "$nome = $valore\n"; inviato un header per l'autorizzazione (il codice 401) che presenta all'utente la maschera che gli
}
} richiede username e password: una volta inserite, sarà eseguito il blocco descritto sopra e, se l'utente
decide di non autorizzarsi, gli viene presentata una pagina contenente il testo "Impossibile eseguire
Quindi, per tutte le informazioni inserite nel cookie, verrà visualizzata una coppia "nome = valore": l'autorizzazione", che è comunque personalizzabile.
ovviamente, il valore è il valore che voi avete impostato nel cookie, i "nome" sono: cookie, expires,
path, domain e secure (quest'ultimo è particolare, visto che se impostato su 1 fa apparire "secure" La funzione che controlla tutto questo meccanismo è "header()", utilizzata per mandare un header al
nel cookie, altrimenti non fa apparire alcunchè). browser che ha inviato la richiesta; essendo quello che viene inviato un header, è necessario che
Per il nostro cookie di esempio, leggeremo qualcosa del genere: questo venga inviato prima di qualsiasi altro output. La funzione è molto semplice, vediamone degli
esempi:

cookie=Test; epires=Thursday, expires=Monday, 31-Jul-00 11:50:00 GMT; path=/nomeutente; x se volessimo inviare un header che rediriga il browser ad una determinata locazione, potremo
domain=.dominio.com scrivere:

Se avessimo impostato 1 anzichè 0 per il protocollo HTTPS, sarebbe apparso anche "secure" alla
fine della stringa. notate un'ultima cosa: la data è gestita di default secondo l'orario GMT: se notate, header("Location: http://www.html.it");
infatti, l'espirazione è impostata per le 11:50:00 GMT, che sono le 13:50:00 locali.
x se invece volessimo inviare un messaggio di pagina inesistente oppure un istruzione per fare in
Autenticazione con PHP modo che il browser non utilizzi la cache, potremo scrivere rispettivamente:

header("http:/1.0 404 Not Found");


Con il PHP e l'ausilio della sua funzione "header" è possibile gestire senza la necessità di utilizzare i header("Pragma: no-cache");
file .htaccess o comunque le autorizzazioni del server le pagine protette.
Basterà semplicemente inviare un header preciso al browser prima di passargli l'output per far si A questo punto, avrete certamente capito come si effettuano le redirezioni con PHP senza l'ausilio
che, all'interno di una pagina, vengano richiesti username e password per l'accesso. Intanto, copiate di file come .htaccess o equivalenti. A questo punto sta a voi migliorare gli esempi proposti per
questo codice in un file e richiamatelo via browser: implementarli con successo nelle vostre pagine Web.

$username = "pippo"; Percorso consigliato di Alberto Mucignat


$pwd = "segreta";
Esperto alberto@html.it
if(!isset($PHP_AUTH_USER)) {
Header("WWW-Authenticate: Basic realm=\"Zona protetta\"");
Header("HTTP/1.0 401 Unauthorized"); Un modulo aggiuntivo per web servers che permette di creare delle pagine web dinamiche. La guida, scritta da Alberto
echo "Impossibile eseguire l'autorizzazione\n";
exit; Mucignat ne spiega le caratteristiche teoriche e pratiche in 15 lezioni.
} else {
if (($PHP_AUTH_USER == $username) && ($PHP_AUTH_PW == $pwd)) {
echo "Autorizzazione riuscita per $username.";
} else { echo "Autorizzazione fallita.";}
}
1. Cos'è Php e come funziona
In questo modo, impostiamo "pippo" come username e "segreta" come password: se i dati inseriti

HTML.IT – Guide PHP 101 HTML.IT – Guide PHP 102


Breve introduzione sui concetti principali di PHP

11. Una prima ricerca


2. Come funziona?
Compiere una prima ricerca all'interno di un database
Per funzionare, Php necessita di un suo motore di scripting (script engine) che esegue le
parti in codice prima che il web server invii la pagina all'utente
12. Un sito di annunci

3. Alcune particolarità Costruzione di un database di annunci e alla sua consultazione tramite pagine web

Alcuni aspetti particolari del funzionamento di PHP


13. Inserimento di un annuncio

4. Primi esempi Primo annuncio all'interno del database

Realizzazione di un file prova.php3


14. Mostrare gli annunci

5. Accodare un file Il codice necessario a mostrare gli annunci nel database

Può essere utile a tutti webmaster inserire alla fine di ogni file del proprio sito una riga di
informazioni sull'autore 15. Ricerca di un annuncio

Il codice necessario per ricercare gli annunci nel database


6. Contatore in ogni pagina

Per inserire un contatore nelle nostre pagine che venga modificato ad ogni visualizzazione Cos'è Php e come funziona

7. Caricare un'immagine Php è un modulo aggiuntivo per web servers che permette di creare delle pagine web dinamiche.
In pratica, una pagina in Php è composta sia da tag html, sia da parti in codice di programmazione
Visualizzare ad ogni apertura di una pagina un'immagine diversa Php. Ogni porzione di codice, limitato entro i tag "<?php" e "?>", viene eseguito prima di essere
inviato all'utente che ne fa richiesta.
Il funzionamento è praticamente lo stesso delle pagine Asp.
8. Spedire mail Un esempio di pagina Php è il seguente:

Con Php è possibile spedire mail da una pagina web <html>


<body>
<!--- Parte di comandi Html --->

9. Come gestire un sito <? #parte di codice Php ?>


<!--- Altri comandi Html --->
Alcune importanti applicazioni di Php permettono ai webmaster di gestire i loro siti in </body>
maniera efficiente e senza troppo lavoro </html>

Come funziona?
10. Php e database

L'impiego più importante di Php si ottiene nel campo delle interrogazioni di database Per funzionare, Php necessita di un suo motore di scripting (script engine) che esegue le parti in
presenti sul server codice prima che il web server invii la pagina all'utente. Attualmente esiste la versione 3.0 del
motore Php (funzionante praticamente su tutti i web server) disponibile presso il sito www.php.net.

HTML.IT – Guide PHP 103 HTML.IT – Guide PHP 104


Quando un utente richiede una pagina Php, il motore esegue il codice contenuto all'interno di quella <HTML>
<BODY>
pagina. Durante l'esecuzione, il codice produce delle informazioni in formato html. Infine il file (in
completo formato html) viene inviato all'utente. <? echo("Ultima modifica: ".date("d/m/Y",filemtime($PATH_TRANSLATED))); ?>

Se provate a visualizzare il sorgente di una pagina in Php potete notare che non vi compare nessuna </BODY>
</HTML>
riga di codice Php. Il vantaggio è proprio questo: nessun utente esterno, tranne il webmaster, può
accedere al codice e modificarlo. Per l'utente esterno, la pagina in Php è esattamente uguale a una
qualsiasi pagina in Html. Esso visualizza la data di ultima modifica del vostro file. Può essere utile nella costruzione di siti
Un consiglio per comprendere al meglio il presente tutorial ed avere poi uno strumento efficace per web in quanto spesso ci si dimentica, dopo una serie di aggiornamenti, di cambiare la data. In
programmare con esattezza i propri script è quello di scaricarsi il Manuale Php 3.0 dal sito questo modo, la pagina visualizzerà correttamente la data, senza doversene preoccupare troppo.
www.php.net.
Accodare un file
Alcune particolarità

Questa sezione è dedicata ad alcuni esempi iniziali per affrontare il mondo Php.
Sono abbastanza semplici, ma possono essere combinati tra loro e con un po' di fantasia si possono
x I tag che indicano la presenza di codice Php sono "<?php" e "?>", ma è possibile configurare Php ottenere dei risultati efficaci per le nostre pagine.
in modo che si accorga anche dei tags "<?" e "?>" di più semplice scrittura.
Può essere utile a tutti webmaster inserire alla fine di ogni file del proprio sito una riga di
x I commenti all'interno del codice Php devono essere compresi tra i tags "/*" e "*/". Un altro tipo informazioni sull'autore (nome, cognome, email).
di commento si ottiene mettendo il tag "#" all'inizio di una riga. La riga intera non verrà eseguita. A questo proposito ci viene in aiuto il comando INCLUDE di Php.
Inserendo il seguente codice alla fine delle vostre pagine verrà caricato automaticamente un codice
x I comandi Php per restituire del codice Html sono: PRINT("<!--- html code --->"); ECHO("<!--- html contenuto nel file /path/codice.txt:
html code --->");
<? include("/path/codice.txt"); ?>
x Il comando per la concatenazione di stringhe è il punto (.). Ad esempio, il comando
echo("Ciao"." "."Alberto")
produce la stringa il contenuto del file /path/codice.txt potrebbe essere:
"Ciao Alberto"
<hr size="1">
Pagina realizzata da <a href="mailto:stain@dei.unipd.it">Alberto Mucignat</a>
x Ogni comando puro in Php deve essere concluso con il punto e virgola (;)
Vedremo in seguito le specifiche del comando INCLUDE e del suo "simile" REQUIRE.
x Per essere eseguiti, i file devono avere estensione ".php3" (a meno che il web server non sia
configurato diversamente). Ogni file del nostro sito che contiene istruzioni Php deve avere quella
Contatore in ogni pagina
estensione.

Primi esempi
Per inserire un contatore nelle nostre pagine che venga modificato ad ogni visualizzazione,
possiamo inserire il seguente codice:
Il primo esercizio potrebbe consistere nella realizzazione di un file prova.php3 contenente il
seguente codice: <?
if (!file_exists("/path/counter.txt")):
<HTML> $file=fopen("/path/counter.txt","w");
<BODY> $num=0;
else:
<? phpinfo(); ?> $file=fopen("/path/counter.txt","r+");
$num=fgets($file,20);
</BODY> endif;
</HTML> $num++;
print("Visitors: ".$num);
fputs($file,$num);
fclose($file);
Questo file produce una schermata in cui vengono visualizzati i parametri di configurazione di Php ?>
nel server in cui viene eseguito il codice. Può essere utile per verificare la presenza di Php in un
server o per conoscere il valore delle variabili di sistema (per programmatori esperti). Il contatore non tiene conto delle visite ricevute dallo stesso utente nel corso della stessa sessione.
Per fare ciò bisogna imparare a configurare i COOKIES o aspettare la nuova versione Php 4 per
Un altro esempio potrebbe essere il seguente. avere tutte queste funzionalità a disposizione con le varibili SESSION.
HTML.IT – Guide PHP 105 HTML.IT – Guide PHP 106
Esistono anche delle librerie che hanno implementato le funzionalità collegate alle variabili di
sessione. Come gestire un sito

Caricare un'immagine
Alcune importanti applicazioni di Php permettono ai webmaster di gestire i loro siti in maniera
efficiente e senza troppo lavoro.
Può accadere di dover visualizzare, ad ogni apertura di una pagina, un'immagine diversa. Un Un problema nei siti composti da molte pagine è il fatto di dover fare piccoli cambiamenti grafici
semplice codice per gestire dinamicamente questa esigenza può essere il seguente: con corrispondente aggiornamento di tutti i files e una mole di lavoro notevole da parte del
webmaster.
A questo vengono in aiuto i programmi tipo Dreamweaver che permettono la creazione dei
<?
$num=rand(1,10);
cosiddetti templates. I templates sono dei file "tipo" che rappresentano la struttura portante (e
print("<img src=\"images/img".$num.".gif\">"); comune) di tutti i file di un sito. I templates permettono di gestire il design di un sito semplicemente
?>
definendo tutti gli attributi comuni alle pagine di un sito.
In Php è utile usare sistemi di questo tipo, facilitati dal linguaggio di programmazione.
Ovviamente bisogna nominare le immagini come images/img1.gif, images/img2.gif, ecc.
Un'altra possibilità è visualizzare un'immagine diversa a seconda del giorno della settimana in cui il Due istruzioni importanti per questi sistemi sono la INCLUDE e la REQUIRE.
visitatore richiede la pagina. Le pagine devono essere chiamate images/Mon.gif, images/Tue.gif, L'istruzione INCLUDE (già vista in precedenza), quando inserita all'interno di pagine web,
ecc, e il codice potrebbe essere: permette di includere un determinato file.
L'istruzione REQUIRE differisce solamente per il fatto che, se viene inserita in un ciclo, include il
file un'unica volta prima di restituire la pagina all'utente.
<?
$img=date("D"); Questo ci permette, ad esempio, di gestire dei banner pubblicitari. Il metodo è semplice.
print("<img src=\"images/".$img.".gif\">");
?>
Inizialmente si deve fare in modo che tutte le pagine del nostro sito abbiano al loro interno la
seguente riga:
Potete sbizzarrirvi in questo genere di giochetti a seconda della vostra fantasia.
<? if (file_exists("/path/banner.inc")): require("/path/banner.inc"); endif; ?>
Spedire mail
nel file banner.inc può essere contenuto un codice Php che restituisce un'immagine con un link
esterno e nel contempo effettua altre operazioni utili (nel caso di banner pubblicitari: selezione
Con Php è possibile spedire mail da una pagina web. random, conteggio delle impression, ecc).
Inizialmente si deve creare una pagina che chiameremo "master", completa di una FORM per Ma torniamo ai templates e cerchiamo di strutturare tutti i file del sito in modo che siano utilizzabili
l'invio dei dati, e di una pagina "slave" che riceve i dati e invia la mail. da Php:
Per quanto riguarda la sintassi di una form, vi rimando a un qualsiasi tutorial html.
La pagina "master" deve avere al suo interno un codice di questo tipo:
<? include("/path/header.inc"); ?>
<!--- Html Code --->
<FORM ACTION="send.php3" METHOD="POST">
Nome e Cognome:<BR> <? include("/path/footer.inc"); ?>
<INPUT TYPE="text" NAME="name" SIZE="20" MAXLENGTH="30"><BR>
Email:<BR>
<INPUT TYPE="text" NAME="email" SIZE="20" MAXLENGTH="30"><BR>
Titolo:<BR> In questo modo basta creare i file header.inc e footer.inc e il gioco è fatto.Il file header potrebbe
<INPUT TYPE="text" NAME="subject" SIZE="20" MAXLENGTH="30"><BR>
Testo della mail:<BR>
contenere le seguenti righe:
<INPUT TYPE="textarea" NAME="text" ROWS="10" COLS="60" MAXLENGTH="200"><BR>
<INPUT TYPE="submit" VALUE="INVIA">
</FORM>
<HTML>
<HEAD>
<TITLE>My Site</TITLE>
Nel file send.php3 (il nostro file "slave") sarà contenuto il seguente codice Php: <META NAME="author" CONTENT="Alberto Mucignat">
<META NAME="description" CONTENT="Questo è il mio sito gestito in Php">
</HEAD>

<? <BODY BGCOLOR="RED">


if (isset($email)): <CENTER><B><H2>My Site</H2></B></CENTER>
# l'indirizzo email a cui inviare la mail <HR SIZE="1">
$target="info@sito.it";
mail($target,$subject,"Nome: ".$nome."\nTitolo: ".$subject."\n\n".$text);
endif;
?>

HTML.IT – Guide PHP 107 HTML.IT – Guide PHP 108


server.
E il file footer.inc potrebbe contenere le righe: Php consente al programmatore e di interfacciarsi con numerosi database tra i più importanti nel
mondo della programmazione:

<CENTER> x PostgreSQL
<HR SIZE="1">
Sito realizzato da <A HREF="mailto:stain@dei.unipd.it>Alberto Mucignat</A> x MySql
</CENTER>
</BODY> x Oracle
</HTML> x Adabas
x filePro
In questo modo ogni aggiornamento alla grafica del nostro sito è facile e immediato. Basta infatti x ODBC
andare a modificare i files header.inc e footer.inc per fare sì che tutte le pagine del sito vengano
aggiornate automaticamente. più alcuni altri meno noti.
In particolare, la connessione ODBC permette di interfacciarsi con database tipo Access.
Un'altra utilità nella gestione dei siti è la realizzazione delle cosiddette "restricted areas", ovvero L'utilizzo dei comandi per la connessione ai database prescinde dalla conoscenza dei database
aree riservate a cui serve una password per accedere. stessi. Il linguaggio SQL è richiesto per formulare le query, come pure la conoscenza del significato
Per fare ciò basta creare un file index.php nella directory del sito protetta e inserire la form: di indici, chiavi, relazioni, ecc.
In buona sostanza, un webmaster che intende organizzare un sistema che preveda la consultazione
di un database via web, nella maggioranza dei casi deve conoscere approfonditamente la struttura
<FORM ACTION="main.php3" METHOD="post">
Inserire password:<BR> stessa del database, nonchè il significato dei dati contenuti.
<INPUT TYPE="password" NAME="pwd" SIZE="20" MAXLENGTH="30"><BR>
<INPUT TYPE="submit" VALUE="ENTRA">
</FORM> Per quanto riguarda SQL, il linguaggio standard di interrogazione sui database, esistono molti
tutorial e manuali in rete. Mi limiterò a dire che per interrogazione o query si intende una serie di
Il file main.php3 è il file che fa la verifica della password e contiene il codice: comandi che un qualsiasi database esegue restituendo una serie di tuple (in generale righe o parti di
righe di una o più tabelle del database).
In questo tutorial consideriamo operazioni su un database di tipo MySQL e diamo per scontata la
<? if ((isset($pwd)) AND ($pwd=="pass128")): ?> conoscenza del database stesso. Al lettore attento non risulterà difficile trasformare le operazioni
<!--- Restricted area - Html code ---> spiegate per ricondurle al suo database preferito.
<? else: ?>
In pratica le operazioni Php sui database potrebbero suddividersi in tre livelli:
<!--- Error message --->
<? endif; ?> x apertura/chiusura connessione
x invio interrogazioni SQL
Per maggior sicurezza, la password può essere memorizzata in un file e il codice diventa: x lettura risultati di una query

Le operazioni di apertura/chiusura di una connessione a un database servono ad aprire/chiudere un


<? if ((isset($pwd)) AND ($pwd==include("passwd.txt")): ?>
collegamento con il database prescelto, al fine di poter fare delle operazioni di lettura/scrittura e
trasmettere i dati in formato html.
Nel caso di sistemi unix/linux è possibile criptare la password con il comando CRIPT e in tal caso, Per aprire/chiudere una connessione in MySql sono disponibili i comandi:
se il file passwd.txt contiene la password precedentemente criptata, la sitassi diventa:

mysql_connect(host,login,password)
<? if ((isset($pwd)) AND (crypt($pwd)==include("passwd.txt")): ?> mysql_close()

Questi sono solo alcuni degli accorgimenti che si possono usare nella costruzione e gestione dei siti Per inviare interrogazioni si può usare il comando:
web. Il consiglio è di non fermarsi alle cose viste, ma di stimolare la fantasia ricercando nuove
strategie e soluzioni.
mysql_db_query(database,query,ID_database)

Php e database
Per leggere i risultati si usano dei comandi che vedremo in seguito.

L'impiego più importante di Php si ottiene nel campo delle interrogazioni di database presenti sul Una prima ricerca

HTML.IT – Guide PHP 109 HTML.IT – Guide PHP 110


che la ricerca.
La tabella Annunci che memorizza gli annunci è stata già descritta e contiene i campi:
Per compiere la nostra prima ricerca nel database poniamo di conoscere l'esistenza, la
configurazione e il significato del contenuto di una tabella chiamata Annunci. x ID [chiave primaria]
La tabella Annunci contiene i campi: x Nome [nome dell'autore dell'annuncio]
x Email [email]
x ID [chiave primaria] x Testo [testo dell'annuncio]
x Nome [nome dell'autore dell'annuncio]
x Email [email] Passiamo alla pratica ricordandoci che lo strumento necessario per inviare dati da un file html/php3
x Testo [testo dell'annuncio] ad un altro è la form, come descritto nelle lezioni precedenti.

Una ricerca all'interno della tabella potrebbe essere fatta mediante il codice seguente: Per fare funzionare il tutto creiamo dei file nel seguente modo:

<? x show.php3 [mostra gli annunci presenti]


$db=mysql_connect("localhost","","") or die("Errore durante la connessione a MySql");
$result=mysql_db_query("database_annunci","SELECT * FROM Annunci",$db); x insert.php3 [inserisce un annuncio]
mysql_close();
?> x search.php3 [cerca una o più parole nel database]

Questi comandi permettono di memorizzare all'interno della variabile $result tutti gli annunci Inserimento di un annuncio
presenti nella tabella Annunci.
Per scriverli occorre prima fare l'operazione:
Supponiamo di ricevere dei dati da una form nelle variabili $nome,$email,$testo. Per inserire un
$row=mysql_fetch_row($result); nuovo annuncio basta fare le seguenti operazioni:

e, successivamente, la prima riga del risultato sarà disponibile nella variabile array $row.Per
<?
scrivere il risultato sarà necessaria una riga tipo: # dati da modificare a seconda del database
$host="localhost";
$user="";
print($row[1]."/".$row[2]."/".$row[3]."/".$row[4]."/"); $pass="";

$db=mysql_connect($host,$user,$pass) or die ("Errore durante la connessione al database");


Per conoscere il numero di righe presenti nel risultato di una query basta usare il comando: $sql="INSERT INTO Annunci (Nome,Email,Testo) VALUES('".$nome."','".$email."','".$testo."')";
mysql_db_query("db_annunci",$sql,$db);
mysql_close();
$num_rows=mysql_num_rows($result); ?>

Un'altra operazione molto utile è quella che restituisce il numero di campi presenti nel set di In questo caso il database inserisce automaticamente una chiave unica che contraddistingue
risultati della query appena compiuta: l'annuncio nel campo ID della tabella Annunci.
Ovviamente si possono anche fare delle operazioni di controllo sulla validità dell'indirizzo email o
$num=mysql_num_fields($result); per verificare che alcuni campi non siano nulli.

A questo punto siamo pronti per formulare query più complesse. Ad esempio, dopo aver creato una Mostrare gli annunci
form che restituisca nella variabile $stringa una parola su cui fare la ricerca, si può scrivere:

$sql="SELECT * FROM Annunci WHERE Testo LIKE '%".$stringa."%'"


$result=mysql_db_query("db_annunci",$sql,$db); Per mostrare gli annunci presenti nel database basta inserire il seguente codice:

$result sarà composto da tutti gli annunci che contengono la parola memorizzata in $stringa.
<?
# dati da modificare a seconda del database
Un sito di annunci $host="localhost";
$user="";
$pass="";

$db=mysql_connect($host,$user,$pass) or die ("Errore durante la connessione al database");


$sql="SELECT * FROM Annunci";
Alla fine dell'ultima lezione accennavamo alla costruzione di un database di annunci e alla sua $result=mysql_db_query("db_annunci",$sql,$db);
consultazione tramite pagine web. while ($row=mysql_fetch_array($result)) {
print("<B>Nome</B>: <A HREF=\"".$row["Email"]."\">".$row["Nome"]."</A><BR>");
Vediamo ora di affrontare meglio il problema e di costruire un sito che permetta sia l'inserimento print("<B>Testo dell'annuncio</B>:<BR>");

HTML.IT – Guide PHP 111 HTML.IT – Guide PHP 112


print(htmlentities($row["Testo"])."<BR>"); conoscienza sul server HTTP Apache
print("<HR SIZE=\"1\">");
}
mysql_close();
?>
2. Presentazione del software
La funzione htmlentities() permette di "tradurre" le lettere accentate e gli altri caratteri particolari
Le funzioni base del webserver Apache
nella loro codifica html, in modo da poter venire visualizzate correttamente dai vari browser.

Ricerca di un annuncio
3. Novità per la versione 1.3

Le nuove funzionalità introdotte rispetto alla versione 1.2


Per la ricerca di un annuncio particolare, pensiamo di ricevere una stringa $str da una form, in modo
che $str contenga una serie di parole da ricercare separate da spazi.
Il seguente codice permette di effettuare la ricerca e visualizzare i risultati:
4. Installazione e configurazione

<? Risorse per l'installazione e la configurazione di Apache


# dati da modificare a seconda del database
$host="localhost";
$user="";
$pass="";
5. Istruzioni preliminari
$db=mysql_connect($host,$user,$pass) or die ("Errore durante la connessione al database");
$sql="SELECT * FROM Annunci ";
$where=""; In questo testo vedremo alcuni parametri per la configurazione ottimale del nostro
$words=explode(" ",$str);
$j=0;
webserver Apache
while (isset($words[$j])) {
$where=$where."Testo LIKE '%".$words[$j]."%'";
if (isset($words[$j+1])):
$where=$where." OR ";
endif;
6. Porte
$j++;
}
$result=mysql_db_query("db_annunci",$sql.$where,$db); Quali porte del server aprire e quali lasciare chiuse
while ($row=mysql_fetch_array($result)) {
print("<B>Nome</B>: <A HREF=\"".$row["Email"]."\">".$row["Nome"]."</A><BR>");
print("<B>Testo dell'annuncio</B>:<BR>");
print(htmlentities($row["Testo"])."<BR>");
print("<HR SIZE=\"1\">"); 7. Utenti
}
mysql_close();
?> Assegnare gli utenti predefiniti sul server

Ovviamente le varianti sono molteplici e ognuno può sbizzarrirsi come meglio crede.
Volendo dare una traccia da seguire per creare un sistema del genere crediamo di aver detto 8. Directory
abbastanza.Vorremmo solo far presente che il passaggio del codice da un database all'altro richiede
un'attenta traduzione da parte del programmatore perchè è possibile che le operazioni richiedano un Come configurare le directory principali del server
numero diverso di operatori a seconda del database.

9. Avvio, riavvio e stop di Apache


Percorso consigliato di Edoardo Valsesia
Esperto edoardo@html.it
Vedremo in questa sede come avviare, riavviare e fermare il processo principale di Apache

Guida rivolta ad utenti professionisti che hanno la possibilità di gestire il proprio server.
10. Avvio su Unix

I due metodi per avviare Apache sotto Linux


1. Introduzione ad Apache
11. Riavvio e stop su Unix
Le pagine qui proposte servono a tutti coloro che intendano approfondire la loro

HTML.IT – Guide PHP 113 HTML.IT – Guide PHP 114


Come riavviare o fermare Apache sotto Unix
Come impostare in modo corretto i file di log

12. Avvio, riavvio e stop su NT


22. Tipologia dei file di log
Come far partire, riavviare o fermare Apache sotto NT
Quanti e quali tipi sono i file di log

13. Apache per Windows


23. Leggere i log
Vedremo in questa breve guida gli aspetti salienti della distribuzione di Apache per
piattaforma Windows, focalizzandoci soprattutto sul sistema Nt. Il modo più corretto per leggere i file di log e risolvere alcuni problemi

14. Documentazione 24. ASP ... ma con Apache

Dove trovare la documentazione ufficiale su Apache Con questo breve testo analizzaremo qualcosa che a molti sembrerà impensabile: vedremo
come utilizzare documenti ASP con Apache.

15. Avvertenze
25. Come fare?
Cosa c'è da sapere di Apache su Windows
Risorse utilizzate per far girare ASP su Apache

16. Problemi conosciuti


26. Non è tutto oro quello che luccica.
I maggiori problemi noti di Apache per Windows
Problemi derivanti dall'utilizzo del modulo ASP su Apache

17. Messaggi di errore


27. APACHE: accesso ristretto al server
Vedremo in queste pagine come personalizzare i messaggi d'errore di Apache
La presenza di documenti riservati, aree ristrette ai soli membri, zone a pagamento ... tutti
questi possono essere buoni motivi per vietare ad occhi indiscreti la visione di determinate
18. Impostazione pagine.

Come configurare i messaggi di errore


28. Configurare Apache

19. Esempi Le modifiche necessarie da fare al webserver

Esempi pratici su pagine di errore gestite da Apache


29. Utility per la creazione degli utenti

20. I file di log Come creare i file utenti all'interno del server

I file di log sono dei semplici file di testo nei quali Apache scriverà, in generale, gli accessi e
gli errori riscontrati. Vediamo come impostarne la 30. APACHE: IIS vs. Apache: i benchmark

HTML.it mette a confronto le prove comparative di Linux ed NT di siti specializzati e


21. Impostazione dei file di log riviste. Cio' che ne esce è un quadro contradditorio ma interessante.

HTML.IT – Guide PHP 115 HTML.IT – Guide PHP 116


Cosa sono e come funzionano gli IP virtualhost
31. Unix o NT? Dipende!

Le principali differenze in base a cui scegliere 41. Name-based virtual hosts

Cosa sono e come funzionano gli Name-based virtual hosts


32. Il primo benchmark

Eseguire il primo benchmark 42. Prima di chiudere

Ultimi passi per la configurazione


33. Il secondo benchmark

Eseguire il secondo benchmark 43. APACHE: un setup sicuro

Le operazioni più importanti da non tralasciare quando si configura un server web, nella
34. Conclusioni fattispecie, ovviamente, Apache.

Conclusione e considerazioni
44. 5 cose da tenere sotto controllo

35. APACHE: il protocollo HTTPS Consigli da tenere a mente

Il rapporto fra il webserver Apache ed il protocollo HTTPS, ossia il protocollo HTTP con il
supporto SSL. Vedremo quindi dove reperire i sorgenti, come compilarli, come creare dei Introduzione ad Apache
certificati e come configurare al meglio il server per abilitare il support

Le pagine qui proposte servono a tutti coloro che intendano approfondire la loro conoscienza sul
36. Parte prima: il codice sorgente server HTTP Apache; in congiunzione con la guida all'installazione presentata nell guida ai CGI,
queste pagine vogliono essere una panoramica quanto più dettagliata possibile su come utilizzare al
Dove reperire il codice sorgente ufficiale meglio questo webserver sulle nostre macchine.

Presentazione del software


37. Il primo certificato

Come creare il primo certificato Apache, il cui sviluppo (ricordiamo che il team è formato da volontari, noti come l'Apache Group) è
arrivato alla versione 1.3.12, è nato come rimpiazzo per il webserver httpd 1.3 sviluppato dal NCSA
(National Center for Supercomputing Applications), inglobandone le carrateristiche, risolvendone i
38. Il file di configurazione problemi ed implementando nuove features.
Come sopra accennato, Apache è un webserver per il protocollo HTTP, designato per poter girare
Struttura del file di configurazione come un processo standalone, senza ciò chiedere l'appoggio ad altre applicazioni o direttamente
all'utente. Per poter fare ciò, Apache, una volta che sia stato avviato, crea dei sottoprocessi
(comunemente e meglio detti "children processes") per poter gestire le richieste: questi processi,
39. APACHE: virtualhosts comunque, non potranno mai interferire con il processo maggiore, ma può succedere l'opposto:
mandando un segnale di stop a questo, anche i children saranno terminati.
Apache supporta sia i virtualhosts basati sul numero di IP sia quelli basati sul nome. Un tipico albero dei processi di Apace potrebbe essere qualcosa di simile a:
Vedremo come creare e configurare entrambi.
USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND
root 203 0.01 1.01 4952 720 ? S 17.20 0.03 /usr/sbin/apache
user 212 0.00 2.03 5012 1456 ? S 17.20 0.00 \_ /usr/sbin/apache
40. IP-Based Virtual Hosts

HTML.IT – Guide PHP 117 HTML.IT – Guide PHP 118


user 213 0.00 2.02 5008 1424 ? S 17.20 0.00 \_ /usr/sbin/apache ufficiale del progetto Apache.
user 214 0.00 0.00 4976 0 ? SW 17.20 0.00 \_ (apache)
user 216 0.00 0.00 4976 0 ? SW 17.20 0.00 \_ (apache) Per chi intenda installare o comunque approfondire le proprie conoscienze su Apache in relazione a
user 473 0.00 1.06 4976 1072 ? S 18.05 0.00 \_ /usr/sbin/apache sistemi Windows, ricordo la pagina "windows.html" presente nel manuale HTML che vi verrà
user 477 0.00 1.07 4976 1076 ? S 18.05 0.00 \_ /usr/sbin/apache
installato a supporto del server.
user 478 0.00 2.04 5012 1544 ? S 18.05 0.00 \_ /usr/sbin/apache

Istruzioni preliminari
Ricordiamo inoltre che Apache è distribuito come free software, per esplicito desiderio del team che
lo sviluppa: questi, infatti, ritengono che strumenti di questo genere debbano essere accessibili a
tutti, e che le software house debbano guadagnarci solo producendo addons o simili di valore, o In questo testo vedremo alcuni parametri per la configurazione ottimale del nostro webserver
magari personalizzati per alcune categorie di utenti. Inoltre, lasciando il software in mano di Apache, partendo dalle porte utilizzate, passando per gli utenti e chiudendo con le directory
chiunque nonchè completo di sorgenti, è possibile che costoro contribuiscano, sia tramite feedback utilizzate a vari scopi.
sia tramite vere e proprie patch, a migliorare il prodotto finale. Date le loro premesse, come dare
loro torto? Porte

Novità per la versione 1.3


Iniziamo con la porta su cui mettere in listening il webserver (non nel caso in cui esso sia chiamato
da inet): il numero specificabile per la porta varia da un range da 0 a 65535, di cui le prime 1024
Vediamo brevemente alcune tra le moltissime modifiche introdotte nella versione 1.3 rispetto alla sono riservate per determinati protocolli; la porta riservata per il protocollo http è comunque, di
1.2: default, la 80. Per chi volesse saperne di più sulle porte ed il relativo protocollo associato, maggiori
informazioni possono essere trovate nel file /etc/services (sistemi Unix). Un'altra particolarità della
x Supporto DSO (Dynamic shared objects): i moduli possono essere caricati si richiesta, in porta 80 ed in generale delle porte al di sotto della 1024 è che sono "di sistema", nel senso che i
modo da utilizzare una minore quantità di memoria. Questa caratteristica è supportata su: normali utenti non possono farne uso. Quindi, è necessario che apache sia fatto partire dall'utente
FreeBSD, OpenBSD, NetBSD, Linux, Solaris, SunOS, Digital UNIX, IRIX, HP/UX, root nel caso si utilizzi la porta 80 (che è comunque consigliato); in seguito, prima di essere pronto
UnixWare, AIX, ReliantUnix e le altre piattaforme SVR4. ad accettare le richieste, l'esecuzione di Apache sarà "spostata" all'utente definito poco oltre nel file
httpd.conf (lo vedremo in seguito): in questo modo, tutti i processi children saranno su porte il cui
x Supporto per Windows 9x/NT: le versioni precedenti non potevano infatti essere installate numero è maggiore di 1024.
su questi sistemi. Al momento, il supporto è sperimentale ma, dalle prove effettuate, si
comporta assai bene sebbene non sia ancora in grado di garantire performances pari a quelle Utenti
riscontrabili su sistemi Unix.

x Migliore gestione dei VirtualHost.


Abbiamo parlato poco sopra degli utenti con i privilegi dei quali Apache è fatto girare: la direttiva
x Miglior gestione dei proxy server. che ci interessa è "User".
Per utilizzare tale direttiva, è necessario che l'utente che ha avviato Apache SIA root. Il nome
x Migliore gestione degli script CGI. dell'utente può essere specificato come il nome a caratteri (ad esempio, nome_utente) oppure
tramite il suo ID numerico preceduto dal simbolo # (ad esempio, # 1002).
x Compatibilità con l'anno 2000 (è un po' tardi per dirlo, ma gli autori se n'erano ricordati per Questo utente non dovrebbe avere troppi provilegi sul sistema, come ad esempio la possibilità di
tempo!) leggere importanti file di sistema, lanciare eseguibili che non hanno a che fare con httpd e simili. La
cosa migliore da fare è quella di creare un nuovo utente ad hoc per l'esecuzione di Apache, visto che
Ovviamente non è tutto qui; quelle qui riportate sono le modifiche "umanamente intelleggibili", anche scegliere l'utente "nobody" può non essere la scelta migliore.
ossia quelle che un utente medio capisce senza troppi problemi. Per chi voglia approfondire Ovviamente, inoltre, è fortemente sconsigliato specificare "root" nella direttiva "User". Il perchè mi
l'argomento, consiglio la pagina "new_features_1_3.html" presente nella documentazione di sembra chiarissimo.
Apache stesso.
Assieme ad "User", inoltre, dovrete specificare anche un nome di gruppo per la direttiva "Group":
Installazione e configurazione se avete creato un nuovo utente (supponiamo "prova") per far girare Apache, potrete inserire
"prova" anche per il gruppo, a meno che abbiate la necessità di utilizzare un Group differente.

Per coloro che non l'abbiano ancora fatto, ricordo che l'argomento è stato precedentemente Directory
affrontato nella guida ai CGI nonchè in un articolo a parte per quanto riguarda l'installazione su
piattaforma Win32. Inoltre, moltissima documentazione la potete trovare nei vostri hard-disk dopo
avere installato Apache sulle vostre macchine o ancora alla pagina http://www.apache.org, sito Vediamo qui le directory che interesseranno Apache: parleremo qui sia delle directory di

HTML.IT – Guide PHP 119 HTML.IT – Guide PHP 120


configurazione sia di quelle utilizzate per contenere le pagine che daranno forma ad uno o più siti
web.
L'avvio di Apache può essere fatto in due modi: al boot della macchina oppure tramite il demone
Scorrendo il file httpd.conf, ci imbatteremo presto nella direttiva "ServerRoot": in questa directory inetd ogni volta che ci sia la richiesta di una connessione HTTP. La seconda possibilità è comunque
saranno contenuti i file di configurazione di Apache, gli errori ed i log, se non specificato poco raccomandata, in quanto è sempre meglio avere il server attivo e pronto a ricevere le richieste.
differentemente. Evitate che tale directory sia visibile dal web, piuttosto scegliete una directory Quindi ipotizzeremo qui che Apache sia avviato al boot della macchina e terminato al suo
come /etc/apache oppure /var/log/apache. Bisognerà anche fare attenzione ai permessi da dare a spegnimento: se parliamo di un server web, capirete che tra i due momenti passerà molto tempo
questa directory: i file che essa contiene, infatti, sono alquanto importanti e possono modificare (visto l'uptime di questi tipi di macchine), e quindi Apache resterà attivo per tutto il tempo durante
radicalmente il comportamento del server: evitate quindi che altri utenti al di fuori il quale la macchina è accesa e, ovviamente, connessa in rete, locale o remota che sia.
dell'amministratore possano leggere e scrivere al suo interno. Inoltre, per lo stesso discorso, fate lo
stesso anche con le directory ed i file di log. L'avvio al boot è determinato da un semplice script presente in /etc/init.d : il nome dello script è,
fantasiosamente, apache! Leggendolo, molti si potebbero spaventare: sapendo scremare tutto quanto
Passiamo poi alla direttiva "DocumentRoot": in questa directory saranno presenti i documenti è superfluo ai nostri scopi, possiamo ridurci a considerare solo le chiamate che ci interessano, senza
visualizzabili dal web, in poche parole il sito principale associato al webserver. Per essere ancora curarci di cosa effettivamente avviene per ognuna.
più chiaro, se il nome del vostro host è "www.server.it", se un utente digiterà dal browser l'indirizzo
"www.server.it" appariranno proprio le pagine presenti in "DocumentRoot". La prima è "start": come apparirà chiaro, con questa chiamata Apache viene attivato, in modo che si
crei il processo padre che sarà seguito dai processi children per gestire le chiamate. La chiamata
Poco sotto a DocumentRoot c'è la direttiva "DirectoryIndex": a cosa serve è presto detto. Provate a start è quella che viene fatta al boot della macchina e, per accertarcene, sarà sufficiente controllare
digitare nel browser l'indirizzo di un qualsiasi server e notate che non inserite alcun nome del file che, al boot, appaia una riga simile a:
che abbia estensione html, eppure il 90% dei file visibili in rete sono in html! Se questo accade, è
grazie alla direttiva "DirectoryIndex": specificando ad esempio "index.html" come valore della Starting web server: apache.
direttiva, saremo sicuri che, se in una directory è presente un file chiamato "index.html", Apache
farà in modo che non sia necessario digitare nomedirectory/index.html perchè sia visualizzato tale Se ciò avviene, possiamo stare sicuri che Apache sia già in ascolto sulla porta 80 del server ma, se
file, ma solamente nomedirectory. Facciamo un esempio: sul server "www.server.com" è presente proprio vogliamo essere pignoli, possiamo controllare tra la lista dei processi se appare (e deve
una directory chiamata, ad esempio, prova, nella quale è presente un file chiamato index.html: per apparire) anche Apache con i suoi processi children. Per la prova del nove, se l'avete già
vedere tale file, non sarà necessario digitare "www.server.com/prova/index.html" ma soltanto configurato anche sommariamente, potete digitare dal browser l'indirizzo "http://localhost" per
"www.server.com/prova". Avrete capito così perchè quando si chiama dal browser qualcosa come controllare che Apache vi risponda.
"www.html.it" non è mai necessario inserire anche "index.html": in fondo, anche www.html.it è una
directory su un server! Un'ultima cosa relativa a DirectoryIndex è il fatto di poter indicare diversi Riavvio e stop su Unix
nomi di pagine, non solo index.html: i più significativi possono essere "index.shtml", "index.htm"
ecc, l'importante è che questi siano separati da spazi.
Il riavvio ha un ruolo alquanto importante: supponete di avere una macchina impiegata a tempo
Veniamo ora alla directory UserDir, impostata di default su /home/*/public_html. Già quel pieno come server, e di effettuare alcune modifiche alla configurazione dell'Apache che gira su di
"public_html" dovrebbe avervi fatto capire qualcosa: infatti, i file presenti nella directory essa; cosa fareste per rendere attive le modifiche?
/home/nomeutente/public_html sono visualizzati quando, dopo il nome di dominio, sia specificato Coloro che, ricordando che Apache viene avviato all'avvio e pensando che sia necessario riavviare
anche ~nomeutente: se ad esempio sulla macchina "www.server.com" è presente un utente "test", la la macchina perchè le modifiche abbiano effetto si sbagliano: come esiste la chiamata "start", esiste
cui home directory è "/home/test" contenente una sottodirectory chiamata "public_html", se dal anche la chiamata "restart", solo che questa deve essere data a mano tramite il comando:
browser sarà digitato "www.server.com/~test" appariranno proprio i file presenti nella directory
"/home/test/public_html". /etc/init.d/apache restart
Ovviamente, ogni utente deve avere un account sulla macchina.
E avete capito così per sommi capi anche come funzionano le comunità virtuali su internet. Ma a cosa serve il riavvio di Apache?
Ipotizzate di gestire un server e che decidiate di includere il supporto per lo scripting PHP: dovrete
Avvio, riavvio e stop di Apache fare in modo che apache riconosca questi tipi di script, caricando l'apposito modulo (libphp3.so).
Come fare è presto detto: nel file httpd.conf, basterà decommentare la linea:

Vedremo in questa sede come avviare, riavviare e fermare il processo principale di Apache. Potrà #LoadModule php3_module /usr/lib/apache/1.3/libphp3.so
sembrare banale, ma in alcni casi è necessario far ripartire il demone dopo aver apportato delle
modifiche di configurazione in run-time. Faremo inoltre una differenziazione per quanto riguarda la Ricordiamo però che, essendo questa una modifica in run-time, Apache non potrà attuare la
descrizione del server in ambiente Unix ed in ambiente Windows. modifica a meno che sia riavviato. E la chiamata restart serve proprio a questo: se dovessimo
riavviare il server completamente (senza dubbio anche questa soluzione funzionerebbe),
Avvio su Unix rischieremmo un downtime del server troppo lungo: non stiamo parlando solamente di Apache, ma

HTML.IT – Guide PHP 121 HTML.IT – Guide PHP 122


di tutte le funzioni a cui il server è preposto: servizi FTP, POP, SMTP ecc.
Con la chiamata restart, invece, andremo a riavviare solamente Apache, limitando il downtime al apache -k restart
solo server HTTP, e tra l'altro il downtime risulterà molto più breve di un reboot della macchina,
sull'ordine di una decina di secondi. oppure:
Capirete quindi l'utilità della chiamata restart.
apache -k shutdown
L'ultima chiamata è stop: sarà senza dubbio chiaro che tramite stop fermeremo Apache del tutto.
La chiamata di stop può essere fatta in due modi: il primo è in automatico, allo spegnimento della Entrambe sono altamente preferibili ad un brutale "Ctrl+c", che chiuderebbe Apache invece di
macchina, quando cioè init manderà un SIGTERM a tutti i procesi attivi; per Apache, dovremmo arrestarlo, con tutte le conseguenze del caso.
veder comparire qualcosa del tipo:
Apache per Windows
Stopping web server: apache.

Se per qualche motivo abbiate bisogno di fermare apache a mano, ad esempio in caso di problemi Vedremo in questa breve guida gli aspetti salienti della distribuzione di Apache per piattaforma
non risolvibili all'istante, oppure di upgrade del pacchetto stesso (magari con un altro server in Windows, focalizzandoci soprattutto sul sistema Nt.
clustering per tenere attive le richieste!), la procedura sarà sempre la solita: basterà lanciare:
Documentazione
/etc/init.d/apache stop

e sarete sicuri che apache dopo pochi istanti smetterà di girare. Come avviene per i sistemi Unix, anche una normale installazione sotto Windows comprende una
directory nella quale è presente una ricca documentazione per il webserver; questa è, solitamente,
Avvio, riavvio e stop su NT ./htdocs/manual, sottodirectory della directory principale definita durante l'installazione. Tutto il
manuale è in formato HTML, ed è a grandi linee l'equivalente del manuale online leggibile
all'indirizzo www.apache.org. In questo sito, è inoltre possibile leggere delle note specifiche alla
Per questa breve sezione ci baseremo fortemente su NT, visto che far girare un webserver su un distribuzione Windows alla pagina http://www.apache.org/docs/windows.html.
sistema win9x è impresa ardua, mancando a questo molte delle caratteristiche proprie di NT.
Avvertenze
I modi per avviare Apache sono due:

x il primo è come servizio (solo per WinNT): questo è il metodo migliore per assicurarci che Essendo Apache un webserver sviluppato su piattaforma Unix, ed essendo la versione per Windows
Apache venga avviato al boot della macchina e continui ad essere attivo anche in caso di un porting, apparirà chiaro che la versione di Apache per Windows non è completamente
logoff; ottimizzata per offrire le migliori performances, come avviene invece per la versione Unix. Per dire
x da una console, peraltro unica opzione con Win9x. ciò, l'Apache Group si basa su prove comparative del software su differenti piattaforme.
Il risultato del lavoro di porting, come loro stessi dicono, è un "ottimo codice ancora in beta", visto
Per avviare Apache come un servizio, è prima becessario che questo sia effettivamente installato che il funzionamento è garantito per differenti gradi di utenza ma non è ancora al livello raggiunto
come un servizio sula macchina: dal menu d'avvio, scegliete l'opzione "Install Apache as Service"; sulle piattaforme per le quali Apache è stato originariamente pensato. Quindi funzionamento e
fatto questo, apache potrà essere avviato aprendo la finestra dei servizi (dal pannello di controllo), performances garantite, anche se non ai massimi livelli.
scegliendo Apache e successivamente su "start". Nel caso si volesse fermarlo, ovviamente, basterà
cliccare su "stop". Problemi conosciuti

In alternativa, Apache può essere avviato dalla linea di comando tramite i comandi:
Vediamo ora una rapida carrellata dei maggiori problemi (noti) di Apache utilizzato sotto Windows.
NET START APACHE
NET STOP APACHE x La direttiva "User" non è ancora sopportata (questa direttiva, insieme a "Group", specifica
l'utente che fa partire il servizio httpd).
rispettivamente per avviarlo e fermarlo. x Nel caso di server carico di richieste, quando un processo children esce, qualunque richiesta
fatta a quel processo che non sia stata precedentemente accettata non viene eseguita.
Per avviare invece Apache da console, e non come un servizio, basterà cliccare l'opzione "Apache x Le password, nel file htpasswd, sono conservate in un file di testo e non crittate, mancando
Server" dal menu d'avvio: verrà quindi aperta una finestra dos che restarà aperta durante tutto il in Windows una funziona crypt().
funzionamento del webserver.
Per il restart o lo stop, sarà sufficiente aprire un'altra finestra e digitare, rispettivamente:

HTML.IT – Guide PHP 123 HTML.IT – Guide PHP 124


x Il "suexec" non funziona; il suexec è la funzione che permette ad Apache di eseguire script E' consigiato non abusare troppo delle redirezioni, soprattutto di quelle esterne: a molti potrebbe
CGI e SSI con un UID (User ID) differente dall'ID dell'utente sotto i permessi del quale dare fastidio trovarsi inspiegabilmente in un sito differente dal vostro per motivi che non si riescono
Apache gira. a spiegare.
x La direttiva "IdentityCheck" non funziona; tale direttiva permette il logging nel file
access.log dei nomi degli utenti remoti per ogni richiesta. Esempi

Messaggi di errore Vediamo ora qualche esempio per chiarire le cose:

1. ErrorDocument 500 "Lo script richiesto non ha potuto essere eseguito per problemi interni.
Vedremo in queste pagine come personalizzare i messaggi d'errore di Apache. I responsi
personalizzati del webserver possono servire ai webmaster per far meglio capire agli utenti ciò che In questo caso, in presenza di un "Error 500" avverte il visitatore che lo script chiamato dal
succede quando il loro browser esce con un messaggio d'errore in seguito ad una richiesta suo browser ha avuto dei problemi nell'esecuzione e l'output non può essere visualizzato.
impossibile da soddisfare per i più svariati motivi (errori nell'esecuzione di script, richiesta id Questo è un tipico esempio di messaggio d'errore in forma semplicemente testuale.
pagine inesistenti ecc.). I risultati della peronsonalizzazione possono essere fondamentalmente di
due tipi: semplici messaggi di testo che spiegano sommariamente l'accaduto e redirezioni verso 2. ErrorDocument 500 http://www.altro_server/cgi-bin/script.cgi
URL interne o esterne al nostro host.
In questo secondo caso ci troviamo di fronte ad una redirezione esterna, che porterà il
Impostazione visitatore (in maniera totalmente trasparente, a parte l'indirizzo nel browser) ad un host
esterno dove verrà eseguito lo stesso script che questi avrebbe voluto veder eseguito
sull'host originario. Questo esempio può essere utile per dimostrare come può essere fatto un
Per impostare Apache in modo che riesca a produrre dei messaggi d'errore personalizzati bisognerà uso intelligiente delle redirezioni esterne: sarebbe buona norma, però, controllare (a livello
andare ad agire sul file srm.conf nella rootdir del webserver; in esso leggeremo infatti qualcosa del di codice dello script CGI) l'URL dalla quale proviene il visitatore e, nel caso questa
tipo: combaci con quella dell'host originario (quello in cui egli ha tentato di eseguire lo script)
mandare in output un messaggio che lo avverta di cosa è avvenuto e del perchè la sua
# Customizable error response (Apache style) richiesta è stata spostata su un diverso host. Questioni di cortesia verso gli utenti smarriti.
# these come in three flavors
#
# 1) plain text 3. ErrorDocument 404 /missing.html
#ErrorDocument 500 "The server made a boo boo.
# n.b. the (") marks it as text, it does not get output
# Se preparate una pagina chiamata "missing.html", per ogni errore 404 (Url not found) verrà
# 2) local redirects
#ErrorDocument 404 /missing.html visualizzata questa pagina, dove potrete personalizzare nel modo che vi sembra più
# to redirect to local url /missing.html
#ErrorDocument 404 /cgi-bin/missing_handler.pl opportuno. E' chiaro che siamo anche qui di fronte ad una redirezione interna. E' da notare,
# n.b. can redirect to a script or a document using inoltre, che è possibile redirigere il visitatore a qualsiasi tipo di pagina, sia un plain text che
# server-side-includes.
# in html, sia contenete uno script che contenente degli includes: se la pagina predefinita
# 3) external redirects
#ErrorDocument 402 http://some.other_server.com/subscription_info.html
(missing.html) è corretamente scritta, non ci sarà alcun problema per il server ad
interpretarla in quanto essa è vista come una semplice pagina da inviare al browser
dell'utente.
La sintassi base per i messaggi d'errore personalizzati è quindi:

ErrorDocument XXX azione


I file di log
dove "ErrorDocument" è la direttiva, XXX è un numero di tre cifre corrispondente al codice
d'errore del server (ad esempio 404, 500 ecc.) e "azione" è quello che il server deve fare in caso si
riscontrino questi errori. I file di log sono dei semplici file di testo nei quali Apache scriverà, in generale, gli accessi e gli
errori riscontrati.
Soffermiamoci su "azione" prima di vedere alcuni esempi: questa può essere: Per un controllo completo sul server, e magari per debuggare script o simili, è utile saper leggere
questi file.
x del semplice testo da visualizzare, preceduto dallle virgolette (") ma non dalle stesse chiuso; Vediamo come impostarne la "profondità" affinchè questi importantissimi file sappiano darci le
queste, inoltre, non verranno visualizzate nel messaggio d'errore (primo caso riportato dal informazioni necessarie a risolvere un deteminato range di problemi riscontrabili durante l'uso.
file srm.conf);
x un'URL locale (secondo caso riportato); Impostazione dei file di log
x un'URL esterna a cui redirigere il visitatore (terzo caso).

HTML.IT – Guide PHP 125 HTML.IT – Guide PHP 126


x alert: bisogna provvedere immediatamente;
Prima di tutto, è necessario istruire Apache sulla locazione dove conservare i file di log. Una buona x emerg: emergenze, il sistema è inutilizzabile.
idea è quella di creare una sottodirectory di /var/log chiamata "apache", nella quale esso potrà
scrivere quanto necessario. Le possibilità sopraelencate sono riportate in ordine di importanza crescente: quindi un LogLevel
Ma come indirizzare i log di apache in tale directory? Ancora una volta, ci viene incontro il file impostato su "debug" darà molte meno informazioni che non settato su "emerg". Inolte, se scegliete
httpd.conf, vero fulcro di Apache. un livello di verbosity elevato, anche i livelli inferiori saranno in esso inclusi: ad esempio,
scegliendo il livello "crit", anche i messaggi normalmente riportati in "debug", "info", "notice",
Scorriamo il file fino a giungere alla riga warn" ed "error" saranno riportati nel file di log.
Sta a voi decidere il livello di importanza dei mesaggi di log, sebbene una scelta abbastanza
# ErrorLog: The location of the error log file standard potrebbe essere "error" oppure "crit".

Come essa stessa specifica, la locazione sotto indicata è quella in cui Apache terrà i suoi logs; nelle Scorrendo di qualche riga il file, noterete anche la direttiva "LogFormat", che specifica i formati dei
ipotesi fatte sopra, la specificazione della directory deve essere fatta come: file.
Vediamo quali possono essere i più significativi:
ErrorLog /var/log/apache/error.log
%b --> Byte inviati, esclusi gli headers HTTP;
in modo da essere sicuri che il log degli errori sia proprio all'interno della directory /var/log/apache
con il nome (arbitrario) di error.log %f --> Il Filename
%{VAR}e --> Il contenuto della variabile d'ambiente {VAR}
Oltre che agli errori, ci interesseremo anche degli accessi, loggato nel file access.log. Qui valgono %h --> L'host remoto
tutte le considerazioni fatte sopra: la directory sarà la stessa (/var/log/apache) ma il file si chiamerà %a --> L'indirizzo IP remoto
access.log. Per specificarlo, basterà avere una riga simile a: %l --> Il logname remoto, se specificato
%p --> La porta dalla quale il server esegue la richiesta
CustomLog /var/log/apache/access.log %P --> L'ID del processo che esegue la richiesta
%r --> La prima riga della richiesta
Se non l'avete già fatto, avviate Apache, giocateci un po' ed andate a vedere i file appena creati: se %s --> Lo stato della richiesta
non avete sbagliato niente, in /var/log/apache avrete due nuovi file che vedremo in seguito come %t --> L'orario delle richiesta
leggere. %T --> Il tempo in secondi per eseguire la richiesta
%u --> Il nome dell'utente remoto
Tipologia dei file di log %U --> L'url richiesta

Una riga standard per determinare i tipi di log potrebbe comunque essere:
Oltre a impostare quali debbano essere i file di log di Apache, possiamo anche determinare come
devono essere composti, che informazioni devono contenere, quanto completi devono essere ecc. "%h %l %u %t \"%r\" %s %b";
Vediamo come.
Leggere i log
Continuando a scorrere il file httpd.conf, noteremo una serie di righe (sotto a ErrorLog) che iniziano
con
Saper leggere i log, specialmente se si stanno sperimentando nuove soluzioni, può essere molto utile
# LogLevel: Control the number of messages logged to the error_log. per la risoluzione di alcuni problemi, nonchè per altri controlli che un buon sysadmin deve saper
fare.
Tramite questa direttiva, possiamo decidere il livello di verbosity dei messaggi che vengono scritti
nei file error_log; abbiamo diverse possibilità: Ad esempio, in access.log potremo andare a controllare gli accessi in un determinato giorno ad un
deterninato script o ad una determinata pagina: prendete ad esempio la righe:
x debug: messaggi utili al debug;
x info: informazioni generali;
x notice: condizioni normali ma significative; 127.0.0.1
127.0.0.1
-
-
-
-
[17/Feb/2000:17:07:38
[17/Feb/2000:17:08:41
+0100]
+0100]
"POST /cgi-bin/ml/mail-admin.pl
"GET /cgi-bin/ml/subscribe.html
HTTP/1.0"
HTTP/1.0"
200
403
1522
223
x warn: warning; 127.0.0.1 - - [17/Feb/2000:17:08:48 +0100] "GET /cgi-bin/ml/subscribe.html HTTP/1.0" 500 514
127.0.0.1 - - [17/Feb/2000:17:09:15 +0100] "GET /cgi-bin/ml/subscribe.html HTTP/1.0" 500 514
x error: errori generali (del tipo "Premature end of script headers", utili per il debugging degli
script CGI);
x crit: condizioni critiche; Il primo campo è l'indirizzo del server (è un server standalone, quindi con indirizzo 127.0.0.1!),

HTML.IT – Guide PHP 127 HTML.IT – Guide PHP 128


viene poi la data, il metodo di richiesta, il nome della pagina o dello sciript richiesto ed il protocollo consigliamo di leggere la documentazione presentata su www.html.it. Vedremo invece come
utilizzato per la richiesta; seguono poi i PID dei processi. utilizzare il modulo affinchè ci permetta di utilizzare la tecnoligia ASP su un webserver Apache.

Andiamo a vedere invece come si può presentare error.log: Continuiamo con la descrizione del modulo di cui qui ci occuperemo; Apache::ASP, dicevamo, è la
soluzione ideale per chi abbia la necessità di utilizzare pagine scritte in ASP anche sotto Apache, ad
esempio per un cambio di server o occasioni simili, oppure per semplice curiosità! Il risultato sarà
[Thu
deny
Feb 17
server
17:08:41 2000] [error] [client 127.0.0.1] file permissions
execution: /usr/lib/cgi-bin/ml/admin.pl
di massima equivalente a quello che si ottiene caricando una pagina ASP direttamente da IIS,
[Thu Feb 17 18:05:40 2000] [notice] httpd: child pid 215 exit signal Segmentation fault (11) sebbene si lavori ancora sul modulo perchè i risultati siano del tutto identici a quelli che si possono
[Fri Feb 18 10:39:18 2000] [error] [client 127.0.0.1] File does not exist: /var/www/pino
[Fri Feb 18 10:41:49 2000] [notice] httpd: caught SIGTERM, shutting down ottenere con IIS.

Ho qui preso quattro righe per poter evidenziare vari casi (che comunque non sono i soli). Tramite il modulo, in pratica, Apache opportunamente istruito interpreterà il documento ASP e
La prima indica un errore nei permessi di un file, e l'incapacità del server di eseguirlo: visualizzerà il normale output HTML. Con quell' "opportunamente istruito" intendiamo che
probabilmente (anzi, sicuramente visto che l'ho fatto apposta!!) si tratta di uno script CGI con i bisognerà configurare Apache con determinate direttive affinchè interagisca con il modulo e dia a
permessi non impostati correttamente. questo la possibilità di interpretare correttamente i documenti ASP. Per la configurazione,
La seconda è una semplice notizia: un child process è andato in Segmentation fault, lasciando rimandiamo alla documentazione del modulo Apache::ASP, che presenta una lista di direttive da
insoddisfatta una richiesta. includere nel file "access.conf" nella root directory di Apache: questa è alquanto dettagliata e
La terza è un errore che mi avverte che la directory /var/www/pino non esiste: avevo infatti cercato spiegata fin nei minimi particolari.
di raggiungere la directory "www.mio_server.it/pino".
La quarta invece è il risultato di un restart di Apache (mentre facevo delle prove): al riavvio, vengo Vediamo ora gli oggetti utilizzabili tramite il modulo: per chi conosca già la programmazione ASP,
avvertito che Apache ha ripreso la normale attività. questi non saranno una novità e si potrà inoltre notare l'analogia con quelli utilizzabili tramite IIS;
insomma, sebbene il modulo abbia dei lati negativi che vedremo in seguito, la mancanza di
Il consiglio, a questo punto, è semplice: se volete imparare a leggere correttamente i file di log, oltre compatibilità con gli strumenti di IIS non è certo uno di questi.
ad un certo intuito e ad una conoscienza del proprio sistema, è necessario fare delle prove, magari In breve, gli oggetti sono:
compiendo di proposito degli errori per vedere come il server risponde.
$Session
$Response
ASP ... ma con Apache
$Request
$Application
$Server
Con questo breve testo analizzaremo qualcosa che a molti sembrerà impensabile: vedremo come
utilizzare documenti ASP con Apache.
Ognuno di essi, poi, ha dei metodi che possono essere utilizzati dal programmatore a seconda delle
sue esigenze; anche per essi, non mancherà una nutrita lista con tanto di esempi su come utilizzare
Le active Server Pages (ASP) sono un'applicazione che ha avuto origine con l'introduzione del
ogni metodo.
server IIS di Microsoft, e che normalmente non si trovano nei sistemi Unix che fanno girare un
webserver differente da IIS.
Non è tutto oro quello che luccica.
Ma se è vero che a tutto c'è una soluzione, ebbene ... qui presentiamo la migliore per coloro che
vogliano utilizzare documenti scritti in ASP anche con Apache. Basterà solamente avere un po' di
pazienza nella fase di configurazione di Apache per l'interazione con il modulo, non immediata ma Ebbene sì, dobbiamo qui ridimensionare il discorso lodevole fatto a proposito del modulo: non
ben documentata. comunque a livello di potenzialità dello stesso che, come abbiamo visto poco sopra, permette una
piena utilizzazione di documenti scritti con tecnologia ASP in modo completamente trasparente per
Vista poi la grande diffusione di questa tecnologia, è certamente interessante il progetto di rendere l'utente che li richiami.
questa tecnologia indipendente dalla piattaforma utilizzata.
Le "pecche" a cui faremo qui riferimento sono fondamentalmente due.
Come fare?
La prima è una certa difficoltà di installazione e, soprattutto, di configurazione del webserver per
l'interazione con il modulo: sebbene la documentazione cerchi di venire incontro quanto più
possibile all'utente, con tanto di esempi, essa non è particolarmente indicata per coloro che non
Molto semplicemente, basterà procurarsi un modulo, Apache::ASP, reperibile come tutti gli altri su
abbiano troppa familiarità con il webserver Apache: saranno infatti necessarie pesanti modifiche al
CPAN.
file access.conf affinchè l'interazione fra webserver, modulo e pagine ASP sia efficiente: cito
comunque dalla documentazione che "(a proposito delle direttive da impostare) Don't set the
Non spiegheremo certo in questa sede come si programma in ASP, anche perchè molto
optional ones if you don't want, the defaults are fine...". Certamente, quindi, basterà molto poco
probabilmente coloro che stanno leggendo queste righe lo sapranno già fare: in caso contrario, vi
HTML.IT – Guide PHP 129 HTML.IT – Guide PHP 130
perchè il tutto funzioni, ma per una completa e minuziosa ottimizzazione bisigna sapere cosa Vediamo come Apache interpreta tale direttiva: una volta che avrete deciso il nome del file che
impostare e come impostarlo: ma specialmente per macchine utilizzate come server web con carichi conterrà le istruzioni e che avrete riavviato Apache per rendere efettive le modifiche, Apache andrà
di lavoro elevati l'ottimizzazione globale del sistema non è solo una cosa consigliata, ma una vera e a cercare per ogni directory richiamata da un browser questo file, dal quale leggerà le istruzioni.
propria necessità. Ovviamente, se questo non è presente, Apache agirà come di norma; se invece il file esiste, Apache
lo leggerà e agirà di conseguenza: se abbiamo impostato delle protezioni tramite password, Apache
Il secondo lato negativo su cui ci dobbiamo fermare è l'alta richiesta di risorse di sistema utilizzate farà in modo che il browser visualizzi una maschera nella quale vengono richiesti username e
dal modulo: capirete che con IIS il webserver va direttamente ad interpretare i documenti ASP, su password, tramite i quali Apache può verificare o meno l'autenticità del richiedente.
una macchina Unix invece le parti in causa non sono più solamente due, ma al webserver ed ai
documenti si frappongono il modulo Apache::ASP e, ovviamente, l'interprete Perl; se questo vi La seconda modifica da attuare è nel file access.conf: scorrete anche questo file fino ad arrivare alla
sembra ancora poco, riporto le prime righe del modulo: riga "AllowOverride": inserendo un "AuthConfig" Apache richiederà l'autentificazione. Le
possibilità, oltre a questa sono molte, in modo da poter affinare il processo di protezione: se volete
use
use
Apache();
MLDBM;
saperne di più, leggete il file manual/mod/core.html#allowoverride, presente nella directory locale
use SDBM_File; della documentazione di Apache.
use Data::Dumper;
use File::stat;
use File::Basename; Riavviato Apache, saremo pronti a preparare il file che servirà a proteggere le directory che ci
use FileHandle;
use Fcntl qw( O_RDWR O_CREAT ); interessano, che supporremo essere ".htaccess".
use MD5;
use HTTP::Date;
Immaginiamo di voler proteggere la directory remota "http://localhost/prova", corrispondente alla
directory locale "/var/www".
Un'altra decina di moduli che Apache: ASP deve andarsi a leggere per poter interpretare i
documenti ASP e visualizzarne l'output.
Prima di tutto, creiamo un file ".htaccess" all'interno di questa directory, e scriviamoci:
E' da sperare che, con le prossime releases del modulo, siano apportati miglioramenti anche in fatto
AuthName "prova"
di leggerezza dello stesso, evitando così carichi troppo elevati per le macchine.
AuthType Basic
AuthUserFile /etc/apache/passwd
APACHE: accesso ristretto al server
require valid-user

Vediamo le caratteristiche del file:


In questo tutorial ci occuperemo di un problema che a molti è caro: rendere protette alcune pagine
del nostro sito: la presenza di documenti riservati, aree ristrette ai soli membri, zone a pagamento ... La prima riga indica il nome della protezione: nella maschera che il browser ci mostrerà leggeremo
tutti questi possono essere buoni motivi per vietare ad occhi indiscreti la visione di determinate infatti: "Enter username for prova at localhost". Il discorso, a dire la verità, sarebbe molto più
pagine. ampio: sappiate comunque che, qualsiasi altro file o directory protetto con lo stesso nome in
AuthName sarà accessibile senza la necessità di eseguire ulteriori autorizzazioni. La seconda riga
Questo si svolgerà in due fasi: nella prima, vedremo come configurare Apache perchè riesca a indica il tipo di autorizzazione da eseguire: al momento, solamente l'autorizzazione del tipo "Basic"
limitare l'accesso alle directory che ci interessano; nella seconda, come automatizzare l'operazione è implementata, sebbene sia già in lavorazione un'autorizzazione "digest". La terza riga indica il file
della creazione degli account tramite l'uso di script o delle utility scritte apposta per questo scopo. che Apache andrà a leggere per verificare se l'username e la password inseriti sono corretti:
approfondiremo a breve questo discorso.
Configurare Apache La quarta riga, infine, controlla gli username: con "require valid-user" Apache accetterà qualsiasi
username presente nel file specificato in AuthUserFile. Si potrebbe invece limitare maggiormente
l'accesso, inserendo gli username ai quali (e solo ai quali, indipendentemente dalle entries presenti
Solitamente Apache, così com'è, non è configurato affinchè possa proibire o permettere l'accesso in AuthUserFile) l'accesso è consentito: quindi potrete scrivere
alle directory: avremo quindi bisogno di tre strumenti: due modifiche ad altrettanti file di
configurazione ed un file .htaccess. require user nome1 nome2 nome3 ecc.
La prima modifica che dobbiamo fare è nel file "srm.conf": scorriamolo fino ad arrivare alla linea E' possibile inoltre far riferimento ai gruppi, specialmente quando il numero di utenti cresce troppo.
che inizia con "AccessFileName": questa direttiva indica il nome del file da utilizzare per leggere I gruppi funzionano come quelli dei sistemi Unix ed ogni utente può far parte di più gruppi. Si potrà
gli attributi che dobbiamo dare alle directory nelle quali tale file è presente. Teoricamente, la quindi scrivere qualcosa del tipo:
direttiva dovrebbe essere seguita da ".htaccess", che è un nome standard (ma utilizzabilissimo!) per
i server Apache. Forse qualcuno si chiederà a cosa serva il puntino prima del nome: ebbene, negli require group nome_del_gruppo
Unix tutti i file che iniziano con un punto sono dei file nascosti, che non sono visibili tramite il
comando "ls", equivalente del "dir" del dos. Rendere nascosto un file così importante può sempre Come con gli utenti, anche in questo caso possono essere specificati più nomi di gruppo da
essere utile.
HTML.IT – Guide PHP 131 HTML.IT – Guide PHP 132
utilizzare. Se invece si usa "require group" insieme a "require user" succede una cosa del genere:
qualunque utente membro di uno dei gruppi indicati può avere accesso, così come ogni utente Vediamo in dettaglio cosa fa lo script: dopo aver chiesto un nome e la password, chiede conferma
esplicitamente specificato. per la password: se la conferma ha esito negativo, avverte della differenza fra le password digitate
ed esce; in caso contrario, apre il file che contiene le coppie username-password, critta la password
Come per gli utenti avevamo creato il file /etc/apache/passwd, dovremo creare anche un file per i inserita e scrive nel file "nomeutente-password". Ad operazione conclusa, chiude il file e avverte
gruppi: questo, semplicemente, sarà formato da linee del tipo: del successo dell'operazione.
Lo script, soprattutto per chi si intende di programmazione, non è certo un gioiello ma serve a
nome_del_gruppo:nome1 nome2 svolgere il suo lavoro: se volete utilizzarlo, sappiate che è necessario apportargli alcune modifiche
come ad esempio il controllo che un username non sia già presente nel file, un'istruzione che in caso
Ancora, come con il file passwd, dovremo specificare ad Apache dove andare a leggere i gruppi ed i di fallimento della conferma della password faccia in modo che lo script riparta dall'inizio ecc.
suoi appartenenti: utilizzeremo
Il secondo metodo, invece, è quello di utilizzare l'utility htpasswd, che crea ed aggiorna i file di
AuthGroupFile /etc/apache/group autentificazione utilizzati da Apache.

In definitiva, quindi, il file .htaccess completo potrebbe essere: La sintassi è assai semplice:

AuthName "prova" htpasswd -c file username password


AuthType Basic
AuthUserFile /etc/apache/passwd Il flag "-c" dice all'utility di creare il file delle password nel caso questo non esista; ATTENZIONE
AuthGroupFile /etc/apache/group che se il file esiste, verrà sovrascritto con la conseguente perdita dei dati precedenti.
require valid-user Vediamo un paio di esempi:
require group admin
htpasswd -c /etc/apache/passwd user
Utility per la creazione degli utenti
creerà il file "/etc/apache/passwd" ed inserirà l'username "user" e chiederà la password (con
conferma, anche in questo caso) per l'utente
Adesso che sappiamo come concedere e vietare l'accesso a determinate directory nei server,
preoccupiamoci di come creare il file. Questo, a differenza del file dei gruppi, conterrà delle righe htpasswd /etc/apache/passwd user
nella quali è specificato l'username e la password crittata, nella forma:
si può comportare in due modi: se l'utente non esiste, inserisce l'username e chiede la password; se
username:password invece l'utente esiste, htpasswd capirà che vogliamo cambiare la password all'utente specificato,
chiedendocela.
Ma come creare le coppie utente-password? I metodi sono due.
E con questo, spero, avrete capito come utilizzare le autorizzazioni di accesso con Apache per
Il primo nonchè il più complesso è quello di creare uno script del tipo: vietare ai non addetti l'accesso a determinate directory del server della vostra rete o del server
remoto.

#!/usr/bin/perl APACHE: IIS vs. Apache: i benchmark


print "Inserisci un username:\n";
chomp($name=<STDIN>);
print "\nInserisci la password per $name:\n";
chomp($pwd=<STDIN>); Meglio Linux o Nt?
print "\nConferma la password per $name\n";
chomp($pwd_confirm=<STDIN>); I benchmark sono test di confronto che intendono mostrare le performance di un prodotto con
if ($pwd ne $pwd_confirm) { software e hardware. Diversi produttori e riviste si sono avventurati in benchmark su Linux ed NT,
# Le due password digitate non sono uguali
print "Conferma password per $nome non riuscita\n"; creando non poca confusione. HTML.it tenta di fare luce mettendo a confronto gli stessi
exit;
} else { benchmark.
open(PASSWD, ">> /etc/apache/passwd")
|| die "Non riesco ad aprire il file. $!\n";
Unix o NT? Dipende!
# Critta la passord
$crypted_pwd = crypt($pwd,'aa');
#Scrive la coppia username:pwd nel file
print PASSWD "$name:$crypted_pwd";
close PASSWD; I due webserver maggiormente diffusi sulla rete sono, senza dubbio alcuno, IIS della Microsoft e
print "\nOperazione riuscita!\n";
} l'avversario Apache, sviluppato sulle ceneri di un precedente progetto e da un team di volontari.

HTML.IT – Guide PHP 133 HTML.IT – Guide PHP 134


da loro, invece, sono basati sulla pratica.
La differenza principale fra i due applicativi è la piattaforma per la quale sono stati pensati: IIS per Vero o no, facciamo finta che lo sia.
server basati su sistemi Windows, Apache per la grande famiglia degli Unix; un punto a favore di
Apache può comunque essere lo sforzo (in parte anche riuscito) di portare il webserver su Intanto, le parti in gioco:
piattaforme non native, quali ad esempio i sistemi Windows: ovviamente, le migliori performances
si ottengono su piattaforma nativa, anche se, si mormora, Apache sulle altre piattaforme non si x windows NT con service pack 4 e IIS 4;
comporta poi male. x linux suse 6.1, kernel 2.2.9 e apache 1.3.6

La "lotta" fra questi due webserver è sempre stata aperta, facendo conseguire anche un forte Entrambi, ovviamente sulle stesse macchine. I client invece erano macchine di fascia bassa (i server
dualismo fra i due sistemi operativi che li supportano: Windows da una parte, gli Unix dall'altra. E, erano equipaggiati con quattro processori Pentium II Xeon a 450 Mhz, due Gb di RAM ed una
come tutti i dualismi, ognuno afferma, dati alla mano, che il proprio prodotto è migliore del scheda di rete), alcuni Linux altri Windows (9x e NT), simulando così qualcosa come 1024 richieste
concorrente. in simultanea.
Ma ci si può fidare dei dati che ci vengono, per così dire, propinati? Se la Microsoft dicesse che IIS
supera Apache in performances in tutti i campi, ci credereste a priori? E se avvenisse il contrario? Il primo test è stato effettuato facendo richiedere a tutti i client la stessa pagina HTML da 4Kb: il
Spesso, poi, anche degli esterni ai progetti si sono lanciati in selvaggi benchmark, con risultati a risultato è una sostanziale parità di performances fra i due webserver.
volte accettabili altre assolutamente inaccettabili: se un applicativo è testato su un sistema
dell'ultima generazione e l'altro su una vecchia macchina da soffitta, chi credete che possa vincere Il secondo, invece, si basa su una richiesta casuale da parte dei client di una pagina fra le 10.000
l'ipotetica sfida? (ovviamente della stessa grandezza) presenti in una directory del server. In questo test,
Linux/Apache è risultato circa il 15% più veloce.
La rete, questa sorta bacheca di informazioni, mette a disposizione moltissime pagine con i risultati
dei benchmark fra IIS e Apache: nella stragrande maggioranza dei casi, comunque, questi risultano Il terzo test, che inizia ad essere impegnativo per le macchine, si basa sulla richiesta di una quantità
fortemente di parte. di file di due volte superiore a quella della RAM dei server (quindi qualcosa come 4 GB di pagine
Vedendo i risultati dei test nella pagine delle compagnia "x" che si dichiara partner di Microsoft, richieste). NT/IIS sembra non riuscire a sopportare più di 30 richieste al secondo, mentre
oppure quelli della compagnia "y" partner di Apache, sareste disposti a credere che i risultati siano Linux/Apache arriva a 166. La differenza, si commenta, può essere principalmente dovuta la tipo di
veritieri? Magari lo sono, ed i dati risultanti non sono stati manipolati, ma chi ci assicura che un test partizione utilizzata dai sistemi (in termine di grandezza dei cluster o inode) che non alle capacità
è stato fatto su un 486 e l'altro su una macchina quadriprocessore? Ad esempio, Netcraft afferma degli stessi.
che la coppia Linux/Apache è la più utilizzata come server web; Mindcraft, invece, afferma che è
esattamente il contrario, anche per il fatto che NT/IIS è circa tre volte più veloce di Linux/Apache Il quarto test si basa non più su pagine statiche come nei precedenti tre test, ma su pagine
... dinamiche: la scelta è ricaduta sui CGI, non essendo le tecnologie ASP e VBscript direttamente
portabli ad altri sistemi. Su NT è stato installato ApcivePerl 517.3, equivalente al Perl 5.005_3
Insomma, anche qui ci sarebbe molto da discutere senza, purtroppo, arrivare ad alcuna conclusione. presente sul server Linux. Il risultato è palese: NT/IIS soffrono della "non-natività" del linguaggio
A meno di volersi fare i test in casa da soli, a qualcuno bisognerà pur credere. Perl utilizzato per l'interpretazione dei CGI, riscontrabile come un'eccessiva lentezza nell'invio delle
pagine create dinamicamente. Ma per questo test, avvertono, il risultato era scontato dall'inizio, e
Navigando per l'intricata rete, mi sono imbattuto in due pagine con gli amati-odiati benchmark, che quindi poco significativo. Ricordiamo infatti che il Perl, linguaggio più largamente utilizzato per
sembrano essere stati condotti con sufficiente serietà e senza voler portare l'acqua al mulino di scrivere script CGI, è nato in ambiente Unix e, sebbene il porting di Activestate per le piattaforme
nessuno: ovviamente mi posso sbagliare, ma fa anche questo parte del gioco. Windows sembra essere molto ben riuscito, ancora una volta la non-natività del linguaggio di
Inoltre, non aspettatevi alcun tipo di commento personale : quello che leggerete è solo un estratto interpretazione si fa sentire.
delle due pagine.
L'ultimo test è quello di servire sedici macchine tramite due schede di rete. Qui NT/IIS riesce a
Prima di passare ai benchmark, ricordo che si sentirà spesso parlare di NT e Linux, che stanno ad prevalere sull'avversario Linux/Apache anche con una potenza di calcolo minore, ossia con un
indicare il comportamento, rispettivamente, fra NT/IIS e Linux/Apache. processore in meno. La velocità con cui NT/IIS invia le pagine ai client ha fatto addirittura pensare
che le performances non sarebbero peggiorate significativamente neanche con quattro schede di rete
Il primo benchmark al posto di due.
Questo dimostra che NT, quando ci si attiene alle sue "regole", può essere veramente veloce.

Questa pagina mi ha subito stupito per una frase: "Server benchmarks comparing Linux and NT are Le conclusioni degli autori del test sono le seguenti: per una rete mista, formata cioè da richieste
in. Mostly, however, they try to make headlines by breaking records in unrealistic benchmark differenti ed indipendentemente dal volume delle stesse, l'accoppiata Linux/Apache risulta migliore.
scenarios. In c't's test lab, a comparison between NT/IIS and the freeware duo Linux/Apache Per un server con più schede di rete e con prestazioni medio-alte, NT/IIS è l'accoppiata ideale.
focused on practice-oriented tasks." Ovviamente, poi, sottolineano il fatto che le necessità possono essere anche altre, ad esempio il
linguaggio di scripting da adottare (CGI, ASP, VBscript ecc.), la potenza della macchina da
Insomma, si afferma che moltissimi test di benchmark sono condotti senza criterio; quelli condotti utilizzare (sembra infatti che Linux/Apache riesca a "spremere" maggiormente le CPU, sebbene

HTML.IT – Guide PHP 135 HTML.IT – Guide PHP 136


NT/IIS appaia sempre più performante per ogni CPU aggiunta) ecc. 3. PC Week, maggio 1999

Insomma, tennisticamente parlando il risultato è un "40-30" a favore di Linux/Apache: la non netta http://www.zdnet.com/pcweek/stories/news/0,4153,401970,00.html Hardware: quattro
supremazia dell'uno o dell'altro mi ha fatto scegliere questa pagina, considerata imparziale nei schede Ethernet 100baseT, quadriprocessore Pentium III a 500 Mhz, 1 GB RAM
giudizi. Software: Linux 2.2.7/Apache - NT 4.0 Workstation - Solaris 2.7 - Netware 5.0

Il secondo benchmark Le performances dei quattro sistemi analizzati sono a grandi linee simili: salgono con una
curva simile fino a stabilizzarsi a seconda dei client richiedenti: Linux si ferma a 28, NT a
40, Solaris e Netware continuano a salire anche oltre i 60 client.
Questa pagina mi è piaciuta per un motivo: non c'è un'opinione personale che sia una. Piuttosto, è
un estratto di tutti i vari benchmark reperibili in rete fra NT/IIS e Linux/Apache. 4. ZD Labs, giugno 1999

Tutti i benchmark riportano: http://www.zdnet.com/pcweek/stories/news/0,4153,1015266,00.html


Hardware: quattro schede Ethernet 100baseT, quadriprocessore Pentium II Xeon a 400 Mhz,
x l'autore o autori; 1 GB RAM
x la data; Software: Linux 2.2.6/Apache 1.3.6 - Win NT 4.0 EE, SP4, IIS 4.0
x il link al benchmark vero e proprio;
x le macchine utilizzate; Questo test è una replica del test di Aprile di Mindcraft.
La performances dei due sistemi questa volta si equivalgono e le performances di Linux non
Inoltre, tutti i benchmark che vedremo si basano su un software multipiattaforma creato ad hoc da hanno bruschi cali come nel test di aprile. Il tutto viene giustificato da una versione del
ZD Labs: WebBench (http://www.zdnet.com/zdbop/webbench/); questo software misura quanto kernel più recente ... ma siamo sicuri che i due tecnici RedHat invitati a preparare il test
velocemente un server riesce ad inviare all'esterno delle pagine HTML statiche da un albero di sulla macchine Linux non c'entino niente (in fatto di competenze e capacità di tuning del
directory di 60 Mb. sistema, intendo)??

5. PC Magazine, settembre 1999


Stiamo a vedere cosa può saltare fuori.
http://www.zdnet.com/pcmag/stories/reviews/0,6755,2327827,00.html
1. ZD, gennaio 1999
Questo test è interessante perchè mostra le prestazioni di due sistemi (Linux e NT, appunto)
http://www.zdnet.com/sr/stories/issue/0,,387506,00.html
non ottimizzati per fungere da webserver: inoltre, le macchine sono di fascia bassa, con una
Hardware: CPU 266Mhz, 64Mb RAM, HD 4 GB IDE, Scheda 100BaseT
singola CPU e 128 Mb di RAM. In questo test, Linux sorpassa le performances di NT di
Software: Linux 2.0.35/Apache 1.3.1 - Win NT Server 4.0, SP4, IIS 4.0
circa il 50%, accedendo anche meno al disco fisso.
Questo test afferma che le distribuzioni commerciali di Linux (sebbene non si capisca
perchè "solo quelle commerciali" ...) si comportano meglio, a parità di hardware, di NT.
Conclusioni
2. Mindcraft, aprile 1999

http://www.mindcraft.com/whitepapers/first-nts4rhlinux.html Hardware: quadriprocessore Avevo detto all'inizio che non mi sarei sbilanciato su conclusioni che potrebbero (anzi, sarebbero
Pentium II Xeon a 400Mhz, 1 GB RAM, scheda 100baseT state!!) personali: ebbene, non mi rimangio tutto ma voglio solo fare alcune considerazioni che
Software: Linux 2.2.2/Apache 1.3.4 - Win NT 4.0 EE, SP3, IIS 4.0 considero oggettive.

C'è da aggiungere che le schede Ethernet in questione erano quattro e sotto NT ogni In primo luogo, l'hardware utilizzato per le prove è determinante per gli esiti dei benchmark:
processore era legato ad una scheda. ovviamente si parla a parità di macchine, ma è ovvio che se un sistema è ottimizzato per avere le
migliori prestazioni su una macchina configurata in un determinato modo e con determinato
I risultati sono di una velocità di NT/IIS due o tre volte superiore a quella di Linux/Apache, hardware installato, per le altre c'è poco scampo.
che ad un certo punto ha avuto un brusco calo di performances. Non è però trascurabile il Se NT è ottimizzato per lavorare con il processore1 sulla scheda Ethernet1 , il processore2 sulla 2 e
fatto che il test sia stato commissionato da Microsoft. via dicendo, ovviamente le prestazioni a confronto con quelle di Linux che non impiega un
Inoltre, i risultati del un test effettuato con quattro schede Ethernet sono abbastanza simili a procesore per ogni scheda sono migliori; inoltre, in un caso come quello appena visto, non
quelli del primo benchmark esaminato. impegnando direttamente Linux un processore per ogni scheda, si sarebbe dovuta (o almeno
potuta!) misurare la capacità dei due sistemi, a parità di carico, di gestire altre applicazioni. Così
come Linux su sistemi "poveri" si comporta meglio di NT, visto il minor impiego di risorse di

HTML.IT – Guide PHP 137 HTML.IT – Guide PHP 138


questo sistema. E questi sono solo due casi che si possono ipotizzare. SSL_BASE=

Inoltre, per quanto riguarda sia Linux che NT, c'è un discorso da fare a livello di software: punti esattamente alla directory dove è presente la libreria SSLeay, nel nostro caso
/usr/local/SSLeay-xxx. Se tutto è a posto, non ci resta che lanciare lo script "./configure" che creerà
x per Linux, la versione del kernel c'entra molto: ogni nuova versione è un miglioramento della il Makefile seguito da un "make" per compilare i sorgenti. Se tutto va per il verso giusto, dovremo
precedente, ed è quindi matematico che una versione del kernel più aggiornata garantisca migliori veder apparire l'eseguibile "httpsd", che sarà proprio il demone che supporterà il protocollo HTTPS.
prestazioni di una vecchia versione;
x Per NT è la stessa cosa a livello di Service Pack: purtroppo non tutti i benchmark riportano la Il primo certificato
versione di SP utilizzata, ma anche qui è ovvio che una versione aggiornata comporta una crescita
di prestazioni; altrimenti, a cosa servirebbero le patch??
Adesso che abbiamo il demone httpsd, possiamo creare il nostro certificato: le informazioni che
A questo punto ognuno può pensare quello che vuole, i dati sono questi e sono forniti da società servono sono tutte contenute nel Makefile creato dal "./configure" lanciato dalla directory dei
presumibilmente serie. Le differenze ci sono, ed ho cercato anche di motivarle per quanto mi fosse sorgenti di Apache, quindi potremo lanciare il comando
possibile: sta ad ognuno, se interessato, provare se questi siano veritieri o meno.
make certificate
Ricordatevi sempre che, comunque, un tecnico windows riuscirà sempre a far prevalere (anche in
buona fede) un sistema NT su un sistema Linux e viceversa! Credo che anche le competenze che compilerà quello che serve, creando la chiave RSA a 1024 bit e ponendoci alcune domande sul
software siano un buon elemento per poter giudicare i test proposti! nostro server, ad esempio:

APACHE: il protocollo HTTPS 1. Country Name (2 letter code);


2. State or Province Name;
3. Locality Name (eg, city);
Quello che qui tratteremo sarà il rapporto fra il webserver Apache ed il protocollo HTTPS, ossia il 4. Organization Name;
protocollo HTTP con il supporto SSL. Vedremo quindi dove reperire i sorgenti, come compilarli, 5. Organization Unit Name;
come creare dei certificati e come configurare al meglio il server per abilitare il supporto HTTPS. 6. Common Name (eg, ssl.domain.com; required!);
Quello di cui tratteremo in queste pagine sarà riferito ai soli sistemi Unix, visto che 7. Email Address;
l'implementazione del protocollo SSL su altre piattaforme non è ancora stata realizzata.
Fornendo tali informazioni, verrà creata la nostra chiave privata RSA ed il nostro certificato: è da
Parte prima: il codice sorgente notare che la maggior parte delle domande che ci verranno fatte sono opzionali, e che solo
"Common Name" è richiesta, per ovvie ragioni.

Ovviamente, prima di iniziare abbiamo bisogno del giusto codice sorgente di Apache, reperibile La chiave RSA che risulterà sarà qualcosa di simile a:
all'homepage del progetto Apache-SSL, http://www.apache-ssl.org/. Alternativamente, è possibile
trovare una versione di Apache con supporto SSL già nei pacchetti del proprio sistema: ad esempio, -----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDBpDjpJQxvcPRdhNOflTOCyQp1Dhg0kBruGAHiwxYYHdlM/z6k
nella Debian 2.2 che sto al momento utilizzando è presente il pacchetto "apache-ssl-1.3.9.12+1.deb" pi8EJFvvkoYdesTVzM+6iABQbk9fzvnG5apxy8aB+byoKZ575ce2Rg43i3KNTXY+
...
che, una volta installato, ci farà avere un webserver Apache già compilato con il supporto SSL C5VTb4CUF7d6ukDVMT2d0/SiAVHBEI2dR8Vw0G7hJPY=
built-in. Per chi non abbia tale pacchetto, il download dei sorgenti da compilare è l'unica strada da -----END RSA PRIVATE KEY-----
seguire.
mentre il certificato sarà qualcosa tipo:
A questo punto, ci servirà anche una libreria per la crittatura dei dati da utilizzare per il "secure
HTTP": stiamo parlando di "SSLeay", reperibile via FTP al sito
ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/; scaricata e spostata in qualche directory come, ad esempio, -----BEGIN CERTIFICATE-----
MIICvTCCAiYCAQAwDQYJKoZIhvcNAQEEBQAwgaYxCzAJBgNVBAYTAlVTMQ8wDQYD
/usr/local, non ci resterà che decomprimerla ed entrare nella risultante sottodirectory SSLeay-xxx VQQIEwZOZXZhZGExFTATBgNVBAcTDEhvcGVmdWwgQ2l0eTEZMBcGA1UEChMQQnV0
...
(dove "xxx" è il numero di versione della libreria). Dopo aver letto il file INSTALL, siamo pronti 7kM1LoxQjZL0bg61Av3WG/TtuGqYshpE09eu77ANLngp
per installare la libreria: lanciando ./Configure ci verrà fornita una serie di sistemi operativi fra cui -----END CERTIFICATE-----
scegliere: troviamo il nostro e lanciamo nuovamente "./Configure nostrosistema".
Ovviamente, per non riportare inutili linee piene di simboli, non è stato riportato il certificato per
Fatto questo, potremo scaricare dal sito FTP ftp://ftp.ox.ac.uk/pub/crypto/SSL/ la patch per Apache: intero, ma è stato "virtualmente" tagliato con l'uso dei "..."; ovviamente, quando creerete la vostra
applichiamola ai sorgenti come descritto nel file README.SSL ed iniziamo a compilare Apache: chiave ed il certificato non vedrete i puntini ma una serie di righe formate da una sequenza di
se il processo di patching è andato a buon fine, dovremo vedere, nei sorgenti di Apache, che la riga caratteri. Ricordiamo, inoltre, che l'output di tutto il lavoro fatto per la creazione della chiave RSA e
del certificato è nel file "httpsd.pem".

HTML.IT – Guide PHP 139 HTML.IT – Guide PHP 140


APACHE: virtualhosts
Il file di configurazione

Quello di cui ci occuperemo in questa guida saranno i virtualhosts. Cosa sono i virtualhosts?
A questo punto siamo a posto per quanto riguarda il demone httpds, la chiave RSA ed il nostro Supponete di avere due hosts sulla stessa macchina: il primo è quello che siamo abituati a chiamare
certificato: quello che ci manca è un file di configurazione che dica al webserver come comportarsi "il server", il secondo è il virtual host. In pratica, quindi, due o più server sulla stessa macchina,
quando è stabilita una connessione SSL; un esempio di file di configurazione è reperibile, sempre come www.server1.com, www.server2.com ecc. Entrambi, comunque, saranno visto come veri e
fra i sorgenti di Apache, alla directory ../apache/SSLconf/conf. Tale file si occupa di creare due propri "server separati".
"siti", uno sicuro sulla porta 8888 ed uno "normale" (semplice protocollo HTTP) sulla porta 8887. I virtualhost, come potrete benissimo immaginare, sono altamente utilizzati nel webhosting, quando
Vediamo le voci del file che ci interessano: noterete che molte sono simili a quelle incontrate per i un utente, oltre ad acquistare dello spazio sul server, registra anche un nome di dominio, al quale il
normali file di configurazione di Apache. server deve rispondere.

User webuser
Group webgroup
Apache, dalla versione 1.1, supporta sia i virtualhosts basati sul numero di IP sia quelli basati sul
# L'utente ed il gruppo, come per il file httpd.conf nome; questi ultimi vengono anche chiamati "basati sull' host" (host-based) oppure "non-IP virtual
Loglevel debug hosts".
# Il livello di dettaglio dei file di log
ServerType standalone Vedremo nei prossimi capitoli come creare e configurare entrambi.
# A differenza di httpd.conf, in una connessione SSL il server deve
# essere di tipo standalone, e non lanciato da inetd.
IP-Based Virtual Hosts
Port 8887
# La porta nella quale il server è in ascolto: di default, questa
# sarebbe la 443 (da /etc/services:
# https 443/udp)
# ma scegliamo la 8888 per non dover essere root. Il primo tipo di configurazione che vedremo è quello basato sull'IP: ovviamente, per rendere il tutto
Listen 8887 possibile, avrete necessariamente bisogno di più di un IP, rispettivamente uno per ogni host virtuale.
Listen 8888
# Le porte nelle quali il server è messo in listen: notate che ne
# abbiamo specificate due, una per il normale protocollo HTTP l'altra per Sicuri di avere quanto necessario, si pone davanti a noi un'altra scelta: configurare Apache in modo
# il protocollo HTTPS.
che un singolo processo httpd sia eseguito per ogni singolo host, oppure utilizzare un solo processo
DocumentRoot /usr/www/site.ssl/htdocs httpd per tutti gli host.
# La document root
Scegliere fra queste due possibilità non sarà comunque un problema: se avete problemi di memoria
SSLRequireSSL RAM, utilizzate un singolo processo, se invece avete bisogno di differenti configurazioni per ogni
# Questa direttiva serve a proteggere una directory negando l'accesso
# quando non si è connessi con protocollo SSL: l'utilità delle direttiva host e sulla vostra macchina la RAM abbonda, utilizzate più processi.
# è quella di non permettere a chiunque di accedere ai documenti ai
# quali normalmente si accederebbe con SSL
TransferLog logs/transfer_log
1. Utilizzazione di più processi httpd.
# Il file di log.
SSLDisable per lavorare con più demoni httpd, basterà semplicemente utilizzare una direttiva "listen" per
# Con questa direttiva disabiliteremo il protocollo SSL per i ognuno, ad esempio:
# virtualhosts; se si vuole fare il contrario, sarà necessario
# sostituire "SSLDisable" con "SSLEnable".
Listen www.sito1.com:80 (oppure Listen 123.456.7.8:80)
SSLCACertificateFile /usr/www/site.ssl/conf/thawte.cert Listen www.sito2.com:81
# Il path per il certificato CA
SSLVerifyClient 0
# Se impostata su "0", non si richiede un certificato; su "1" il client e via dicendo. 2. Utilizzare un solo processo con i virtual hosts. In questo caso, utilizzeremo un solo
# può presentare un certificato valido; su "2" il client deve presentare processo httpd per tutti gli host virtuali; la configurazione di ogni host può partire dall'esempio
# un certificato valido; su "3" il client può presentare un certificato
# valido anche se questo non è richiesto per il certificato CA. Un riportato nel file httpd.conf:
# tipico messaggio del server quando un client non presenta un
# certificato potrebbe essere:
# "No User Certificate.
# The site 'www.sito.com' has requested client <VirtualHost host.some_domain.com>
# authentication, but you don't have a Personal Certificate ServerAdmin webmaster@host.some_domain.com
# to autenthicate yourself. The site may choose not to give you access DocumentRoot /var/www/host.some_domain.com
# without one." ServerName host.some_domain.com
ErrorLog /var/log/apache/host.some_domain.com-error.log
SSLCACertificateFile /usr/www/site.ssl/conf/cert.pem TransferLog /var/log/apache/host.some_domain.com-access.log
# Il path per il certificato che abbiamo creato all'inizio del capitolo. </VirtualHost>
CustomLoglogs/ssl_log "%t %{version}c %{cipher}c %{clientcert}c"
# Il file di log "custom", come quello visto per Apache senza supporto # SSL.
Poniamo di voler creare l'host virtuale www.virtuale.com, la cui DocumentRoot sia /www/virtuale

HTML.IT – Guide PHP 141 HTML.IT – Guide PHP 142


ed il file di log degli errori in /var/log/virtuale/error.log; quello che dovremo scrivere sarà: differenti configurazioni, consiglio una lettura degli esempi forniti con la documentazione di
Apache, presenti nella directory ../apache/manual/vhosts/examples.html

<VirtualHost www.virtuale.com>
ServerAdmin admin@virtuale.com
APACHE: un setup sicuro
DocumentRoot /www/virtuale
ErrorLog /var/log/virtuale/error.log
</VirtualHost>
Sappiamo tutti l'importanza di un servizio di webserver, specialmente in questi ultimi periodi nei
Per ogni host virtuale che vorremo creare, ovviamente, sarà necessario inserire un altro blocco di quali sembra che la rete sia un nuovo Eldorado; un servizio del genere, comunque, non può che
istruzioni fra i "tags" <VirtualHost> e </VirtualHost> implicare dei rischi, vista la potenziale insicurezza dei webserver; se poi a questi, oltre al normale
onere di inviare pagine web, diamo anche altre mansioni come ad esempio eseguire file (soprattutto
Name-based virtual hosts script) e cose del genere, il potenziale rischio di creare un servizio non solo poco efficiente ma
anche pericoloso cresce esponenzialmente.

Utilizzare una configurazione del genere per i virtual hosts è un'ottima maniera di implementare un Un webserver ben configurato, da mani esperte con anni di esperienza alle spalle e miriadi di
bel numero di host su un solo server. Il piccolo contro, è che i browser devono supportare il macchine preparate a questo scopo, è certamente un ottimo punto di partenza; l'altra faccia della
protocollo HTTP/1.1, che praticamente tutti i browser recenti supportano. medaglia è, comunque, la possibilità purtroppo non così remota di compiere degli errori anche
banali in fase di configurazione che si possono trasformare in veri e propri eventi drammatici. Un
Configurare degli host in questo modo non è troppo dissimile dalla configurazione degli IP-based esempio su tutti è un errore di assegnazione di qualche permesso, in modo che qualcuno senza
virtual hosts: l'unica differenza è l'utilizzo della direttiva NameVirtualHost. autorizzazione si veda avere accesso a zone vietate della macchina.
Se ad esempio www.server1.com e www.server2.com sono legati all'indirizzo IP 123.456.7.8,
possiamo impostare due virtual host come segue: Vedremo qui le cose più importanti da non tralasciare quando si configura un server web, nella
fattispecie, ovviamente, Apache.
NameVirtualHost 123.456.7.8
<VirtualHost 123.456.7.8>
5 cose da tenere sotto controllo
ServerName www.server1.com
DocumentRoot /www/server1
</VirtualHost>
<VirtualHost 123.456.7.8>
ServerName www.server2.com
DocumentRoot /www/server2
</VirtualHost> 1. Disabilitare i SSI (Server Side Includes) ogni volta che questi non siano strettamente
necessari; si utilizzi la direttiva "Options" in ogni directory oppure in ogni file .htaccess per
Quindi, sulla macchina con IP 123.456.7.8, saranno presenti due host, ognuno con le proprie abilitarli dove serva; inoltre, sarebbe da disailitare la funzione "exec", potenzialmente
caratteristiche e, soprattutto, nome. Ricordate inoltre che fra <VirtualHost> e </VirtualHost> dannosa se utilizzata per secondi fini.
potrete inserire tutte le istruzioni che vi servono, differenti per l'uno e per l'altro host: in questo caso
2. Si utilizzi la direttiva "AllowOverride None" ogni volta che questo sia possibile. Tale
abbiamo cercato di semplificare al massimo la configurazione degli host ma, per un esempio, potete
direttiva serve a questo: se il webserver trova, ad esempio, un file ".htaccess" o comunque
rifarvi all'esempio riportato poco sopra.
un file il cui nome sia specificato nella direttiva "AccessFileName", deve sapere quali valori
presenti in questo file possono bypassare quelli di default del server. Quindi,
Prima di chiudere
potenzialmente, un file ".htaccess" potrebbe far comportare il webserver in maniera
totalmente differente da quella definita nel suo file di configurazione. Ovviamente, con la
direttiva "AllowOverride None" non si corrono di questi rischi: a monte di tutto c'è,
Prima di terminare, poniamo l'accento su una cosa che per alcuni potrebbe essere utile: ad esempio, comunque, un solido e curato file di configurazione principale di Apache.
volete che a "http://server.it" corrisponda anche "www.server.it". Questo può essere fatto con
semplicità tramite: 3. Proteggete le home directory degli utenti, specialmente nel caso in cui facciate dell'hosting
remoto. Questo può essere fatto tramite la direttiva "<Directory> </Directory>", che
ServerAlias server.it www.server.it specifica delle direttiva da applicare ad una determinata directory ed alle sue sottodirectory.
Ad esempio, supponendo che tutti i vostri utenti abbiano le loro home in /usr/home, il
oppure minimo che potete scrivere è:
ServerAlias server.it *.server.it <Directory /usr/home>
AllowOverride None
Per chi volesse approfondire l'argomento dei virtual hosts, soprattutto per quanto riguarda le Options Indexes

HTML.IT – Guide PHP 143 HTML.IT – Guide PHP 144


SymLinksIfOwnerMatch
</Directory> Una prima operazione sul database è creare una tabella di lavoro

Ovviamente, potrete poi specificare altre opzioni che ritenete utili per ognuno dei vostri
utenti separatamente o, perchè no, tutti. 5. Ultime operazioni preliminari

4. Non abusate della direttiva "AddHandler". Sebbene questa possa essere utile a farci perdere Aggiunta del codice html necessario a creare un'interfaccia di interazione per l'utente
meno tempo in configurazioni, copia dei file in determinate directory ecc, può essere
pericolosa per il semplice fatto che qualsiasi estensione passata alla direttiva può diventare
uno script eseguibile sul server con conseguenza imprevedibili. Puntate piuttosto su una cgi- 6. Inseriamo l'articolo nel database
bin di sistema ed, eventualmente, su una directory cgi-bin per ogni utente (che dev'essere
comunque controllata) senza specificare, ad esempio, che qualsiasi file con estensione .pl o Come mettere al sicuro i dati in MySql
.cgi sia eseguito dal server.
E' senza dubbio migliore perdere qualche minuto a spostare gli script nella directory cgi-bin
che non lasciare che qualsiasi file sia indiscriminatamente eseguito da qualunque posizione 7. Visualizziamo i titoli degli articoli
(ovviamente "web-visible").
Estrapoliamo solo il titolo della news dal database
5. Fate attenzione all'assegnazione dei permessi: di regola, un utente, specialmente in hosting,
non dovrebbe mai avere la possibilità di uscire dalla propria home directory, sia in lettura
che soprattutto in scrittura; questo per diversi motivi: intanto, per non andare a leggere o 8. Visualizziamo l'articolo completo
modificare lavori di altri utenti e, in secondo luogo, per non andare a zonzo nel sistema
trovando magari qualche eseguibile da lanciare o dati riservati da leggere. LA cosa migliore
Estrapoliamo dal database l'intera news
sarebbe quella di creare un gruppo (potrebbe essere "users" o "remote_users" o qualunque
cosa vogliate) nel quale ogni nuovo utente viene inserito, in modo che si veda già alla
creazione limitato nelle azioni da compiere sul sistema ospitante.
9. Elencare i titoli di tutti gli articoli

Selezionare e mostrare solo i titoli delle news


Percorso consigliato di Francesco Bonetto
Apprendista fra117@html.it
10. Il motore di ricerca
Una guida di base per capire i comandi fondamentali di interazione tra Php e MySql
Costruire un motore per ricercare le news

11. Lo schema utilizzato


1. Introduzione
Breve riassunto delle funzioni utilizzate
Accenni sull'interazione tra Php e Mysql

12. La struttura della query


2. Breve introduzione ai database relazionali
Creare in modo corretto una query al database
Cosa sono e quali le loro caratteristiche

13. Miglioriamo lo script


3. Prima connessione al database
Accorgimenti per rendere più efficiente lo script
Poche righe di codice per effettuare la prima connessione al database

14. Gestire due tabelle come una sola


4. Creiamo la tabella

HTML.IT – Guide PHP 145 HTML.IT – Guide PHP 146


Come unire più tabelle per interrogarle con un'unica query caratteristiche dell'elemento che vogliamo memorizzare. In particolare nel nostro esempio vorremo
memorizzare un id, il titolo, il testo, la data, l'autore e magari anche l'indirizzo e-mail dell'autore.
Per ogni elemento che inseriremo nella tabella verrà creata una nuova riga. Vediamo un esempio:
15. Le principali funzioni Php - MySQL

Le principali funzioni Php per interagire con MySQL +----+--------+---------+--------+--------+------------+


| id | titolo | testo | data | autore | mail |
+----+--------+---------+--------+--------+------------+
| 1 | Primo | Ecco il |10-10-01| freephp|mail@html.it|
| | art. | primo | | | |
Introduzione | | | articolo| | | |
+----+--------+---------+--------+--------+------------+
| | Secondo| Ed ecco |11-10-01| freephp|mail@html.it|
| | art. | il | | | |
| | | secondo | | | |
Un problema sempre più frequente dei webmaster è quello di dover gestire intere sezioni dei loro +----+--------+---------+--------+--------+------------+

siti in modo semplice e veloce. La gestione è quanto più efficiente, tanto più è possibile effettuare
modifiche frequenti di contenuto, ma, a volte, anche di veste grafica. Un sito che aspiri ad aver un Da notare, in particolare, la colonna id: questa, come potete immaginare, non contiene alcuna
certo successo deve anche offrire una consistente quantità di informazioni, ma è impensabile dover informazione che riguarda l'articolo. Anzi, vedremo che questo valore non sarà mai visibile
modificare centinaia di pagine ogni volta si apporti anche il minimo aggiornamento. all'utente. Il database, però, ha bisogno di poter distinguere i vari articoli e questo deve avvenire
attraverso un campo (o un insieme di campi) univoco in ogni riga che prende il nome di chiave
In tutto questo, per fortuna, ci sono venuti in aiuto i linguaggi di programmazione orientati al web primaria. Questo campo, in questo caso, è un numero che si auto incrementa all'inserimento di
publishing come Php, asp o perl. Purtroppo tutto questo si è rivelato subito insufficiente: i linguaggi ogni nuova riga.
sono ottimi per la creazione di pagine dinamiche, ma non offrono nessuna possibilità di Ogni colonna della tabella avrà determinate caratteristiche a seconda dell'informazione che
memorizzazione dei dati. La soluzione attuale è quindi quella di utilizzare parallelamente un vogliamo memorizzare:
linguaggio di programmazione e un database. id è, come detto, un numero intero positivo che si auto incrementa;
titolo è una stringa di una certa lunghezza;
In questa guida ci occuperemo infatti di far interagire Php con il database relazionale MySQL. data potrà essere memorizzata in diversi formati, ma vedremo in seguito quale utilizzare;
Questa accoppiata è, al giorno d’oggi, una delle più diffuse in rete in quanto abbiamo a disposizione testo è un'altra stringa, ma notevolmente più grande;
gratuitamente un linguaggio solido, capace di sopportare grandi carichi di lavoro, e un database autore e mail, infine, saranno anch'esse stringhe.
dalle notevoli qualità tecniche.
Un database può contenere più di una tabella con strutture differenti. Queste tabelle possono però
Prima di imparare a lavorare con MySQL è necessario avere una discreta conoscenza del Php. Per avere informazioni incrociate e con un certo legame concettuale. Questi li possiamo definire
questo consigliamo a chi si avvicina per la prima volta a questo tipo di programmazione di iniziare attraverso relazioni (da cui il nome database relazionale). Questo concetto, però, lo
con una guida meno specifica, come la Guida di base di Giangiacomo Patteri. approfondiremo più avanti.
Nel corso di queste lezioni vedremo come creare uno script completo e accessoriato di varie
funzionalità. In particolare il nostro script creerà un archivio di articoli, di cui ne visualiziamo in Prima connessione al database
una determinata pagina i titoli. Cliccando su questi sarà possibile leggere l’intero articolo, vedere gli
arretrati, e fare una ricerca all’interno dell’archivio.
Durante questa lezione vedremo le operazioni necessarie per la connessione al database. Prima di
Come già saprete, per poter testare il codice sul nostro computer di casa abbiamo bisogno di un poter comunicare con questo abbiamo infatti bisogno di creare un "collegamento" fra lo script e
webserver, del modulo Php e del server MySQL. Questi ci eviteranno il fastidio e il costo di dover MySQL.
trasferire le pagine su un server ogni volta che ne vorremo valutare la correttezza. Per quanto
riguarda l’installazione di questi componenti vi rimando nuovamente alla Guida di base Php e alla E' importante prima di tutto chiarire un concetto: ognuno di noi ha disposizione un database che non
Guida sull'installazione di Apache, Php e MySql in ambiente Windows . viene memorizzato in un file specifico. In particolare questo viene memorizzato in un insieme di
file che non è accessibile a chiunque. Anche se possedete un dominio e vi siete rivolti a un servizio
Breve introduzione ai database relazionali di hosting a pagamento, questo non vi permetterà di accedere ai file: potrete modificarli
indirettamente (quindi tramite query), ma non potrete copiarli o salvarli. Questo crea una
limitazione nel senso che quando volete distribuire uno script, non potete fornire con esso anche il
I database sono delle strutture nelle quali è possibile memorizzare grandi quantità di informazioni, database. Dovete quindi fare in modo che l'utente crei le tabelle necessarie all'interno del suo
per poi ricavarle attraverso linguaggi di scripting come il PHP. Il punto di forza di un database sta database: potremmo quindi dirgli di accedere a phpMyAdmin e crearsi una tabella con determinate
nella velocità con cui le informazioni vengono trovate; dato il loro largo utilizzo ne esistono diversi caratteristiche. Questo metodo, però, richiede una serie di conoscenze da parte dell'utente che
tipi a seconda dell'uso che ne dobbiamo fare. Fra questi quello attualmente più diffuso è probabilmente non ha. Quindi gli forniremo uno script che creerà per lui tutte le tabelle necessarie.
sicuramente il modello relazionale che ci permette di memorizzare i dati all'interno di tabelle.
Le tabelle saranno ovviamente costituite da colonne e da righe. Le colonne rappresentano le Prima di tutto, però, avremo bisogno di alcune informazioni relative all'accesso al database: l'host

HTML.IT – Guide PHP 147 HTML.IT – Guide PHP 148


da cui si può raggiungere MySQL (generalmente è localhost); username e password per l'accesso mysql_select_db($db_name, $db)
or die ("Errore nella selezione del database. Verificare i parametri nel file
al database; il nome del database. Questi quattro parametri vengono forniti dall'amministratore del config.inc.php");
nostro spazio web.
Quindi creeremo una pagina di nome config.inc.php con queste righe: In questo caso non abbiamo bisogno di memorizzare alcun valore, visto che la funzione restituisce
solo TRUE o FALSE.
<?
// parametri del database Creiamo la tabella
$db_host = "localhost";
$db_user = "";
$db_password = "";
$db_name = "";
Dopo aver creato la connessione possiamo finalmente agire sul database. In questa lezione vediamo
quindi come creare una tabella utilizzando procedimenti differenti il cui risultato finale è però
Abbiamo dato proprio questo nome al file per diversi motivi: sempre identico.
config indica che il file contiene dei dati relativi alla configurazione dello script. Ovviamente
possiamo chiamarlo come vogliamo, ma facendo così ci risulterà più facile distinguerlo dagli altri In questo caso dovremo comunicare direttamente con il database, quindi dovremo mescolare i
file. .inc ci ricorderà che questo file non è una pagina che verrà visualizzata direttamente, ma verrà codici Php e Sql. I comandi che inviamo al database sono detti query che letteralmente significa
inclusa all'interno di altre. Anche questa parte del nome può essere modificata, se non addirittura domanda. Infatti noi chiediamo al database di compiere una certa operazione. In particolare gli
omessa. chiederemo di creare una tabella con determinate caratteristiche. Aggiungiamo in fondo al file
.php invece viene inserito per motivi di sicurezza. Se qualcuno cercherà di visualizzare questa install.php:
pagina con il browser, vedrà solo una pagina vuota. Il webserver, infatti, grazie a quest'estensione,
prima di passare la pagina al browser, la farà elaborare dal modulo Php. Visto che non è previsto
nessun output, sul browser verrà visualizzata solo una pagina bianca. $query = "CREATE TABLE news (id INT (5) UNSIGNED not null AUTO_INCREMENT, titolo VARCHAR (255)
not null , testo TEXT not null , data INT (11) , autore VARCHAR (50) , mail VARCHAR (50) ,
PRIMARY KEY (id))";
Da notare inoltre che non abbiamo chiuso i tag Php: questo perché in seguito aggiungeremo altre
stringhe di configurazione.
Vediamo nel dettaglio che cosa chiede questa query:
CREATE TABLE news chiede la creazione di una tabella di nome news. In seguito, tra parentesi,
A questo punto abbiamo tutti i dati necessari per la connessione al database. Questa la possiamo
specificheremo le colonne di cui sarà composta e le loro caratteristiche.
realizzare attraverso la funzione mysql_connect. Creiamo quindi una pagina di nome install.php
id INT (5) UNSIGNED not null AUTO_INCREMENT: tutta questa parte indica le caratteristiche
con questo contenuto:
della prima colonna, cioè l'id. Questo dovrà essere un intero composto al massimo da cinque cifre.
Ovviamente potete specificare un valore diverso se pensate che si possano inserire più di 99.999
<? articoli. Un limite ragionevole, però, ci consente di non sprecare inutilmente spazio per la
include("config.inc.php"); memorizzazione di un numero eccessivamente grande. Visto che la numerazione parte da 1 il valore
$db = mysql_connect($db_host, $db_user, $db_password);
di id sarà sempre maggiore di zero e lo specifichiamo attraverso l'attributo UNSIGNED. In seguito
imponiamo che il campo id sia sempre definito e che quindi non possa restare vuoto attraverso not
Come potete notare il codice richiama dal file di configurazione i parametri del database, poi li null. Infine specifichiamo a MySQL che questo deve essere un campo AUTO_INCREMENT e che
utilizza per connettersi. quindi deve pensarci lui a incrementarlo ogni volta che inseriamo un nuovo record.
La funzione mysql_connect richiede diversi parametri, di cui generalmente si utilizzano i primi tre, titolo VARCHAR (255) not null è il campo che conterrà il titolo delle news. Gli assegnamo una
che sono proprio quelli che abbiamo richiesto all'utente. Se la connessione ha buon fine ci stringa di lunghezza massima di 255 caratteri. Se specifichiamo una stringa di tipo varchar
restituisce un identificatore alla connessione che noi memorizziamo in $db. Questa variabile la dobbiamo sempre specificare la lunghezza massima di cui sarà la stringa. Questa non potrà mai
utilizzeremo ogni volta che vorremo fare un'operazione sul database. Se la connessione non dovesse essere più di 255, quindi qui sfruttiamo al limite il tipo varchar. Anche il titolo dovrà sempre essere
andare a buon fine (per esempio se uno dei parametri fosse sbagliato) verrebbe restituito FALSE. specificato (not null).
Quindi dovremo verificare il buon esito della connessione aggiungendo di seguito: testo TEXT not null Come abbiamo visto in precedenza anche il testo è una stringa.
Ragionevolmente, però, il testo sarà più lungo del titolo e comunque più grande di 255 caratteri. Per
if ($db == FALSE)
questo genere di stringhe esistono i tipi TINYTEXT (max 255 caratteri), TEXT (max 65.535
die ("Errore nella connessione. Verificare i parametri nel file config.inc.php"); caratteri), MEDIUMTEXT (max 16.777.215 caratteri) e LONGTEXT (max 4.294.967.295 caratteri).
Abbiamo scelto il tipo TEXT, perché questo è il più vicino alle possibili caratteristiche dell'articolo
Grazie a queste righe se la connessione dovesse fallire, otterremmo il messaggio di errore e che verrà inserito, ma ovviamente si potrebbe utilizzare anche il tipo MEDIUMTEXT.
l'interruzione dell'esecuzione del programma. data INT (11) è il campo in cui memorizzeremo la data in formato timestamp. Questa è una delle
tante possibilità che abbiamo a disposizione. In particolare si tratta di un numero intero equivalente
Fatto tutto questo dobbiamo specificare su quale database vogliamo lavorare e verificare al numero di secondi trascorsi a partire dall'ora 00:00 del 1 gennaio 1970. Utilizziamo questo
nuovamente la riuscita dell'operazione: formato, perché ci risulterà più semplice ricavare la data in qualunque formato.
autore VARCHAR (50) , mail VARCHAR (50) Anche l'autore e l'indirizzo e-mail vengono

HTML.IT – Guide PHP 149 HTML.IT – Guide PHP 150


memorizzati in stringe, ma questa volta non sarà necessario specificarli. Quindi sarà possibile
inserire un articolo senza doverne indicare l'autore e/o il suo indirizzo e-mail. In questa lezione creeremo tutto ciò che ci manca prima di poter operare direttamente sul database.
PRIMARY KEY (id) Tramite questo comando indichiamo quale colonna sarà la chiave primaria, Creeremo tutte quelle pagine che richiedono in modo particolare codice html. Queste non
quindi quella che identificherà univocamente le righe. Automaticamente questo aggiunge al campo influenzeranno l'operatività dello script, ma solo la possibilità di personalizzarlo.
id la proprietà di unicità. Quindi se una riga ha un determinato numero di id, nessun'altra riga potrà
avere lo stesso id. Per questo creiamo una pagina con i codici html che caratterizzano la veste grafica. Questo file lo
chiamiamo top_foot.inc.php con questo contenuto:
Fin qui abbiamo raccolto i principali tipi di colonne, ma potrete trovarne un elenco completo nella
documentazione di MySQL sul sito ufficiale (www.mysql.com).
<? function top() { ?>
<HTML>
Una volta definita la query, possiamo comunicarla al database attraverso la funzione mysql_query: <HEAD>
<meta name=generator content="Script di freephp.it">
</HEAD>
<BODY bgcolor=ffffff text=000000>
if (mysql_query($query, $db)) <font face=verdana,tahoma,arial size=-1>
echo "L'installazione è stata eseguita correttamente"; <h1>FREEPHP.IT</h1><br>
else <? }
echo "Errore durante l'installazione";
function foot() { ?>
</body></HTML>
<? } ?>
Anche questa funzione restituisce FALSE in caso di errore, generalmente quando la query contiene
uno o più errori di sintassi.
top_foot.inc.php contiene quindi due funzioni, top() e foot(), che hanno il solo compito di generare
Al termine dello script è sempre bene terminare la connessione al database:
la prima e l'ultima parte delle pagine che verranno visualizzate. In questo esempio le due funzioni
sono ridotte al minimo, ma l'utente potrà agire direttamente su questo file per adattare lo script
mysql_close($db); all'aspetto del suo sito.
?>
Fatto questo vediamo subito come utilizzare questo file creando il modulo per l'inserzione degli
Con questo il file di installazione è pronto, quindi chiederemo all'utente di eseguirlo una sola volta articoli in un nuovo file di nome insert.php:
prima dell'utilizzo dello script.

Come detto in precedenza è possibile creare la tabella senza dover scrivere una pagina <?
include ("config.inc.php");
appositamente. Questo metodo, infatti, è utile quando si vuole distribuire lo script, ma se lo creiamo include ("top_foot.inc.php");
per uso personale risulta più veloce crearla in altri modi. Uno di questi l'abbiamo già introdotto ed è //intestazione
quello di aiutarsi con phpMyAdmin. top();
?>
In questo caso la creazione è molto semplice. Ci basta accedere al nostro phpMyAdmin, cliccare sul
nome del database nella colonna di sinistra e inserire la query nella casella di testo con intestazione <form method=post action=save.php>
Titolo:<br>
"Esegui una/più query SQL sul database": <input type=text size=40 name=titolo><br>
<br>
Data:<br>
<select name=giorno>
<?
CREATE TABLE news (id INT (5) UNSIGNED not null AUTO_INCREMENT, titolo VARCHAR (255) not null for ($i=1; $i<=31; $i++)
, testo TEXT not null , data INT (11) , autore VARCHAR (50) , mail VARCHAR (50) , PRIMARY KEY echo "<option value=$i>$i";
(id)) ?>
</select>
<select name=mese>
Cliccando su "Esegui" la tabella verrà creata automaticamente da phpMyAdmin. <option value=1>Gennaio
<option value=2>Febbraio
<option value=3>Marzo
L'ultimo metodo che introduciamo è quello di agire direttamente da una shell di MySQL. Anche <option value=4>Aprile
<option value=5>Maggio
questo metodo è relativamente semplice: basterà infatti inserire direttamente la query per la <option value=6>Giugno
<option value=7>Luglio
creazione della tabella: <option value=8>Agosto
<option value=9>Settembre
<option value=10>Ottobre
<option value=11>Novembre
mysql> CREATE TABLE news (id INT (5) UNSIGNED not null AUTO_INCREMENT, titolo VARCHAR (255) <option value=12>Dicembre
not null , testo TEXT not null , data INT (11) , autore VARCHAR (50) , mail VARCHAR (50) , </select>
PRIMARY KEY (id)); <select name=anno>
<option value=2001>2001
<option value=2002>2002
<option value=2003>2003
Ultime operazioni preliminari <option value=2004>2004
<option value=2005>2005

HTML.IT – Guide PHP 151 HTML.IT – Guide PHP 152


</select><br> Quindi verifichiamo che i campi titolo e testo non siano vuoti o non contengano solo spazi:
<br>
Autore:<br>
<input type=text size=40 name=autore><br>
<br>
E-mail:<br> elseif (trim($titolo) == "" OR trim($testo) == ""):
<input type=text size=40 name=mail><br> echo "I campi Titolo e Testo devono essere riempiti!";
<br>
Testo:<br>
<textarea cols=60 rows=40 name=testo></textarea><br> Abbiamo utilizzato la funzione trim che ha lo scopo di eliminare caratteri vuoti dall'inizio e dalla
<br>
Password:<br> fine della stringa. Questo eviterà di accettare stringhe composte da soli spazi e quindi senza
<input type=password size=40 name=pass><br> contenuto informativo.
<br> <input type=submit value=Invia> </form>
<?
// chiusura pagina A questo punto verifichiamo che le stringe non contengano caratteri particolari (come l'apice o le
foot(); virgolette), quindi questi li facciamo precedere dallo slash. Questo avviene automaticamente in
?>
php4, ma il nostro utente potrebbe utilizzare una versione precedente. Quindi inseriamo queste
righe che prima eliminano gli slash, poi li reinseriscono:
Come avrete notato le informazioni che richiediamo sono più o meno quelle che dovranno essere
inserite nel database. Le uniche differenze le potete notare nei campi giorno, mese, anno che nella
tabella sono memorizzati in un unico campo. Vedremo in seguito come raggruppare questi tre valori else:
in uno; il campo id non è presente, infatti verrà aggiornato automaticamente da MySQL; password $titolo = addslashes(stripslashes($titolo));
$autore = addslashes(stripslashes($autore));
serve per evitare che chiunque possa inserire un articolo. Il valore di questo campo verrà $mail = addslashes(stripslashes($mail));
$testo = addslashes(stripslashes($testo));
confrontato con una password scelta dall'utente. Per permettergli questo dobbiamo quindi
aggiungere ancora alcune righe al file config.inc.php:
Quando sarà il momento di visualizzare l'articolo, potremmo avere problemi con alcuni caratteri, in
particolare con quelli che vanno in contrasto con i tag html. Per questo conviene ancora sostituire il
//password per inserimento articoli carattere < con l'equivalente html &lt; e inserire nel testo i tag di fine riga:
$password = "";
?>

$titolo = str_replace("<", "&lt;", $titolo);


Visto che non avremo bisogno di altre informazioni dall'utente possiamo finalmente chiudere il tag $titolo = str_replace(">", "&gt;", $titolo);
$autore = str_replace("<", "&lt;", $autore);
php nel file config.inc.php e procedere all'inserimento degli articoli nel database. >< $autore = str_replace(">", "&gt;", $autore);
$testo = str_replace("<", "&lt;", $testo);
$testo = str_replace(">", "&gt;", $testo);
Inseriamo l'articolo nel database $testo = nl2br($testo);

Possiamo ora convertire la data in formato timestamp. Questa operazione è relativamente semplice
Finalmente possiamo dedicarci nuovamente al database. Vedremo adesso le operazioni da compiere grazie alla funzione mktime:
per il corretto inserimento dei dati nel database.

La prima operazione sarà quella di verificare che la password sia stata inserita correttamente. $data = mktime("0", "0", "0", $mese, $giorno, $anno);
Creiamo quindi la pagina save.php con le seguenti righe:
A questo punto prima di inserire i dati dobbiamo connetterci al database utilizzando le funzioni
viste in precedenza:
<? include("top_foot.inc.php");
include("config.inc.php");
top();
if ($pass != $password): $db = mysql_connect($db_host, $db_user, $db_password);
echo "Password errata"; if ($db == FALSE)
die ("Errore nella connessione. Verificare i parametri nel file config.inc.php");
mysql_select_db($db_name, $db)
Anche in questa pagina abbiamo richiamato la funzione top() che genera il codice html relativo or die ("Errore nella selezione del database. Verificare i parametri nel file
config.inc.php");
all'aspetto della pagina. Abbiamo poi confrontato la password inserita dall'utente, $pass, con quella
memorizzata in config.inc.php, $password. Quindi prepariamo una nuova query che questa volta dovrà occuparsi dell'inserzione:

Avvenuto il riconoscimento dobbiamo subito controllare che i dati necessari siano stati inserti.
$query = "INSERT INTO news (titolo, testo, data, autore, mail) VALUES ('$titolo', '$testo',
Questo eviterà fastidiosi errori da parte di MySQL. Infatti se noi non forniamo il contenuto dei '$data', '$autore', '$mail')";
campi not null, l'inserzione non può avvenire.
Anche questa query è composta da più parti:

HTML.IT – Guide PHP 153 HTML.IT – Guide PHP 154


INSERT INTO news indica che vogliamo inserire un nuovo elemento nella tabella news La $db = mysql_connect($db_host, $db_user, $db_password);
if ($db == FALSE)
parentesi che segue indica in quali colonne vogliamo specificare il valore da inserire. Nel nostro die ("Errore nella connessione. Verificare i parametri nel file config.inc.php");
caso specifichiamo tutte le colonne eccetto id, che verrà aggiornata automaticamente da MySQL. mysql_select_db($db_name, $db)
or die ("Errore nella selezione del database. Verificare i parametri nel file
Tramite VALUES indichiamo che ci apprestiamo a elencare i valori che vanno inseriti nelle config.inc.php");
colonne specificate in precedenza. Questi valori sono contenuti nella seconda parentesi e disposte
nello stesso ordine con cui abbiamo specificato le colonne. Tutti i valori devono essere indicati fra A questo punto veniamo alla query che dirà a MySQL di selezionare gli ultimi articoli in ordine
due apici che possono essere omessi solo nel caso di valori numerici. cronologico:
Questa query non richiede alcuna informazione al database, se non l'avvenuto inserimento, quindi
anche qui possiamo verificare se l'inserzione è avvenuta:
$query = "SELECT id,data,titolo FROM news ORDER BY data DESC LIMIT 0,5";

if (mysql_query($query, $db))
echo "L'articolo è stato inserito correttamente";
Questa query contiene molte delle possibilità che abbiamo a disposizione per la selezione di
else particolari righe dal database. Vediamole nel dettaglio:
echo "Erorre durante l'inserimento";
mysql_close($db); endif; SELECT id,data,titolo FROM news Questa prima parte è sempre necessaria quando vogliamo
foot();
?>
selezionare una o più righe. In particolare indica che a noi interessano solo le colonne id, data e
titolo della tabella news. Se avessimo voluto selezionare tutte le colonne, invece di indicarle tutte
avremmo potuto usare la scorciatoia SELECT * FROM news. Se utilizzassimo solo questa parte
Come potete notare la sintassi per l'inserimento è molto semplice e richiede solo qualche
della query, ci verrebbero restituite tutte le righe senza un particolare ordine. Questo perché non
accorgimento sul contenuto delle stringhe.
avremmo applicato nessun vincolo alla ricerca. I vincoli possono essere di diversi tipi e vengono
specificati in seguito.
Anche in questo caso abbiamo altre alternative per l'inserimento di nuove righe nel database.
ORDER BY data DESC Anche aggiungendo questo verranno selezionate tutte le righe, ma in
Possiamo per esempio utilizzare phpMyAdmin inserendo la query direttamente nella casella di testo
ordine di data. Visto che abbiamo aggiunto il parametro DESC la data verrà ordinata in modo
"Esegui una/più query SQL sul database":
decrescente. Quindi la prima riga della selezione sarà l'ultimo articolo inserito, la seconda sarà il
penultimo e così via.
INSERT INTO news (titolo, testo, data, autore, mail) VALUES ('primo articolo', 'Ecco il primo
LIMIT 0,5 è il vincolo che limita la selezione a sole cinque righe. I due parametri da fornire
articolo', '1002664800', 'freephp.it', 'mail@html.it'); rappresentano il primo elemento della selezione da cui partire (la numerazione parte da 0) e il
numero di righe da selezionare. Quindi aggiungendo questo vincolo limitiamo la selezione ai primi
La stessa query può essere utilizzata per inserire l'articolo direttamente da una shell MySQL. cinque elementi. Ci verranno quindi visualizzati solo gli ultimi 5 articoli inseriti.
Da notare che in questi due casi abbiamo dovuto inserire tutti i valori all'interno della query, senza
poter utilizzare le variabili come abbiamo fatto attraverso php. Questo può comportare alcuni Inviamo quindi la query al database e ne ricaviamo un identificatore nella variabile $result:
problemi dovendo inserire campi di grandi dimensioni, come per esempio il nostro testo. Inoltre
abbiamo dovuto calcolare manualmente la data in formato timestamp.
$result = mysql_query($query, $db);

Visualizziamo i titoli degli articoli


Attraverso $result, potremo ora ottenere le singole righe che ci vengono restituite dal database. Per
fare questo utilizziamo la funzione mysql_fetch_array:
Dopo aver popolato il database con un certo numero di articoli, possiamo occuparci di visualizzarne
i titoli. In questa lezione ci occuperemo quindi di mostrare gli ultimi articoli, ordinati per data.
while ($row = mysql_fetch_array($result))

Prima di tutto creiamo, come sempre, la pagina che dovrà contenere i titoli inseriti. Questa pagina la
chiamiamo index.php visto che sarà la prima pagina dello script: La funzione restituisce una sola riga del database in base alla selezione della query identificata da
$result. Una volta ottenuta la prima riga, sarà possibile ricavare la riga seguente richiamando
nuovamente la funzione mysql_fetch_array. Quando le rige saranno finite, la funzione restituirà
<? FALSE. Per ottenere questo effetto abbiamo utilizzato while che esegue mysql_fetch_array
include("top_foot.inc.php");
include("config.inc.php");
ripetutamente finché ci saranno righe da visualizzare. Da notare che se il nostro database contiene
top(); meno di cinque articoli, non abbiamo nessun problema, né per quanto riguarda la query, né per la
visualizzazione. In seguito dovremo specificare in un blocco cosa vogliamo fare con la riga
Visto che anche qui opereremo sul database dovremo come sempre connetterci utilizzando le selezionata, prima di passare alla successiva:
funzioni già viste in precedenza:
{ echo "<a href=\"view.php?id=$row[id]\">" . date("j/n/y", $row[data]) . " -
$row[titolo]</a><br>"; }

HTML.IT – Guide PHP 155 HTML.IT – Guide PHP 156


$query = "SELECT titolo,testo,data,autore,mail FROM news WHERE id='$id'";
Il blocco può sembrare complicato, ma in realtà non presenta grandi difficoltà. Prima di spiegarlo
nel dettaglio, notiamo che i valori dei tre campi selezionati sono memorizzati nell'array $row. Visto che anche in questo caso dobbiamo selezionare una o più righe dalla tabella news, dovremo
usare il comando SELECT e in particolare vogliamo avere tutte le colonne, tranne id. Tutto questo
<a href=\"view.php?id=$row[id]\"> questa parte crea il link che permette all'utente di cliccare sul viene indicato con SELECT titolo,testo,data,autore,mail FROM news.
titolo per poter leggere tutto il contenuto. Questo link porta alla pagina view.php, che creeremo in In questo caso abbiamo inserito un vincolo diverso, cioè abbiamo specificato tramite WHERE
seguito, passandogli come parametro l'id dell'articolo. Questo valore cambia da articolo ad articolo, id='$id' che ci interessano solo gli articoli che hanno id esattamente uguale al valore contenuto nella
quindi dovremo leggerlo dal database. Per questo abbiamo specificato nella query che ci interessava variabile $id. Facendo così selezioniamo solo l'articolo di cui è stato cliccato il titolo nella pagina
conoscere anche l'id dell'articolo. Quindi lo stampiamo sotto forma di $row[id]. index.php.
date("j/n/y", $row[data]) è una funzione Php che in base a una data in timestamp (nel nostro caso
memorizzato in $row[data] crea la data nel formato g/m/aa. Questa la visualizziamo accanto al Non ci resta che ricavare i dati e visualizzarli:
titolo.
- $row[titolo]</a><br> dopo aver inserito un delimitatore (nel nosto caso il meno -), visualizziamo
il titolo, chiudiamo il tag del link e andiamo a capo. $result = mysql_query($query, $db);
$row = mysql_fetch_array($result);
$data = date("j/n/y", $row[data]);
Dopo aver visualizzato i cinque titoli, possiamo quindi chiudere la pagina: echo "<b>$row[titolo]</b><br><br>";
echo "$row[testo]<br><br>";
if ($row[mail] != "") echo "$data, <a href=mailto:$row[mail]>$row[autore]</a><br>"; else echo
"$data, $row[autore]<br>";
mysql_close($db); foot();
?>
In fondo all'articolo inseriamo due link: il primo porterà nuovamente alla prima pagina (index.php),
A questo punto creeremo la pagina che ci permetterà di leggere i contenuti degli articoli. il secondo aprirà una nuova pagina in cui verranno visualizzati i titoli di tutti gli articoli. Questa
pagina si chiamerà all.php e la creeremo in seguito:
Visualizziamo l'articolo completo
echo "<br><a href=index.php>Torna alla pagina iniziale</a><br>";
echo "<a href=all.php>Visualizza tutti gli articoli</a><br>";
Abbiamo appena visto come visualizzare i titoli degli ultimi articoli, attraverso i quali possiamo
accedere ai testi completi. Vediamo quindi come possiamo accedere al contenuto di un articolo a Infine chiudiamo la connessione al database e inseriamo la parte finale della pagina:
partire dal solo id. Creiamo quindi una nuova pagina che chiamiamo view.php che ha come unico
scopo quello di visualizzare il testo completo di un articolo selezionato in precedenza nella pagina
index.php. Anche a questa pagina diamo l'aspetto predefinito grazie alla funzione top(): mysql_close($db);
foot();
?>

<? include("top_foot.inc.php"); include("config.inc.php"); top();


Elencare i titoli di tutti gli articoli
Aggiungiamo inoltre la parte relativa alla connessione a MySQL:
Nella precedente lezione abbiamo inserito nella pagina view.php un link attraverso il quale sarà
$db = mysql_connect($db_host, $db_user, $db_password); possibile vedere i titoli di tutti gli articoli. L'operazione sarebbe estremamente semplice nel caso in
if ($db == FALSE) cui il numero di articoli è piccolo, ma quest'ipotesi risulta essere eccessivamente restrittiva.
die ("Errore nella connessione. Verificare i parametri nel file config.inc.php");
mysql_select_db($db_name, $db) Vedremo quindi come visualizzare gli articoli suddivisi automaticamente in più pagine.
or die ("Errore nella selezione del database. Verificare i parametri nel file
config.inc.php");
Iniziamo, come sempre, a creare la pagina all.php e vi inseriamo le parti iniziali relative ad aspetto
grafico e connessione al database:
Da notare a questo punto che attraverso il link che abbiamo creato nella pagina index.php, abbiamo
passato un solo parametro. Questo parametro è l'id che caratterizza un solo particolare articolo nel
database. Questo parametro resterà memorizzato nella variabile $id. Grazie a questa possiamo <?
eseguire una query che ci permetta di ricavare il contenuto e le caratteristiche dell'articolo. In questo include("top_foot.inc.php");
include("config.inc.php");
caso la query sarà molto simile a quella vista in precedenza. Addirittura, visto che grazie all'id top();
esatto richiederemo un solo articolo, non avremo bisogno di tutte le opzioni di ordinamento come $db = mysql_connect($db_host, $db_user, $db_password);
nel caso della pagina index.php. La query da aggiungere in view.php sarà quindi: if ($db == FALSE)
die ("Errore nella connessione. Verificare i parametri nel file config.inc.php");
mysql_select_db($db_name, $db)
or die ("Errore nella selezione del database. Verificare i parametri nel file

HTML.IT – Guide PHP 157 HTML.IT – Guide PHP 158


config.inc.php"); Prima di inserire il link alla pagina successiva, creiamo una sorta di indice con tutte le pagine
elencate e numerate. Questo permetterà all'utente di accedere rapidamente ad articoli distanti da
Il primo articolo da visualizzare sarà memorizzato in una variabile che passeremo alla pagina con il quelli attualmente visualizzati. Prima di tutto, però, abbiamo bisogno di sapere quanti sono gli
metodo get. Se questa non viene passata assumiamo questo valore uguale a zero, quindi articoli inseriti nel database. Per fare questo possiamo dire a MySQL di contare gli elementi inseriti
visualizzeremo gli ultimi articoli. Impostiamo inoltre il numero di articoli da visualizzare nella tabella attraverso una funzione specifica. Infatti attraverso la query possiamo richiedere al
contemporaneamente a 20: database di eseguire alcune operazioni, senza doverle fare tramite php. La query quindi sarà di
questo tipo:

if (!isset($start) OR $start<0)
$start=0;
$step = 20; $query = "SELECT count(*) AS tot FROM news";

La query che vedremo adessso sarà molto simile a quella già vista in precedenza per visualizzare gli Come si può notare non abbiamo selezionato alcuna colonna della tabella, ma abbiamo scelto di
ultimi 5 articoli: farci restituire una tabella con una sola colonna e una sola riga. La riga conterrà il numero di righe
che rispondono ai criteri di selezione indicati. Nel nostro caso l'unico vincolo inserito è quello di
appartenere alla tabella news (FROM news). Questo ci permetterà di ottenere il numero di articoli
$query = "SELECT id,data,titolo FROM news ORDER BY data DESC LIMIT $start,$step"; inseriti nella tabella. Tramite AS tot abbiamo indicato che nella tabella che otteniamo la colonna
che contiene la somma si deve chiamare tot. Questo non è necessario, ma può essere utile nel caso
L'unica differenza che si nota è il fatto che i parametri del vincolo LIMIT sono variabili. $step è in cui si utilizzano le funzioni.
impostato a priori e sempre fisso, $start varia invece a seconda del valore passato alla pagina.
A questo punto visualizziamo l'elenco dei titoli come abbiamo già fatto nella prima pagina: Per ottenere il risultato utilizziamo i metodi usati fin'ora:

$result = mysql_query($query, $db); $result = mysql_query($query, $db);


while ($row = mysql_fetch_array($result)) $row = mysql_fetch_array($result);
{ echo "<a href=\"view.php?id=$row[id]\">" . date("j/n/y", $row[data]) . " -
$row[titolo]</a><br>"; }
Quindi il numero totale di articoli sarà contenuto in $row[tot].
A questo punto vediamo in quante pagine sarà suddiviso il risultato.
Infine dovremo creare i link per accedere alle pagine successive. Per posizionare i link nella pagina,
li inseriamo all'interno di una tabella:
$pages = intval(($row[tot]-1) / $step)+1;

?>
<br><br> Vediamo come abbiamo ottenuto questa formula: prima di tutto prendiamo in consderazione il
<table width=90% border=0><tr>
<td width=20% align=left> metodo più intuitivo per ottenere il risultato: $row[tot] / $step. Facendo così si ottiene il numero di
<? pagine totali a partire da zero (che indica la prima pagina). L'unico problema sorge quando ci
troviamo al limite, per esempio quando $row[tot] è uguale a 20. In questo caso dovremmo ottenere
Abbiamo così creato una tabella che conterrà tre celle. La prima, quella più a sinistra, conterrà il 0, invece otteniamo 1. Per questo abbiamo modificato la formula in ($row[tot]-1) / $step. Noi, però,
link per tornare alla pagina precedente (se esiste): vogliamo ottenere un risultato intero, quindi tronchiamo il valore dopo la virgola tramite la funzione
intval. Infine aggiungiamo 1 per far partire la numerazione da 1 e non da 0.
if ($start>0)
{ $start_back = $start - $step; A questo punto possiamo creare i link, uno per ogni pagina, all'interno della cella centrale della
echo "<a href=all.php?start=$start_back>precedenti</a>"; tabella:
}
?>
</td>
<?
?>
<td width=60% align=center>
<?
Prima di tutto abbiamo verificato di non trovarci alla prima pagina. Se $start è maggiore di zero, for ($i=0; $i<$pages AND $i<20; $i++)
significa, infatti, che non stiamo visualizzando l'ultimo articolo inserito, ma solo articoli più vecchi. { $start_page = $i * $step;
echo "<a href=all.php?start=$start_page>" . ($i+1) . "</a> ";
Se questa condizione si verifica, creiamo una variabile $start_back che conterrà il primo articolo }
?>
da visualizzare nella pagina precedente. Ovvimanete dobbiamo "arretrare" nella lista di venti </td>
elementi. In seguito visualizziamo il link vero e proprio che passa $start_back come parametro che
verrà ricevuto da all.php con il nome start. Da notare che la pagina richiama se stessa, passando Abbiamo inserito un ciclo for che termina nel caso una delle due condizioni sia vera. La prima
però ogni volta la variabile $start con valori differenti. indica che abbiamo elencato tutte le pagine possibili, oltre le quali non ci sono risultati da

HTML.IT – Guide PHP 159 HTML.IT – Guide PHP 160


visualizzare. La seconda limita l'indice alla ventesima pagina, per evitare di indicare un elenco <?
include("top_foot.inc.php");
eccessivamente lungo nel caso gli articoli siano tanti. include("config.inc.php");
top();

Infine possimao inserire il link alla pagina successiva. Prima di inserirlo dobbiamo verificare che $db = mysql_connect($db_host, $db_user, $db_password);
if ($db == FALSE)
questa possa esistere e che non porti a pagine vuote. Per questo ci verrà utile il valore di $row[tot] die ("Errore nella connessione. Verificare i parametri nel file config.inc.php");
trovato in precedenza. mysql_select_db($db_name, $db)
or die ("Errore nella selezione del database. Verificare i parametri nel file
config.inc.php");

<td width=20%>
<? Per prima cosa dovremo suddividere la stringa nelle chiavi da ricercare. Noi supporremo che le
if ($start + $step < $row[tot])
{ $start_next = $start + $step;
diverse chiavi siano suddivise da virgole. Quindi le inseriremo in un array di nome $keys:
echo "<a href=all.php?start=$start_next>successivi</a>";
}
?>
</td> $keys = explode (",", $chiave);
</tr></table>
<br>
<? Tramite questa operazione abbiamo spezzato la stringa $chiave in corrispondenza di ogni virgola e
inserito i frammenti all'interno dell'array $keys.
Fatto questo inseriamo un link al motore di ricerca e chiudiamo la pagina: A questo punto possiamo creare la query. In questo caso non possiamo utilizzare una semplice
uguaglianza, ma dobbiamo specificare che le celle devono solo contenere le parole. Vedremo quindi
un nuovo metodo:
echo "<a href=search.php>Cerca negli articoli</a>";
foot();
?>
$query = "";
reset ($keys);
Il motore di ricerca while (list(,$parola) = each ($keys))
{ $parola = trim($parola);
if ($parola != "")
$query .= "titolo LIKE '%$parola%' OR testo LIKE '%$parola%' OR autore LIKE '%$parola%' OR ";
}
Finalmente in questa lezione sfruttiamo fino in fondo le potenzialità del database. Inseriremo un $query .= "0";
motore di ricerca che, in base alle parole chiave inserite dall'utente, cercherà gli articoli che le
contengono. Iniziamo come sempre crando la pagina search.php con l'intestazione: Prima di tutto abbiamo definito $query una stringa vuota. In seguito attraverso la seconda e la terza
riga abbiamo indicato che vogliamo manovrare un solo elemento dell'array alla volta. Avremmo
potuto usare foreach e semplificare il codice, ma questa funzione esiste solo a partire dalla versione
<?
include("top_foot.inc.php");
4 di Php.
include("config.inc.php"); Ogni elemento dell'array sarà quindi disponibile uno alla volta con il nome $parola. Da questa
top();
?> eliminiamo gli spazi a sinistra e a destra tramite trim e, se la parola non è vuota, creiamo la query.
Tutto quello che vedete tra le virgolette, verrà aggiunto in fondo alla query già esistente.
Quindi dovremo creare un form che contenga un campo di testo per immettere le parole da cercare: Prendiamo per il momento in considerazione il caso in cui l'utente abbia immesso due sole parole
chiave e vediamo quali sono le operazioni che vengono compiute passo passo. Consideriamo per
esempio che le parole inserite siano "articolo" e "freephp":
<form method=post action=result.php> - Prima di tutto viene definita la query vuota: $query = "";
<input type=text name=chiave><input type=submit value=cerca><br>
</form>
- Con le prime due righe si ottiene la prima parola ("articolo") all'interno di $parola
- Eliminiamo gli spazi alle estremità di "articolo" che in questo caso resta tale e quale
- Verifichiamo che $parola non sia vuota.
e infine chiudiamo la pagina:
- Modifichiamo la stringa $query che diventerà "titolo LIKE '%articolo%' OR testo LIKE
'%articolo%' OR autore LIKE '%articolo%' OR "
<? - Passimao alla parola successiva, quindi $parola assume il valore "freephp".
foot(); - Eliminiamo gli spazi e verichiamo che non sia vuota
?>
- Aggiungiamo la stringa in fondo alla query che diventa: "titolo LIKE '%articolo%' OR testo LIKE
'%articolo%' OR autore LIKE '%articolo%' OR titolo LIKE '%freephp%' OR testo LIKE
A questo punto possiamo venire alla pagina result.php che avrà il compito di elaborare la stringa '%freephp%' OR autore LIKE '%freephp%' OR "
inserita dall'utente: - Le parole chiave sono finite, ma la stringa finisce ancora con un OR. Per annullare il suo effetto
aggiungiamo in fondo uno 0. Avremmo potuto eliminare l'OR, ma avremmo dovuto fare una serie
di verifiche. Risulta invece molto più semplice e immediato usare questa scorciatoia per

HTML.IT – Guide PHP 161 HTML.IT – Guide PHP 162


"neutralizzare" il suo effetto senza eliminarlo. ci obbliga a specificare anche tutti i precedenti, ci troviamo costretti quindi a specificare tutti e tre i
parametri quando lavoriamo on line. Tuttavia se si lavora in locale e non si ha indicato nessuna
Fatto tutto questo possimao inserire la prima parte della stringa: password al proprio MySQL (quello in locale), la connessione funziona anche senza i tre parametri.
Questo è un frequente caso di errore quando si prova uno script in locale e funziona correttamente,
ma una volta portato on line su uno spazio preso in hosting riceviamo una serie di errori.
$query = "SELECT id, titolo, data FROM news WHERE " . $query;
Dopo la connessione selezioniamo un database:
Quindi la stringa diventerà:
"SELECT id, titolo, data FROM news WHERE titolo LIKE '%articolo%' OR ... OR autore LIKE
'%freephp%' OR 0" mysql_select_db ($database_name, $db);
Come vedete LIKE ha sostituito l'operatore di uguaglianza che abbiamo usato in tutte le altre query.
Prendiamo in considerazione un singolo blocco LIKE: titolo LIKE '%articolo%' Questa funzione può sembrare inutile, visto che nella maggior parte dei casi abbiamo a disposizione
LIKE indica che titolo deve contenere articolo e non che deve essere uguale a titolo. un solo database. Tuttavia non sempre è così, anzi, generalmente un singolo MySQL contiene
% all'inizio indica che prima di "articolo" possono comparire altri caratteri. Quindi "articolo" non diversi database, ma noi abbiamo accesso a uno solo di questi. Ovviamente dobbiamo specificare il
deve necesariamente trovarsi all'inizio della cella. Stessa cosa indica il simbolo % alla fine. Quindi primo parametro che conterrà una stringa con il nome del database che ci è stato assegnato dal
inserendo questi due simboli abbiamo indicato di verificare se la cella titolo contiene la parola gestore. Il secondo parametro indica la connessione attiva e può essere omesso, in quanto Php
"articolo" in una qualunque posizione: all'inizio, al centro o alla fine. considera come identificatore di default l'ultimo creato. Visto che noi ne creiamo uno solo per
pagina, non avrà problemi a identificare l'unico giusto. In realtà è possibile specificare il database in
Una volta definita la query possiamo inviarla a MySQL ed elencare i risultati: seguito ogni volta che invieremo una query, ma questa procedura è sconsigliata dai creatori di PHP.

In seguito prepariamo la query e la inviamo al database:


$result = mysql_query($query, $db);
while ($row = mysql_fetch_array($result))
{ echo "<a href=\"view.php?id=$row[id]\">" . date("j/n/y", $row[data]) . " -
$row[titolo]</a><br>"; } $result = mysql_query ($query, $db);

Infine, come sempre, chiudiamo la pagina: Anche in questo caso possiamo omettere l'identificatore $db. Tutte le query possono essere
suddivise in due categorie. La prima contiene tutte quelle che richiedono al database di restituirci
determinati dati. Per esempio possiamo richiedere il contenuto di determinate righe di una tabella o
foot()
?> il numero di record presenti in un'altra tabella. La seconda categoria comprende le query che
richiedono a MySQL di apportare modifiche al database: inserimento di un record, eliminazione di
una tabella, modifica di un insieme di record ecc.
Lo schema utilizzato
Per tutte le query della seconda categoria non avremo bisogno di creare l'identificatore $result, visto
che le modifiche vengono apportate subito.
Vedremo adesso di riassumere le diverse modalità di gestione del database che abbiamo usato. In
Nel primo caso invece avremo bisogno di ricavare le informazioni che abbiamo richiesto in
particolare si nota che alcuni passaggi sono sempre presenti e devono presentare determinate
precedenza. Questo lo facciamo usando la funzione:
caratteristiche. Faremo particolarmente caso a quelle funzioni che devono essere utilizzate e quali
parametri devono essere specificati e quali invece possono essere omessi.
$row = mysql_fetch_array ($result, $result_type);
Abbiamo visto che prima di fare qualunque operazione con MySQL bisogna creare una
connessione. Con questa indichiamo allo script dove si trova il nostro database e quali dati Tramite questa funzione memorizziamo i risultati nell'array $row. $row può essere associativo con
utilizzare. Come abbiamo visto la funzione è: indice incrementale o entrambi. Questo lo scegliamo con in secondo parametro che può essere
omesso. Vista la ridotta utilità di questa opzione, scegliamo di non utilizzare questo parametro.
$db = mysql_connect ($server, $username, $password);
Per poter ottenere tutte le righe richieste ci ricordiamo inoltre di inserire mysql_fetch_array
all'interno di un ciclo while in modo tale da richiamarla finché non abbiamo esaurito i risultati.
Questa funzione è sempre necessaria e deve essere, ovviamente, configurata correttamente tramite i
Dopo aver eseguito tutte le operazioni, alla fine della pagina ci ricordiamo di chiudere la
tre parametri indicati sopra. Tutti e tre i parametri possono essere omessi. In questo caso i valori di
connessione al database:
default saranno localhost:3306 per il server (:3306 indica il numero della porta), username sarà
quello del proprietario del database e la password sarà vuota. Visto che generalmente la password
viene modificata per prima cosa dal gestore del server, risulterà impossibile effettuare una mysql_close ($db);
connessione senza indicare almeno gli ultimi due parametri. Ma visto che specificare un parametro

HTML.IT – Guide PHP 163 HTML.IT – Guide PHP 164


fondo al comando possiamo aggiungere FIRST se vogliamo che la colonna inserita sia la prima o
Anche in questo caso possiamo omettere il parametro. Anzi, possiamo addirittuta evitare di inserire AFTER column_name per asseganre una posizione diversa. Se non specifichiamo niente la colonna
la funzione stessa, come abbiamo già fatto in precedenza, visto che tutte le connessioni vengono verrà inserita in ultima posizione.
chiuse automaticamente alla fine della pagina. Per fare un esemio inseriamo fra id e nome la colonna cognome:

La struttura della query ALTER TABLE my_table ADD COLUMN cognome VARCHAR(20) AFTER id
Allo stesso modo possiamo eliminare una colonna:

ALTER TABLE my_table DROP COLUMN cognome


Vedremo adesso com'è costruita generalmente una query da inviare al database. Abbiamo visto
nella precedente lezione una suddivisione molto generica fra query che richiedono informazioni e Possiamo infine modificare il tipo di una colonna:
query che invece indicano modifiche da apportare. In questa sezione faremo una distinzione più ALTER TABLE tbl_name MODIFY colonna new_type
precisa indicando le query di uso più comune. Ovviamente non prenderemo in considerazione tutte In particolare per modificare la colonna nome da VARCHAR(20) a VARCHAR (30):
ALTER TABLE my_table MODIFY nome VARCHAR(30)
le possibili sintassi, che potete però trovare nella documentazione ufficiale sul sito
www.mysql.com.
Vediamo quindi le principali query per gestire il contenuto di un database:
Innanzi tutto esaminiamo le query che vengono utilizzate per gestire la struttura del database:
INSERT:
CREATE: Una volta creato un database dovremo popolarlo inserendo i record:
Tramite questo comando possiamo creare database e tabelle. Nel primo caso dobbiano solamente INSERT INTO tbl_name (cols) VALUES (values)
indicare il nome: CREATE DATABASE IF NOT EXISTS db_name Anche di questa query abbiamo già visto la struttura nelle precedenti lezioni.
db_name indica ovviamente il nome che vogliamo assegnare al database, mentre l'opzione
facoltativa IF NOT EXISTS evita che venga visualizzato un errore nel caso la tabella esisa già. Da UPDATE:
notare che nella maggior parte dei casi di hosting, ci viene assegnato un database dal gestore e non Tramite questa funzione possiamo modificare alcuni valori di determinate righe:
possiamo crearne altri. Tuttavia questa possibilità può essere comoda se possiamo gestire UPDATE tbl_name SET col_name=expr WHERE where_definition
direttamente MySQL. Questa notazione è piuttosto generale: tbl_name indica come sempre il nome della tabella,
Per creare una tabella utilizziamo invece il generico comando: col_name=expr indica la modifica da apportare a una determinata colonna e where_definition
CREATE TABLE IF NOT EXISTS tbl_name (definizioni) indica le condizioni che si devono verificare in una riga perché questa possa essere modificata.
Anche qui abbiamo la possibilità di usare l'opzione IF NOT EXISTS. Le definizioni indicano i tipi di Per fare un esempio, possiamo assegnare il nome "Mario" a tutte le persone che hanno il cognome
colonne di cui deve essere composta la tabella e la chiave primaria che verrà utilizzata. Abbiamo "Rossi":
già visto queste caratteristiche nelle prime lezioni di questa guida, quindi non ci tornerò un'altra
UPDATE my_table SET nome='Mario' WHERE cognome='Rossi'
volta.
Per fare un po' di esempi, una query per creare un database chiamato "mio_db" potrebbe essere: Ovviamente possiamo indicare anche più condizioni tramite gli operatori OR o AND e possimao
indicare più modifiche. Queste possono essere sotituite da funzioni. Per esempio possiamo anche
CREATE DATABASE IF NOT EXISTS my_db creare la query:
Una volta impostate le operazioni su quel database, vi creiamo una tabella (my_table) nella quale
UPDATE my_table SET id=id*1000, nome='Mario' WHERE (cognome='Rossi' OR cognome='Bianchi') AND
inseriamo due colonne: la prima un contatore id e la seconda una colonna nome (stringa di 20 id>5
caratteri): Questa query più complicata ha lo scopo di cambiare il nome in Mario e di moltiplicare la colonna
CREATE TABLE my_table (id INT UNSIGNED NOT NULL AUTO_INCREMENT, nome varchar(20), primary
key(id)) id per 1000. A dire il vero questa operazione è pericolosa: id è chiave primaria e moltiplicare per
mille si potrebbe ottenere un id già utilizzato. In questo caso avremmo un errore. La modifica viene
DROP: apportata solo alle righe in cui cognome sia "Rossi" o "Bianchi" e comunque id sia maggiore di 5.
Così come abbiamo creato database e tabelle, li possiamo eliminare: Tutta questa query non ha molto senso pratico, ma mostra bene parecchie possibilità...
DROP DATABASE IF EXISTS db_name
DROP TABLE IF EXISTS tbl_name DELETE:
E' consigliata la massima prudenza nell'usare questi comandi, visto che elminando un database o Per eliminare una o più righe ci basta indicare le condizioni che devono verificarsi:
una tabella si elimina anche tutto il loro contenuto! Anche in questo caso IF EXISTS è facoltativo. DELETE FROM tbl_name WHERE condizioni
Anche qui possiamo utilizzare condizioni composte:
ALTER: DELETE FROM my_table WHERE id<1000 AND (nome='Mario' OR nome='Luigi')
Una volta creata una tabella, possiamo modificarla inserendo, rimuovendo o modificarndo colonne:
ALTER TABLE tbl_name ADD COLUMN definizione
Con una query di questo tipo aggiungiamo la colonna specificata in "definizione" alla tabella SELECT:
"tbl_name". La sintassi di "definizione" è uguale a quella usata per la creazione della tabella. In Questo genere di query è quella che probabilmente utilizzerete più spesso, in quanto vi servirà per

HTML.IT – Guide PHP 165 HTML.IT – Guide PHP 166


ricavare i dati precedentemente inseriti in una tabella: titolo VARCHAR (255) not null ,
testo TEXT not null ,
SELECT colonne FROM tbl_name WHERE condizioni opzioni data INT (11) ,
In precedenza abbiamo già visto anche questa query, ma sarà meglio fare un ripasso: nome VARCHAR (50) ,
PRIMARY KEY (id))";
colonne indica tutte le colonne di cui vogliamo il valore. Queste possono anche essere operazioni, $query2 = "CREATE TABLE autori (nome VARCHAR (50) not null,
mail VARCHAR(50),
come vedremo nell'esempio. PRIMARY KEY (nome))";
condizioni sono le condizioni che devono verificarsi, perché una riga sia visualizzata. Queste sono
if (mysql_query($query1, $db) AND mysql_query($query2, $db))
dello stesso tipo di quelle viste nei casi UPDATE e DELETE. echo "L'installazione è stata eseguita correttamente";
else
opzioni ci serviranno per esempio per ordinare le righe. echo "Errore durante l'installazione:<br>" . mysql_error();
Per fare un esempio:

SELECT id, cognome, nome, count(*) AS tot FROM my_table WHERE cognome='Rossi' ORDER BY nome,
Questa parte va ovviamente inserita fra l'apertura e la chiusura della connessione. Quello che
id DESC abbiamo fatto è creare due query per la creazione delle due tabelle e inviarle entrambe tramite due
Con questa query otterremo una tabella composta da quattro colonne. Le prime tre saranno quelle chiamate a mysql_create.
contenute nel database, mentre l'ultima conterrà un valore uguale per tutte le righe, cioè il numero
di righe selezionate. Se per esempio nel database ci sono 32 persone di cognome 'Rossi', allora A questo punto dovremo modificare l'inserimento dell'articolo. La pagina insert.php resta
quella colonna conterrà 32 volte il valore 32. Infine abbiamo indicato che le righe devono essere ovviamente uguale, visto che le modifiche che stiamo apportando dovrebbero risultare trasparenti
ordinate per nome e in caso di nomi uguali per id decrescente. all'utente. Modifichiamo quindi la pagina save.php in modo da inserire le informaioni nelle due
Se vogliamo per esempio sapere tutti i cognomi presenti nel database usiamo l'opzione GROUP tabelle.
BY, grazie alla quale le righe vengono raggruppate in base al loro contenuto in una colonna: Dopo le righe relative alla connesione al database sostituiamo tutto il codice rimanente con questo:

SELECT cognome FROM my_table GORUP BY cognome


Utilizzando quest'opzione eviteremo di avere cognomi uguali ripetuti. $query1 = "INSERT INTO news (titolo, testo, data, nome) VALUES ('$titolo', '$testo', '$data',
'$autore')";
Come condizione possiamo anche utilizzare il metodo di confronto LIKE. Per esempio posso creare $query2 = "INSERT IGNORE INTO autori (nome, mail) VALUES ('$autore', '$mail')";
la query: if (mysql_query($query1, $db) AND mysql_query($query2, $db))
echo "L'articolo è stato inserito correttamente";
else
SELECT * FROM my_table WHERE cognome LIKE 'Ro%' OR nome LIKE '%ri%' echo "Erorre durante l'inserimento
L'asterisco indica che voglio selezionare tutte le colonne. In seguito ho indicato di scegliere tutte le $query";
endif;
righe in cui il cognome inizi con "Ro" e finisca con qualunque sequenza di caratteri (indicata con il foot();
?>
simbolo %),oppure il cui nome contenga "ri" (e possa quindi iniziare e finire con qualunque
stringa).
Anche in questo caso abbiamo utilizzato due query per la modifica di due tabelle. In pratica le
Miglioriamo lo script gestiamo come se non avessero nulla a che fare l'una con l'altra; in effetti MySQL non vede la
relazione fra queste tabelle. Abbiamo specificato IGNORE in modo da evitare di ottenere un errore
nel caso l'autore sia già presente nella tabella autori.
Il nostro script per gli articoli è finalmente funzionante, ma così com'è non è perfetto. La prima cosa
che dovrebbe saltare all'occhio è che le caselle autore ed e-mail sono spesso ripetute. In pratica a A questo punto non ci resta ch vedere come visualizzare le informazioni in modo tale da specificare
scrivere gli articoli sono generalmente un numero ristretto di persone e soprattutto a ogni persona che quando un articolo è scritto da una certa persona, vogliamo che sia visualizzato proprio il suo
corrisponde sempre lo stesso indirizzo e-mail. Ci ritroviamo quindi con una serie di informazioni indirizzo mail. Per fare questo abbiamo diversi metodi che vedremo nella prossima lezione.
che vengono ripetute più volte. Per risolvere questo problema divideremo il nostro archivio di
notizie su due tabelle e vedremo come gestirle. Gestire due tabelle come una sola

Abbiamo parlato all'inizio di questa guida delle relazioni che possono essere definite nei database
relazionali. Ne vedremo un esempio pratico proprio in questa sezione. Il nostro scopo sarà quello di unire due tabelle (news e autori) e farle diventare una sola, in modo da
Innanzi tutto vediamo come devono essere suddivise le tabelle che utilizzeremo. Quello che trattarla come abbiamo fatto nella prima versione dello script. Per fare questo usiamo particolari
dovremo fare sarà spezzare la tabella news in due parti: prenderemo le colonne autore e mail e ne sintassi MySQL specifiche per questo scopo.
faremo una tabella nuova che chiameremo autori. Poi dovremo creare una relazione fra la prima e la
seconda tabella. Nella parte rimanente della tabella news aggiungeremo una colonna autore che mi Quello che dobbiamo fare è modificare la query in view.php in modo tale da ottenere l'effetto sopra
farà corrispondere ogni riga della tabella a una sola riga della tabella autori. Dovremo quindi descritto. Il metodo più semplice è quello di selezionare le singole colonne:
modificare il file install.php in questo modo:
$query = "SELECT news.titolo, news.testo, news.data, news.nome AS autore, autori.mail FROM
news, autori WHERE news.nome = autori.nome AND id='$id'";
$query1 = "CREATE TABLE news (id INT (5) UNSIGNED not null AUTO_INCREMENT,

HTML.IT – Guide PHP 167 HTML.IT – Guide PHP 168


$query = "INSERT INTO my_table (id, nome, cognome) VALUES ('', 'Luigi', 'Bianchi')";
mysql_query($query);
In questo modo abbiamo specificato di voler selezionare tutte le colonne di news e la sola colonna $num = mysql_insert_id();
mail di autori (autori.mail). Abbiamo poi indicato che la colonna nome verrà gestita con l'alias echo "Luigi Rossi ha id: $num";

autore, così non avremo bisogno di modificare tutto il codice che segue la query. Inoltre abbiamo
specificato che il nome in news deve essere uguale al nome in autori (WHERE news.nome = mysql_list_tables($nome_database)
autori.nome). In questo modo otteniamo una tabella con le stesse caratteristiche di quella che Restituisce una lista contenente i nomi delle tabelle nel database specificato.
abbiamo utilizzato in precedenza. Esempio:

$result = mysql_list_tables($my_db);
Con il metodo che abbiamo visto otteniamo l'unione di due tabelle tramite una relazione, ma questa while (list($table) = mysql_fetch_array($tables))
è una scorciatoia per semplificare il codice. Normalmente per ottenere l'unione di due tabelle si usa echo "$table
";
JOIN:
mysql_escape_string($stringa)
$query "SELECT titolo, testo, data, news.nome AS autore, mail FROM news LEFT JOIN autori ON Tramite questa funzione vengono inseriti i caratteri di escape nella stringa. Per fare un esempio, un
news.nome = autori.nome WHERE id='$id'"; utente potrebbe inserire in un form il suo username e password per visualizzare i suoi dati. Tramite
alcuni accorgimenti potrebbe inserire dei valori particolari in modo tale da visualizzare i dati di un
Questa query può sembrare incomprensibile, ma vediamo che in realtà ha una struttura molto simile qualunque utente:
a quella delle calssiche query: SELECT campi FROM tabella
Nel nostro caso abbiamo indicato normalmente i campi, ma la tabella è indicata in modo un po' più $nome = "billy"; $pass= "' OR password != '";
complicato: news LEFT JOIN autori ON news.nome = autori.nome e con una query di questo tipo:
In questo modo abbiamo indicato che vogliamo ottenere una tabella che sia l'unione delle tabelle
news e autori. Questa unione deve avvenire nelle colonne nome di entrambe le tabelle. Usando $query = "SELECT * FROM utenti WHERE nome='$nome' AND password='$pass'";
LEFT JOIN otterremo una riga per ognuna della tabella specificata a sinistra (news). In questo caso la query diventerebbe:
Abbiamo dovuto solamente specificare da quale tabella ricavare la colonna nome, anche se il
risultato sarebbe lo stesso utilizzando una o l'altra tabella. SELECT * FOROM utenti WHERE nome='billy' AND password='' OR password != ''
Potremmo evitare questo utilizzando mysql_escape_string:
Le principali funzioni Php - MySQL
$nome = mysql_escape_string($nome);
$pass = mysql_escape_string($pass);
$query = "SELECT * FROM utenti WHERE nome='$nome' AND password='$pass'";
In quest'ultima lezione vediamo quali sono le principali funzioni Php per interagire con MySQL. La funzione non agisce sui simboli % e _ ed è stata inserita a partire dalla versione 4.0.3 di Php.

mysql_affected_rows() In Php possiamo nascondere gli eventuali errori ottenuti da una funzione, precedendo la stessa dal
Dopo aver inviato una query di modifica al database (INSERT, UPDATE, o DELETE) possiamo simbolo @. Questa particolarità non riguarda soltanto le operazioni MySQL, ma anche tutte le altre
utilizzare questa funzione per ottenere il numero di righe su cui la modifica ha avuto effetto. funzioni. Nel caso di MySQL possiamo poi ricavare l'eventuale errore tramite due funzioni:
Esempio:
mysql_errno()
$query = "UPDATE my_table SET nome='Mario' WHERE cognome='Rossi'"; Otteniamo il numero dell'errore dell'ultima operazione eseguita da MySQL. Se non ci sono stati
mysql_query($query);
$num = mysql_affected_rows(); errori la funzione restituisce 0.
echo "Modificate $num righe";
Esempio:

mysql_num_rows($result) $query = "INSERT INTO my_table (id, nome, cognome) VALUES (13, 'Luigi', 'Bianchi')";
if (!(@mysql_query($query)))
Restituisce il numero di righe di cui è composto il risultato di una query. Questa funzione è valida echo "Errore nr ". mysql_errno() ." nell'inserimento";
solo per query del tipo SELECT.
Esempio: mysql_error()
Come la funzione precedente, ma invece di restituire il numero dell'errore, ne restituisce una
$query = "SELECT * FROM my_table WHERE cognome='Rossi'";
$result = mysql_query($query); descrizione.
$num = mysql_num_rows();
echo "Trovati $num Rossi";
$query = "INSERT INTO my_table (id, nome, cognome) VALUES (13, 'Luigi', 'Bianchi')";
if (!(@mysql_query($query)))
echo "Errore nell'inserimento: ". mysql_error();
mysql_insert_id()
Dopo un inserimento, restituisce il valore utilizzato per la colonna di tipo AUTO_INCREMENT.
Esempio: Percorso consigliato di saibal

HTML.IT – Guide PHP 169 HTML.IT – Guide PHP 170


Apprendista lorenzoforti@html.it

10. Creazione della tabella con file .sql


Un breve tutorial per capire com'è strutturato e come funziona questo tool
Importare la struttura di un database tramite un file .sql

1. Introduzione 11. Installazione dello script

Cos'è e perchè usare PhpMyAdmin Prepariamoci ad installare lo script per gli utenti connessi

2. Interfaccia di PhpMyAdmin 12. Creazione della tabella "useronline"

Primo impatto con PhpMyAdmin Creazione manuale della tabella utile al funzionamento dello script

3. Creare un database 13. Test dello script

In pochi secondi viene creato un nuovo database su cui lavorare Configurare e testare lo script nelle nostre pagine

4. Cancellare un database Introduzione

Semplici operazioni per eliminare un database inutile


Non è detto che, per installare uno script, si debbe necessariamente conoscere il Php. I puristi della
programmazione inorridiranno certamente leggendo questa frase ma è evidente che ci sia differenza
5. Creazione di una tabella tra conoscere bene il linguaggio e montare semplicemente, sul proprio spazio web, delle pagine in
php.
Come creare manualmente delle tabelle all'interno del database Dicevamo che c'è differenza...un'enorme differenza: non possiamo certo paragonarci a chi crea,
partendo da zero, uno script complesso dato che non abbiamo le conoscenze necessarie; ciò che
invece ci serve per una semplice installazione è alla portata di tutti: poche regole di base per capire
6. Cancellare o modificare una tabella come interagire con un database, richiesto solitamente dagli script più complessi.

Operazioni utili alla gestione delle tabelle di un database Ecco quindi il perchè di questo brevissimo tutorial: avere a disposizione una guida pratica
all'utilizzo di PhpMyAdmin con l'obiettivo di installare il nostro primo script che richieda MySql.
Prima di cominciare vediamo di cosa abbiamo bisogno:
7. Cancella o Modificare i dati di un campo
x un webserver
Agire specificatamente su alcuni campi della tabella x il modulo Php
x MySql
x PhpMyAdmin
8. Effettuare una copia di backup del database
Il tutorial è rivolto principalmente a chi lavora in locale e presuppongo abbiate letto la mia guida di
Per avere sempre una copia di sicurezza sul proprio pc base. Se invece volete lavorare direttamente sul vostro spazio web (che risponde ai requisiti appena
elencati) non preoccupatevi: tuttosommato il procedimento è molto simile e basterà capire alcuni
meccanismi di routine. Ricordate, però, che in remoto alcune opzioni di gestione non saranno
9. Reinstallare una copia di backup del database disponibili (motivi di sicurezza) e avrete bisogno anche dei dati di accesso al database, da richiedere
al vostro provider.
Ripristianre velocemente il backup scaricato
PhpMyAdmin non è altro che un'interfaccia grafica che permette di amministrare MySql, un tipo

HTML.IT – Guide PHP 171 HTML.IT – Guide PHP 172


di database che immagazzina qualsiasi tipo di dati in strutture chiamate tabelle; con PhpMyAdmin,
in pratica, possiamo visualizzare il contenuto del nostro database; creare, modificare, cancellare Se si ha la possibilità di farlo, perchè il nostro hoster ce lo permette, si potrebbe creare un db per
intere tabelle o singoli record; fare un backup dei dati contenuti; visualizzare informazioni ogni nuovo codice installato in modo da avere tutti i dati suddivisi ed ordinati; sappiate comunque
interessanti sul db. che, come già detto, è possibile installare diversi script sullo stesso db purchè non ci siano tabelle
Per tentare di entrare nell'argomento (anche se siamo inesperti) possiamo considerare le tabelle con lo stesso nome.
come dei "contenitori" di dati (chiamati record); le tabelle, che possono avere diversi tipi di Ci dovremo abituare a questa situazione quando agiremo sul nostro spazio remoto dato che la
struttura, si trovano all'interno di archivi molto grossi (i singoli database appunto); ogni database, maggior parte dei provider offrono, per ciascun utente, un solo database su cui lavorare. Trovandoci
infine, può contenere diverse tables purchè queste non abbiano lo stesso nome. in locale, invece, non abbiamo questa restrizione.
PhpMyAdmin è uno strumento utilissimo, oltre che per gli esperti, anche per chi non conosce i Finita questa piccola premessa continuiamo con le operazioni di creazione. Facciamo riferimento al
comandi base di interazione tra Php e MySql; nel momento in cui scrivo l'ultima versione è la 2.2.1 frame centrale: nel campo di testo sotto la scritta Crea un nuovo database [Documentazione]
con diverse funzioni in più rispetto alle precedenti; questo tutorial, tuttavia, risulterà utile anche a possiamo inserire il nome del nuovo db. In questo caso, data la tipologia dello script che
chi lavora con release più vecchie: le operazioni fondamentali, infatti, sono identiche. installeremo, suggerisco utenti_connessi (non dobbiamo mai usare nomi staccati).

Per capire il funzionamento di questo strumento, alla fine della guida, installeremo uno script che
permette di conteggiare gli utenti connessi sulle nostre pagine. Lo zip è stato modificato inserendo
alcuni commenti utili; potete scaricare il file da qui.

Interfaccia di PhpMyAdmin
Una volta scritto il titolo possiamo premere sul bottone Crea e, "magicamente" (nel frame di
sinistra), apparirà il db che abbiamo appena costruito; noterete anche la presenza di un segno -
Prima di inziare il lavoro vero e proprio, vediamo superficialmente com'è strutturato PhpMyAdmin.
(meno) che sta ad indicare l'assenza di tabelle all'interno di utenti_connessi. Viceversa il segno +
Attiviamo Apache, il database MySql ed accediamo a PhpMyAdmin digitando l'URL
indica la presenza di tabelle all'interno di un database, come possiamo facilmente vedere facendo
corrispettivo...io ad esempio digito:
riferimento a quello chiamato mysql.
http://localhost/phpadmin/index.php

Ci troviamo di fronte ad una pagina composta da due frames; nella colonna di sinistra, sotto la
scritta Home, ci sono i nomi di tutti i database creati; se è la prima volta che attivate MySql
dovreste visualizzarne solo due: mysql e test (mysql non va assolutamente toccato visto che
contiene dati importanti per il funzionamento del db). Cancellare un database
Nella pagina centrale ci sono le risorse principali; abbiamo, ad esempio, il form per creare un nuovo
db; la scritta Utenti per impostare nuovi users; il collegamento per riavviare MySql ed una serie di
link per visualizzare alcune informazioni statistiche; sono presenti, infine, interessanti collegamenti Operazione inversa alla precedente. Mi riferisco, in particolare, al db chiamato test dato che, per le
alla documentazione ufficiale. nostre prove, non ci servirà.
Clicchiamo una volta sul nome del db da cancellare; se ci fossero delle tabelle al suo interno queste
verrebbero visualizzate sia nel frame di sinistra che nella pagina centrale; in questo caso, invece,
test è vuoto.
Avrete sicuramente notato come, una volta selezionato il db, sia cambiato il contenuto del frame
principale; in fondo a questa stessa pagina troverete un link molto interessante: Elimina database
test [Documentazione].
È facile intuire la funzione di questo comando; clicchiamo senza paura sul link, diamo la conferma
quando ci verrà richiesto e test verrà cancellato definitivamente. Ovviamente, per non completare
l'operazione, clicchiamo su "ANNULLA".

Andiamo con ordine e facciamo un po' di pratica provando alcuni dei comandi base.

Creare un database

HTML.IT – Guide PHP 173 HTML.IT – Guide PHP 174


Non è questa la sede appropriata per spiegare le caratteristiche che ogni campo può avere; ci basti
sapere (se ancora non abbiamo letto le guide di base) che, quando installeremo degli script creando
le tabelle a mano, dovremo impostare alcuni parametri specifici per ogni campo.
Visto che stiamo facendo delle prove riempiano le voci "Campo", nella schermata poco fa
visualizzata, con due nomi a piacere: prova1 e prova2. Fatto questo clicchiamo su Salva per
completare l'operazione.
Per avere un riassunto della situazione selezioniamo (nel frame di sinistra) il nostro db
(utenti_connessi); nel frame centrale avremo tutte le tabelle presenti all'interno del db selezionato
(in questo caso una sola); clicchiamo su Proprietà per vedere in dettaglio la composizione della
tabella test:

Creazione di una tabella

Abbiamo detto che ogni db contiene delle tabelle dove sono immagazzinati i dati. Le tabelle, che
dobbiamo creare noi, possono avere numerosi campi al loro interno ed ogni campo ha specifiche Cancellare o modificare una tabella
caratteristiche, ad esempio in base alla grandezza dei record da immettere.
Per creare le tabelle con PhpMyAdmin esistono fondamentalmente due modi: uno manuale in cui
dovremo impostare ogni singolo campo a mano ed un altro in cui basterà creare un file con Facciamo riferimento sempre all'immagine successiva; notiamo che accanto alla voce "Proprietà"
estensione .sql e caricarlo sul server. ci sono altri link per la gestione delle tabelle: analizziamoli velocemente.
Inizialmente studieremo il primo procedimento (analizzeremo l'altra possibilità alla fine della prima
parte della guida): clicchiamo sul database utenti_connessi; nel frame centrale, a fondo pagina,
avremo: Crea una nuova tabella nel database utenti_connessi :

x Mostra: mostra il contenuto della tabella selezionata


x Seleziona: permette delle operazioni sui campi selezionati dalla tabella: ad esempio possiamo
I due text field richiedono il nome da dare alla tabella e il numero di campi che questa tabella dovrà cambiare l'ordine di visualizzazione dei campi
avere. Supponiamo di voler creare un esempio di prova. Immettiamo i seguenti dati:
x Inserisci: dà la possibilità di inserire manualmente i record nei campi della tabella
x Nome : test x Proprietà: mostra i singoli campi della tabella dando la possibilità di cancellare o modificare il
loro contenuto
x Campi : 2
x Elimina: elimina la tabella selezionata
Clicchiamo su Esegui e, se tutto è andato come dovrebbe, PhpMyAdmin visualizzerà la struttura x Svuota: cancella i record all'interno della tabella senza eliminarla.
dei campi (2) della tabella (test):
Cancella o Modificare i dati di un campo

Nel caso avessimo commesso uno sbaglio nel compilare un campo abbiamo la possibilità di
correggere gli errori senza dover ripartire da zero.
Supponiamo di voler cambiare il nome del primo campo da prova1 a prova.
Clicchiamo, ancora una volta, sul nome del db nel frame sinistro; dopo che il menù si sarà espanso,

HTML.IT – Guide PHP 175 HTML.IT – Guide PHP 176


mostrando le tabelle presenti all'interno di utenti_connessi, selezioniamo la tabella interessata (in file con estensione .sql che rapprensenta, appunto, il backup effettuato. Adesso, nel frame di
questo caso test). Avremo davanti una schermata di questo tipo: sinistra, clicchiamo sul nome del db che vogliamo ripristinare (se questo non esiste più basterà
ricrearlo). Nella schermata centrale, poco sotto il link Visualizza per stampa, ci sarà un text field
con accanto il bottone "Sfoglia".
Andiamo a cercare il file .sql come da figura:

Selezioniamo Modifica riferito a prova1 e, nella schermata successiva, trasformiamo il contenuto di


"Campo" da prova1 a prova; premiamo "Salva" per aggiornare le modifiche.
Questo stesso procedimento può essere compiuto anche per le modifiche agli altri campi della
tabella (non solo al nome).

Effettuare una copia di backup del database

e clicchiamo su "Esegui". Il tempo di importazione varierà a seconda della grandezza del file e alla
Prima di concludere questa parte "teorica" è bene sapere come fare un backup del database e come fine del processo dovremmo ricevere questo messaggio:
reinstallarlo in caso di bisogno.
Per scaricare sul nostro pc una copia dei dati basta cliccare (nel frame di sinistra) sul nome del db Database xxxx
che vogliamo salvare; fatto questo cerchiamo, nella parte centrale della pagina, la scritta Visualizza La query è stata eseguita con successo :
dump (schema) del database e spuntiamo i checkbox come da figura: Il contenuto del file è stato inserito. (xxx Istruzioni)

Com'è facilmente intuibile il testo ci indica che tutto è andato a buon fine.
Personalmente consiglio di effettuare periodicamente un backup del database, soprattutto se si tratta
di dati online. È vero che raramente dovrebbero verificarsi dei seri problemi ma, vista la semplicità
dell'operazione, è sempre bene tenere una copia di sicurezza sul nostro pc.

Creazione della tabella con file .sql

Molti di voi avranno già capito che la stessa procedura per reinstallare un backup è valida anche per
importare un file .sql adatto al funzionamento di uno script.
Riprendiamo, quindi, il discorso sulla creazione delle tabelle lasciato a metà in precedenza;
avevamo detto che, oltre alla possibilità di crearle a mano, si può anche importare direttamente un
file a patto che questo sia scritto in un certo modo.
Dovete sapere, infatti, che molti script (specialmente i più complessi) hanno un file .sql che
permette di creare la struttura del database senza dover impostare ogni singola tabella a mano... cosa
che richiederebbe molto tempo.
Una volta cliccato su "Esegui" inizierà il salvataggio (nel formato scelto) del nostro database in L'utente non dovrà fare altro che scegliere il db appropriato e uploadare il file su Mysql.
modo da poter custodire una copia di sicurezza per ogni evenienza. Ad esempio vi avrei reso la vita più facile se avessi incluso nello zip dello script utenti, un
documento useronline.sql strutturato così:
Reinstallare una copia di backup del database

# phpMyAdmin MySQL-Dump
# version 2.2.1
Supponiamo, adesso, di dover reinstallare un backup del db perchè i dati sono andati persi...sono # http://phpwizard.net/phpMyAdmin/
cose che succedono raramente ma per fortuna siamo previdenti. #
#
http://phpmyadmin.sourceforge.net/ (download page)

Prima di tutto scompattiamo il file zip che avevamo precedentemente scaricato; dentro ci sarà un # Host: localhost

HTML.IT – Guide PHP 177 HTML.IT – Guide PHP 178


# Generato il: 10 Dic, 2001 at 05:07 PM Il resto dello script non va toccato; quello che invece dobbiamo fare è creare a mano la tabella
# Versione MySQL: 3.23.41
# Versione PHP: 4.0.6 "useronline" all'interno del database "utenti_connessi".
# Database : `utenti_connessi`
# --------------------------------------------------------
Creazione della tabella "useronline"
#
# Struttura della tabella `useronline`
#
CREATE TABLE useronline (
zeit int(15) NOT NULL default '0', La tabella necessaria al funzionamento dello script ha questa struttura:
ip varchar(15) NOT NULL default '',
file varchar(50) NOT NULL default '',
PRIMARY KEY (zeit),
KEY ip (ip),
KEY file (file) CREATE TABLE useronline (
) zeit int(15) NOT NULL,
ip varchar(15) NOT NULL,
# file varchar(50) NOT NULL,
# Dump dei dati per la tabella `useronline` PRIMARY KEY (zeit),
# KEY ip (ip),
KEY file (file) );

Avendo a disposizione un file di questo tipo in pochissimo tempo avremmo impostato in modo Da una prima occhiata possiamo vedere che sono necessari tre campi: zeit, ip e file, ognuno con
corretto la tabella; sarebbe stato sufficiente uploadare useronline.sql nel database utenti_connessi determinate caratteristiche.
senza tutti i passaggi che eseguiremo prossimamente. Vediamo passo passo come impostare il tutto:
A questo punto penso di aver descritto tutte le principali funzioni di PhpMyAdmin; l'importante è x Clicchiamo, nel frame sinistro, sul db "utenti_connessi";
conoscere le basi di questo utile tool...lascio a voi l'arduo compito di scoprire il resto se vi va.
x Nel frame centrale (in basso) creiamo una tabella chiamata "useronline" con 3 campi;
Installazione dello script
x Premiamo "Esegui";

Adesso che abbiamo familiarizzato con PhpMyAdmin possiamo passare all'installazione dello
script. Visto che ormai sappiamo come fare, cancelliamo la tabella di prova che avevamo creato
all'interno del db utenti_connessi in modo da lasciarlo vuoto.
Scompattiamo lo zip dello script; al suo interno troveremo 3 file oltre ad una cartella contenente il
documento per configurare l'accesso al database MySql.
Apriamo, con un qualsiasi editor di testo (anche il notepad), il file dbconf.php situato dentro la
cartella include. Nella schermata successiva abbiamo la struttura dei tre campi ancora da riempire.
La prima parte del documento contiene questo codice:
x Campo zeit
Alla voce "Campo" della prima riga scriviamo zeit; dal menù a tendina "Tipo" scegliamo INT; nel
//Dati di accesso al database campo "Lunghezza" inseriamo 15; il campo "Null" lasciamolo su Notnull; infine spuntiamo il
//host checkbox della voce "Primaria".
$db_server = "localhost";

//username x Campo ip
$db_username = "root";
Nel primo campo inseriamo ip; dal menù a tendina "Tipo" scegliamo VARCHAR; nel campo
//password "Lunghezza" inseriamo 15; il campo "Null" lasciamolo su Notnull; spuntiamo il checkbox della
$db_passwort = "";
voce "Indice".
//nome del database
$db_database = "utenti_connessi";
x Campo file
//nome della tabella
$db_table = "useronline"; Nel primo campo scriviamo file; dal menù a tendina "Tipo" scegliamo VARCHAR; nel campo
"Lunghezza" inseriamo 50; il campo "Null" lasciamolo su Notnull; spuntiamo il checkbox della
voce "Indice".
Se stiamo lavorando in locale probabilmente non avremo bisogno di toccare nulla (sempre che
abbiate impostato, tra i vari user, anche l'utente "root" senza password). Nel caso lavoriate in Adesso premiamo "Salva" per completare l'operazione.
remoto (oppure abbiate cancellato l'utente "root") dovrete personalizzare i dati di accesso.
Test dello script

HTML.IT – Guide PHP 179 HTML.IT – Guide PHP 180


La configurazione del database è completa. Spostiamoci dentro la cartella di lavoro di Apache
(quella in cui solitamente mettiamo i documenti da testare) e mettiamoci dentro la cartella dello
script (è chiamata utenti) con tutto il suo contenuto: il folder include, il file useronline.php e il file
userin.php.

Creiamo due semplici pagine con estensione .php: la prima verrà chiamata index.php e la seconda
prova.php (o qualsiasi altro nome).
L'index conterrà solamente questa stringa:

<? include ("useronline.php"); ?>

La pagina prova, invece, avrà questa inclusione:

<? include ("userin.php"); ?>

Salviamo le due pagine appena create dentro la cartella utenti e, dopo aver attivato Mysql e
Apache, digitiamo l'url che porta all'index:
http://localhost/utenti/index.php

Sperando che abbiate seguito alla lettera le mie istruzioni dovrebbe apparire questa tabella:

Ecco qui: adesso possiamo visualizzare quanti utenti accedono al nostro sito.

Prima di concludere una breve spiegazione sullo script. Il file useronline.php va incluso nella
pagina in cui si vuole visualizzare la tabella che mostra gli utenti on line. La grafica della tabella
stessa può essere modificata agendo sul file dbconf.php all'interno della cartella include.
Il file userin.php, invece, va inserito in tutte le pagine del sito che si vogliono includere nel
conteggio degli utenti. Se infatti un altro utente, con un IP diverso dal nostro quindi, si collegasse
alla pagina prova.php, noteremmo che, "refreshando" l'index.php, il contatore è aumentato di una
unità.
Va da sè che, solitamente, tutte le pagine di un sito non stanno nella stessa cartella; ecco quindi che,
per facilitare le cose, consiglio di includere il file userin.php con percorso assoluto e non relativo:

<? include ("http://www.vostro_sito.it/utenti/userin.php"); ?>

A questo punto non resta che augurarvi buon lavoro...

HTML.IT – Guide PHP 181

Potrebbero piacerti anche