Una
guida di base per capire i comandi fondamentali
di interazione tra Php e MySql
|
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 certo successo deve anche offrire una
consistente quantità di informazioni, ma è
impensabile dover modificare centinaia di pagine
ogni volta si apporti anche il minimo
aggiornamento.
In tutto questo, per fortuna, ci sono venuti in aiuto i linguaggi di programmazione orientati al web publishing come Php, asp o perl. Purtroppo tutto questo si è rivelato subito insufficiente: i linguaggi sono ottimi per la creazione di pagine dinamiche, ma non offrono nessuna possibilità di memorizzazione dei dati. La soluzione attuale è quindi quella di utilizzare parallelamente un linguaggio di programmazione e un database.
In questa guida ci occuperemo infatti di far interagire Php con il database relazionale MySQL. Questa accoppiata è, al giorno d’oggi, una delle più diffuse in rete in quanto abbiamo a disposizione gratuitamente un linguaggio solido, capace di sopportare grandi carichi di lavoro, e un database dalle notevoli qualità tecniche.
Prima di imparare a lavorare con MySQL è necessario avere una discreta conoscenza del Php. Per questo consigliamo a chi si avvicina per la prima volta a questo tipo di programmazione di iniziare con una guida meno specifica, come la Guida di base di FREEPHP.
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 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.
Come già saprete, per poter testare il codice sul nostro computer di casa abbiamo bisogno di un webserver, del modulo Php e del server MySQL. Questi ci eviteranno il fastidio e il costo di dover 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 in ambiente Windows.
I
database sono delle strutture nelle quali è
possibile memorizzare grandi quantità di
informazioni, per poi ricavarle attraverso
linguaggi di scripting come il PHP. Il punto di
forza di un database sta nella velocità con cui le
informazioni vengono trovate; dato il loro largo
utilizzo ne esistono diversi tipi a seconda
dell'uso che ne dobbiamo fare. Fra questi quello
attualmente più diffuso è 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 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:
+----+--------+---------+--------+--------+------------+ | id | titolo | testo | data | autore | mail | +----+--------+---------+--------+--------+------------+ | 1 | Primo | Ecco il |10-10-01| freephp|[email protected]| | | art. | primo | | | | | | | articolo| | | | +----+--------+---------+--------+--------+------------+ | | Secondo| Ed ecco |11-10-01| freephp|[email protected]| | | art. | il | | | | | | | secondo | | | | +----+--------+---------+--------+--------+------------+ |
Da
notare, in particolare, la colonna id: questa,
come potete immaginare, non contiene alcuna
informazione che riguarda l'articolo. Anzi,
vedremo che questo valore non sarà mai visibile
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 primaria. Questo campo, in questo
caso, è un numero che si auto incrementa
all'inserimento di ogni nuova riga.
Ogni
colonna della tabella avrà determinate
caratteristiche a seconda dell'informazione che
vogliamo memorizzare:
id è, come detto,
un numero intero positivo che si auto
incrementa;
titolo è una stringa di una
certa lunghezza;
data potrà essere
memorizzata in diversi formati, ma vedremo in
seguito quale utilizzare;
testo è
un'altra stringa, ma notevolmente più
grande;
autore e mail, infine,
saranno anch'esse stringhe.
Un database può
contenere più di una tabella con strutture
differenti. Queste tabelle possono però avere
informazioni incrociate e con un certo legame
concettuale. Questi li possiamo definire
attraverso relazioni (da cui il nome
database relazionale). Questo concetto,
però, lo approfondiremo più avanti.
Durante
questa lezione vedremo le operazioni necessarie
per la connessione al database. Prima di poter
comunicare con questo abbiamo infatti bisogno di
creare un "collegamento" fra lo script e
MySQL.
E' importante prima di tutto
chiarire un concetto: ognuno di noi ha
disposizione un database che non 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 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 database. Dovete quindi fare in modo
che l'utente crei le tabelle necessarie
all'interno del suo database: potremmo quindi
dirgli di accedere a phpMyAdmin e crearsi una
tabella con determinate caratteristiche. Questo
metodo, però, richiede una serie di conoscenze da
parte dell'utente che probabilmente non ha. Quindi
gli forniremo uno script che creerà per lui tutte
le tabelle necessarie.
Prima di tutto,
però, avremo bisogno di alcune informazioni
relative all'accesso al database: l'host da
cui si può raggiungere MySQL (generalmente è
localhost); username e
password per l'accesso al database; il
nome del database. Questi quattro parametri
vengono forniti dall'amministratore del nostro
spazio web.
Quindi creeremo una pagina di nome
config.inc.php con queste
righe:
// parametri del database $db_host = "localhost"; $db_user = ""; $db_password = ""; $db_name = ""; |
Abbiamo
dato proprio questo nome al file per diversi
motivi:
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 file. .inc ci
ricorderà che questo file non è una pagina che
verrà visualizzata direttamente, ma verrà inclusa
all'interno di altre. Anche questa parte del nome
può essere modificata, se non addirittura
omessa.
.php invece viene inserito per
motivi di sicurezza. Se qualcuno cercherà di
visualizzare questa 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.
Da notare inoltre che non abbiamo
chiuso i tag Php: questo perché in seguito
aggiungeremo altre stringhe di
configurazione.
A questo punto abbiamo
tutti i dati necessari per la connessione al
database. Questa la possiamo realizzare attraverso
la funzione mysql_connect. Creiamo quindi
una pagina di nome install.php con questo
contenuto:
include("config.inc.php"); $db = mysql_connect($db_host, $db_user, $db_password); |
Come
potete notare il codice richiama dal file di
configurazione i parametri del database, poi li
utilizza per connettersi.
La funzione
mysql_connect richiede diversi parametri, di cui
generalmente si utilizzano i primi tre, che sono
proprio quelli che abbiamo richiesto all'utente.
Se la connessione ha buon fine ci restituisce un
identificatore alla connessione che noi
memorizziamo in $db. Questa variabile la
utilizzeremo ogni volta che vorremo fare
un'operazione sul database. Se la connessione non
dovesse andare a buon fine (per esempio se uno dei
parametri fosse sbagliato) verrebbe restituito
FALSE. Quindi dovremo verificare il buon esito
della connessione aggiungendo di
seguito:
if
($db == FALSE) die ("Errore nella connessione. Verificare i parametri nel file config.inc.php"); |
Grazie
a queste righe se la connessione dovesse fallire,
otterremmo il messaggio di errore e l'interruzione
dell'esecuzione del programma.
Fatto tutto
questo dobbiamo specificare su quale database
vogliamo lavorare e verificare nuovamente la
riuscita dell'operazione:
mysql_select_db($db_name,
$db) or die ("Errore nella selezione del database. Verificare i parametri nel file config.inc.php"); |
In
questo caso non abbiamo bisogno di memorizzare
alcun valore, visto che la funzione restituisce
solo TRUE o FALSE.
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ò sempre identico.
In questo caso
dovremo comunicare direttamente con il database,
quindi dovremo mescolare i codici Php e Sql. I
comandi che inviamo al database sono detti
query che letteralmente significa
domanda. Infatti noi chiediamo al database
di compiere una certa operazione. In particolare
gli chiederemo di creare una tabella con
determinate caratteristiche. Aggiungiamo in fondo
al file install.php:
$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))"; |
Vediamo
nel dettaglio che cosa chiede questa
query:
CREATE TABLE news chiede la
creazione di una tabella di nome news. In
seguito, tra parentesi, specificheremo le colonne
di cui sarà composta e le loro
caratteristiche.
id INT (5) UNSIGNED not
null AUTO_INCREMENT: tutta questa parte indica
le caratteristiche 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 memorizzazione di un numero
eccessivamente grande. Visto che la numerazione
parte da 1 il valore 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
null. Infine specifichiamo a MySQL che questo
deve essere un campo AUTO_INCREMENT e che
quindi deve pensarci lui a incrementarlo ogni
volta che inseriamo un nuovo record.
titolo
VARCHAR (255) not null è il campo che conterrà
il titolo delle news. Gli assegnamo una stringa di
lunghezza massima di 255 caratteri. Se
specifichiamo una stringa di tipo varchar
dobbiamo sempre specificare la lunghezza massima
di cui sarà la stringa. Questa non potrà mai
essere più di 255, quindi qui sfruttiamo al limite
il tipo varchar. Anche il titolo dovrà
sempre essere specificato (not
null).
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 questo genere di stringhe esistono
i tipi TINYTEXT (max 255 caratteri),
TEXT (max 65.535 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 che verrà inserito, ma ovviamente si
potrebbe utilizzare anche il tipo
MEDIUMTEXT.
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 al numero
di secondi trascorsi a partire dall'ora 00:00 del
1 gennaio 1970. Utilizziamo questo 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 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.
PRIMARY KEY (id) Tramite questo
comando indichiamo quale colonna sarà la chiave
primaria, quindi quella che identificherà
univocamente le righe. Automaticamente questo
aggiunge al campo id la proprietà di
unicità. Quindi se una riga ha un determinato
numero di id, nessun'altra riga potrà avere lo
stesso id.
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).
Una volta
definita la query, possiamo comunicarla al
database attraverso la funzione
mysql_query:
if
(mysql_query($query, $db)) echo "L'installazione è stata eseguita correttamente"; else echo "Errore durante l'installazione"; |
Anche
questa funzione restituisce FALSE in caso di
errore, generalmente quando la query contiene uno
o più errori di sintassi.
Al termine dello
script è sempre bene terminare la connessione al
database:
mysql_close($db); ?> |
Con
questo il file di installazione è pronto, quindi
chiederemo all'utente di eseguirlo una sola volta
prima dell'utilizzo dello script.
Come
detto in precedenza è possibile creare la tabella
senza dover scrivere una pagina appositamente.
Questo metodo, infatti, è utile quando si vuole
distribuire lo script, ma se lo creiamo per uso
personale risulta più veloce crearla in altri
modi. Uno di questi l'abbiamo già introdotto ed è
quello di aiutarsi con phpMyAdmin.
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
"Esegui una/più query SQL sul
database":
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)) |
Cliccando
su "Esegui" la tabella verrà creata
automaticamente da phpMyAdmin.
L'ultimo
metodo che introduciamo è quello di agire
direttamente da una shell di MySQL. Anche questo
metodo è relativamente semplice: basterà infatti
inserire direttamente la query per la creazione
della tabella:
mysql>
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)); |
In
questa lezione creeremo tutto ciò che ci manca
prima di poter operare direttamente sul database.
Creeremo tutte quelle pagine che richiedono in
modo particolare codice html. Queste non
influenzeranno l'operatività dello script, ma solo
la possibilità di personalizzarlo.
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:
<?
function top() {
?> <HTML> <HEAD> <meta name=generator content="Script di freephp.it"> </HEAD> <BODY bgcolor=ffffff text=000000> <font face=verdana,tahoma,arial size=-1> <h1>FREEPHP.IT</h1><br> <? } function foot() { ?> </body></HTML> <? } ?> |
top_foot.inc.php
contiene quindi due funzioni, top() e foot(), che
hanno il solo compito di generare 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
all'aspetto del suo sito.
Fatto questo
vediamo subito come utilizzare questo file creando
il modulo per l'inserzione degli articoli in un
nuovo file di nome insert.php:
<? include ("config.inc.php"); include ("top_foot.inc.php"); //intestazione top(); ?> <form method=post action=save.php> Titolo:<br> <input type=text size=40 name=titolo><br> <br> Data:<br> <select name=giorno> <? for ($i=1; $i<=31; $i++) echo "<option value=$i>$i"; ?> </select> <select name=mese> <option value=1>Gennaio <option value=2>Febbraio <option value=3>Marzo <option value=4>Aprile <option value=5>Maggio <option value=6>Giugno <option value=7>Luglio <option value=8>Agosto <option value=9>Settembre <option value=10>Ottobre <option value=11>Novembre <option value=12>Dicembre </select> <select name=anno> <option value=2001>2001 <option value=2002>2002 <option value=2003>2003 <option value=2004>2004 <option value=2005>2005 </select><br> <br> Autore:<br> <input type=text size=40 name=autore><br> <br> E-mail:<br> <input type=text size=40 name=mail><br> <br> Testo:<br> <textarea cols=60 rows=40 name=testo></textarea><br> <br> Password:<br> <input type=password size=40 name=pass><br> <br> <input type=submit value=Invia> </form> <? // chiusura pagina foot(); ?> |
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 in uno; il campo id non è
presente, infatti verrà aggiornato automaticamente
da MySQL; password serve per evitare che
chiunque possa inserire un articolo. Il valore di
questo campo verrà confrontato con una password
scelta dall'utente. Per permettergli questo
dobbiamo quindi aggiungere ancora alcune righe al
file config.inc.php:
//password
per inserimento articoli $password = ""; ?> |
Visto
che non avremo bisogno di altre informazioni
dall'utente possiamo finalmente chiudere il tag
php nel file config.inc.php e procedere
all'inserimento degli articoli nel
database.
Finalmente
possiamo dedicarci nuovamente al database. Vedremo
adesso le operazioni da compiere per il corretto
inserimento dei dati nel database.
La prima
operazione sarà quella di verificare che la
password sia stata inserita correttamente. Creiamo
quindi la pagina save.php con le seguenti
righe:
<?
include("top_foot.inc.php"); include("config.inc.php"); top(); if ($pass != $password): echo "Password errata"; |
Anche
in questa pagina abbiamo richiamato la funzione
top() che genera il codice html relativo
all'aspetto della pagina. Abbiamo poi confrontato
la password inserita dall'utente, $pass,
con quella memorizzata in config.inc.php,
$password.
Avvenuto il
riconoscimento dobbiamo subito controllare che i
dati necessari siano stati inserti. Questo eviterà
fastidiosi errori da parte di MySQL. Infatti se
noi non forniamo il contenuto dei campi not
null, l'inserzione non può avvenire.
Quindi
verifichiamo che i campi titolo e testo non siano
vuoti o non contengano solo spazi:
elseif
(trim($titolo) == "" OR trim($testo) ==
""): echo "I campi Titolo e Testo devono essere riempiti!"; |
Abbiamo
utilizzato la funzione trim che ha lo scopo
di eliminare caratteri vuoti dall'inizio e dalla
fine della stringa. Questo eviterà di accettare
stringhe composte da soli spazi e quindi senza
contenuto informativo.
A questo punto
verifichiamo che le stringe non contengano
caratteri particolari (come l'apice o le
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:
else: $titolo = addslashes(stripslashes($titolo)); $autore = addslashes(stripslashes($autore)); $mail = addslashes(stripslashes($mail)); $testo = addslashes(stripslashes($testo)); |
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 carattere < con l'equivalente html <
e inserire nel testo i tag di fine
riga:
$titolo
= str_replace("<", "<",
$titolo); $titolo = str_replace(">", ">", $titolo); $autore = str_replace("<", "<", $autore); $autore = str_replace(">", ">", $autore); $testo = str_replace("<", "<", $testo); $testo = str_replace(">", ">", $testo); $testo = nl2br($testo); |
Possiamo
ora convertire la data in formato timestamp.
Questa operazione è relativamente semplice grazie
alla funzione mktime:
$data
= mktime("0", "0", "0", $mese, $giorno,
$anno); |
A
questo punto prima di inserire i dati dobbiamo
connetterci al database utilizzando le funzioni
viste in precedenza:
$db
= mysql_connect($db_host, $db_user,
$db_password); 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 config.inc.php"); |
Quindi
prepariamo una nuova query che questa volta dovrà
occuparsi dell'inserzione:
$query
= "INSERT INTO news (titolo, testo, data,
autore, mail) VALUES ('$titolo', '$testo',
'$data', '$autore',
'$mail')"; |
Anche
questa query è composta da più parti:
INSERT
INTO news indica che vogliamo inserire un
nuovo elemento nella tabella news La
parentesi che segue indica in quali colonne
vogliamo specificare il valore da inserire. Nel
nostro caso specifichiamo tutte le colonne eccetto
id, che verrà aggiornata automaticamente da
MySQL.
Tramite VALUES indichiamo che ci
apprestiamo a elencare i valori che vanno inseriti
nelle 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 due apici che possono essere
omessi solo nel caso di valori numerici.
Questa
query non richiede alcuna informazione al
database, se non l'avvenuto inserimento, quindi
anche qui possiamo verificare se l'inserzione è
avvenuta:
if
(mysql_query($query, $db)) echo "L'articolo è stato inserito correttamente"; else echo "Erorre durante l'inserimento"; mysql_close($db); endif; foot(); ?> |
Come
potete notare la sintassi per l'inserimento è
molto semplice e richiede solo qualche
accorgimento sul contenuto delle
stringhe.
Anche in questo caso abbiamo
altre alternative per l'inserimento di nuove righe
nel database. Possiamo per esempio utilizzare
phpMyAdmin inserendo la query direttamente nella
casella di testo "Esegui una/più query SQL sul
database":
INSERT
INTO news (titolo, testo, data, autore, mail)
VALUES ('primo articolo', 'Ecco il primo
articolo', '1002664800', 'freephp.it',
'[email protected]'); |
La
stessa query può essere utilizzata per inserire
l'articolo direttamente da una shell MySQL.
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
problemi dovendo inserire campi di grandi
dimensioni, come per esempio il nostro
testo. Inoltre abbiamo dovuto calcolare
manualmente la data in formato timestamp.
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.
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:
<? include("top_foot.inc.php"); include("config.inc.php"); top(); |
Visto
che anche qui opereremo sul database dovremo come
sempre connetterci utilizzando le funzioni già
viste in precedenza:
$db
= mysql_connect($db_host, $db_user,
$db_password); 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 config.inc.php"); |
A
questo punto veniamo alla query che dirà a MySQL
di selezionare gli ultimi articoli in ordine
cronologico:
$query
= "SELECT id,data,titolo FROM news ORDER BY data
DESC LIMIT
0,5"; |
Questa
query contiene molte delle possibilità che abbiamo
a disposizione per la selezione di particolari
righe dal database. Vediamole nel
dettaglio:
SELECT id,data,titolo FROM
news Questa prima parte è sempre necessaria
quando vogliamo 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 della query, ci verrebbero restituite
tutte le righe senza un particolare ordine. Questo
perché non avremmo applicato nessun vincolo alla
ricerca. I vincoli possono essere di diversi tipi
e vengono specificati in seguito.
ORDER BY
data DESC Anche aggiungendo questo verranno
selezionate tutte le righe, ma in ordine di data.
Visto che abbiamo aggiunto il parametro
DESC la data verrà ordinata in modo
decrescente. Quindi la prima riga della selezione
sarà l'ultimo articolo inserito, la seconda sarà
il penultimo e così via.
LIMIT 0,5 è il
vincolo che limita la selezione a sole cinque
righe. I due parametri da fornire 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 cinque elementi.
Ci verranno quindi visualizzati solo gli ultimi 5
articoli inseriti.
Inviamo quindi la query
al database e ne ricaviamo un identificatore nella
variabile $result:
$result
= mysql_query($query,
$db); |
Attraverso
$result, potremo ora ottenere le singole righe che
ci vengono restituite dal database. Per fare
questo utilizziamo la funzione
mysql_fetch_array:
while
($row =
mysql_fetch_array($result)) |
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 ripetutamente finché ci saranno
righe da visualizzare. Da notare che se il nostro
database contiene 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 selezionata, prima di passare
alla successiva:
{
echo "<a href=\"view.php?id=$row[id]\">" .
date("j/n/y", $row[data]) . " -
$row[titolo]</a><br>";
} |
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.
<a
href=\"view.php?id=$row[id]\"> questa parte
crea il link che permette all'utente di cliccare
sul titolo per poter leggere tutto il contenuto.
Questo link porta alla pagina view.php, che
creeremo in seguito, passandogli come parametro
l'id dell'articolo. Questo valore cambia da
articolo ad articolo, quindi dovremo leggerlo dal
database. Per questo abbiamo specificato nella
query che ci interessava conoscere anche l'id
dell'articolo. Quindi lo stampiamo sotto forma di
$row[id].
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
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.
Dopo aver
visualizzato i cinque titoli, possiamo quindi
chiudere la pagina:
mysql_close($db);
foot(); ?> |
A
questo punto creeremo la pagina che ci permetterà
di leggere i contenuti degli articoli.
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
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():
<?
include("top_foot.inc.php");
include("config.inc.php");
top(); |
Aggiungiamo
inoltre la parte relativa alla connessione a
MySQL:
$db
= mysql_connect($db_host, $db_user,
$db_password); 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 config.inc.php"); |
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 caso la query sarà molto simile a quella
vista in precedenza. Addirittura, visto che grazie
all'id esatto richiederemo un solo articolo, non
avremo bisogno di tutte le opzioni di ordinamento
come nel caso della pagina index.php. La query da
aggiungere in view.php sarà quindi:
$query
= "SELECT titolo,testo,data,autore,mail FROM
news WHERE
id='$id'"; |
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 viene
indicato con SELECT titolo,testo,data,autore,mail
FROM news.
In questo caso abbiamo inserito un
vincolo diverso, cioè abbiamo specificato tramite
WHERE id='$id' che ci interessano solo gli
articoli che hanno id esattamente uguale al valore
contenuto nella variabile $id. Facendo così
selezioniamo solo l'articolo di cui è stato
cliccato il titolo nella pagina
index.php.
Non ci resta che ricavare i dati
e visualizzarli:
$result
= mysql_query($query, $db); $row = mysql_fetch_array($result); $data = date("j/n/y", $row[data]); 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>"; |
In
fondo all'articolo inseriamo due link: il primo
porterà nuovamente alla prima pagina (index.php),
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:
echo
"<br><a href=index.php>Torna alla
pagina iniziale</a><br>"; echo "<a href=all.php>Visualizza tutti gli articoli</a><br>"; |
Infine
chiudiamo la connessione al database e inseriamo
la parte finale della pagina:
mysql_close($db); foot(); ?> |
Nella
precedente lezione abbiamo inserito nella pagina
view.php un link attraverso il quale sarà
possibile vedere i titoli di tutti gli articoli.
L'operazione sarebbe estremamente semplice nel
caso in cui il numero di articoli è piccolo, ma
quest'ipotesi risulta essere eccessivamente
restrittiva. Vedremo quindi come visualizzare gli
articoli suddivisi automaticamente in più
pagine.
Iniziamo, come sempre, a creare la
pagina all.php e vi inseriamo le parti
iniziali relative ad aspetto grafico e connessione
al database:
<? include("top_foot.inc.php"); include("config.inc.php"); top(); $db = mysql_connect($db_host, $db_user, $db_password); 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 config.inc.php"); |
Il
primo articolo da visualizzare sarà memorizzato in
una variabile che passeremo alla pagina con il
metodo get. Se questa non viene passata assumiamo
questo valore uguale a zero, quindi visualizzeremo
gli ultimi articoli. Impostiamo inoltre il numero
di articoli da visualizzare contemporaneamente a
20:
if
(!isset($start) OR
$start<0) $start=0; $step = 20; |
La query
che vedremo adessso sarà molto simile a quella già
vista in precedenza per visualizzare gli ultimi 5
articoli:
$query
= "SELECT id,data,titolo FROM news ORDER BY data
DESC LIMIT
$start,$step"; |
L'unica
differenza che si nota è il fatto che i parametri
del vincolo LIMIT sono variabili. $step è
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:
$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>"; } |
Infine
dovremo creare i link per accedere alle pagine
successive. Per posizionare i link nella pagina,
li inseriamo all'interno di una
tabella:
?> <br><br> <table width=90% border=0><tr> <td width=20% align=left> <? |
Abbiamo
così creato una tabella che conterrà tre celle. La
prima, quella più a sinistra, conterrà il link per
tornare alla pagina precedente (se
esiste):
if
($start>0) { $start_back = $start - $step; echo "<a href=all.php?start=$start_back>precedenti</a>"; } ?> </td> <? |
Prima
di tutto abbiamo verificato di non trovarci alla
prima pagina. Se $start è maggiore di zero,
significa, infatti, che non stiamo visualizzando
l'ultimo articolo inserito, ma solo articoli più
vecchi. 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 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 però ogni volta la variabile
$start con valori differenti.
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 quelli
attualmente visualizzati. Prima di tutto, però,
abbiamo bisogno di sapere quanti sono gli articoli
inseriti nel database. Per fare questo possiamo
dire a MySQL di contare gli elementi inseriti
nella tabella attraverso una funzione specifica.
Infatti attraverso la query possiamo richiedere al
database di eseguire alcune operazioni, senza
doverle fare tramite php. La query quindi sarà di
questo tipo:
$query
= "SELECT count(*) AS tot FROM
news"; |
Come si
può notare non abbiamo selezionato alcuna colonna
della tabella, ma abbiamo scelto di 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
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 in cui si utilizzano le
funzioni.
Per ottenere il risultato
utilizziamo i metodi usati fin'ora:
$result
= mysql_query($query, $db); $row = mysql_fetch_array($result); |
Quindi
il numero totale di articoli sarà contenuto in
$row[tot].
A questo punto vediamo in quante
pagine sarà suddiviso il risultato.
$pages
= intval(($row[tot]-1) /
$step)+1; |
Vediamo
come abbiamo ottenuto questa formula: prima di
tutto prendiamo in consderazione il 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 0,
invece otteniamo 1. Per questo abbiamo modificato
la formula in ($row[tot]-1) / $step. Noi,
però, 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.
A questo punto possiamo creare
i link, uno per ogni pagina, all'interno della
cella centrale della tabella:
?> <td width=60% align=center> <? for ($i=0; $i<$pages AND $i<20; $i++) { $start_page = $i * $step; echo "<a href=all.php?start=$start_page>" . ($i+1) . "</a> "; } ?> </td> |
Abbiamo
inserito un ciclo for che termina nel caso una
delle due condizioni sia vera. La prima indica che
abbiamo elencato tutte le pagine possibili, oltre
le quali non ci sono risultati da visualizzare. La
seconda limita l'indice alla ventesima pagina, per
evitare di indicare un elenco eccessivamente lungo
nel caso gli articoli siano tanti.
Infine
possimao inserire il link alla pagina successiva.
Prima di inserirlo dobbiamo verificare che questa
possa esistere e che non porti a pagine vuote. Per
questo ci verrà utile il valore di $row[tot]
trovato in precedenza.
<td
width=20%> <? if ($start + $step < $row[tot]) { $start_next = $start + $step; echo "<a href=all.php?start=$start_next>successivi</a>"; } ?> </td> </tr></table> <br> <? |
Fatto
questo inseriamo un link al motore di ricerca e
chiudiamo la pagina:
echo
"<a href=search.php>Cerca negli
articoli</a>"; foot(); ?> |
Finalmente
in questa lezione sfruttiamo fino in fondo le
potenzialità del database. Inseriremo un 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:
<? include("top_foot.inc.php"); include("config.inc.php"); top(); ?> |
Quindi
dovremo creare un form che contenga un campo di
testo per immettere le parole da
cercare:
<form
method=post action=result.php> <input type=text name=chiave><input type=submit value=cerca><br> </form> |
e
infine chiudiamo la pagina:
<? foot(); ?> |
A
questo punto possiamo venire alla pagina
result.php che avrà il compito di elaborare
la stringa inserita dall'utente:
<? include("top_foot.inc.php"); include("config.inc.php"); top(); $db = mysql_connect($db_host, $db_user, $db_password); 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 config.inc.php"); |
Per
prima cosa dovremo suddividere la stringa nelle
chiavi da ricercare. Noi supporremo che le diverse
chiavi siano suddivise da virgole. Quindi le
inseriremo in un array di nome
$keys:
$keys
= explode (",",
$chiave); |
Tramite
questa operazione abbiamo spezzato la stringa
$chiave in corrispondenza di ogni virgola e
inserito i frammenti all'interno dell'array
$keys.
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:
$query
= ""; reset ($keys); while (list(,$parola) = each ($keys)) { $parola = trim($parola); if ($parola != "") $query .= "titolo LIKE '%$parola%' OR testo LIKE '%$parola%' OR autore LIKE '%$parola%' OR "; } $query .= "0"; |
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 4 di Php.
Ogni elemento dell'array
sarà quindi disponibile uno alla volta con il nome
$parola. Da questa 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.
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":
- Prima
di tutto viene definita la query vuota: $query =
"";
- 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.
- 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".
- 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 '%freephp%' OR
autore LIKE '%freephp%' OR "
- 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 "neutralizzare" il
suo effetto senza eliminarlo.
Fatto tutto
questo possimao inserire la prima parte della
stringa:
$query
= "SELECT id, titolo, data FROM news WHERE " .
$query; |
Quindi
la stringa diventerà:
"SELECT id, titolo, data
FROM news WHERE titolo LIKE '%articolo%' OR ... OR
autore LIKE '%freephp%' OR 0"
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%'
LIKE indica che titolo deve
contenere articolo e non che deve essere uguale a
titolo.
% all'inizio indica che prima di
"articolo" possono comparire altri caratteri.
Quindi "articolo" non deve necesariamente trovarsi
all'inizio della cella. Stessa cosa indica il
simbolo % alla fine. Quindi inserendo questi due
simboli abbiamo indicato di verificare se la cella
titolo contiene la parola "articolo" in una
qualunque posizione: all'inizio, al centro o alla
fine.
Una volta definita la query possiamo
inviarla a MySQL ed elencare i
risultati:
$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>"; } |
Infine, come
sempre, chiudiamo la pagina:
foot() ?> |
Vedremo
adesso di riassumere le diverse modalità di
gestione del database che abbiamo usato. In
particolare si nota che alcuni passaggi sono
sempre presenti e devono presentare determinate
caratteristiche. Faremo particolarmente caso a
quelle funzioni che devono essere utilizzate e
quali parametri devono essere specificati e quali
invece possono essere omessi.
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 utilizzare. Come abbiamo
visto la funzione è:
$db
= mysql_connect ($server, $username,
$password); |
Questa
funzione è sempre necessaria e deve essere,
ovviamente, configurata correttamente tramite i
tre parametri indicati sopra. Tutti e tre i
parametri possono essere omessi. In questo caso i
valori di 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 connessione senza
indicare almeno gli ultimi due parametri. Ma visto
che specificare un parametro 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
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.
Dopo la connessione selezioniamo
un database:
mysql_select_db
($database_name,
$db); |
Questa
funzione può sembrare inutile, visto che nella
maggior parte dei casi abbiamo a disposizione un
solo database. Tuttavia non sempre è così, anzi,
generalmente un singolo MySQL contiene diversi
database, ma noi abbiamo accesso a uno solo di
questi. Ovviamente dobbiamo specificare il primo
parametro che conterrà una stringa con il nome del
database che ci è stato assegnato dal gestore. Il
secondo parametro indica la connessione attiva e
può essere omesso, in quanto Php 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 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); |
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 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.
Per tutte le query della seconda categoria
non avremo bisogno di creare l'identificatore
$result, visto che le modifiche vengono apportate
subito.
Nel primo caso invece avremo
bisogno di ricavare le informazioni che
abbiamo richiesto in precedenza. Questo lo
facciamo usando la funzione:
$row
= mysql_fetch_array ($result,
$result_type); |
Tramite
questa funzione memorizziamo i risultati
nell'array $row. $row può essere
associativo con 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.
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.
Dopo aver
eseguito tutte le operazioni, alla fine della
pagina ci ricordiamo di chiudere la
connessione al database:
mysql_close
($db); |
Anche in
questo caso possiamo omettere il parametro. Anzi,
possiamo addirittuta evitare di inserire la
funzione stessa, come abbiamo già fatto in
precedenza, visto che tutte le connessioni vengono
chiuse automaticamente alla fine della
pagina.
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 query che
invece indicano modifiche da apportare. In questa
sezione faremo una distinzione più precisa
indicando le query di uso più comune. Ovviamente
non prenderemo in considerazione tutte le
possibili sintassi, che potete però trovare nella
documentazione ufficiale sul sito
www.mysql.com.
Innanzi tutto esaminiamo le
query che vengono utilizzate per gestire la
struttura del
database:
CREATE:
Tramite questo
comando possiamo creare database e tabelle. Nel
primo caso dobbiano solamente indicare il nome:
CREATE DATABASE IF NOT EXISTS
db_name
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 notare che nella maggior
parte dei casi di hosting, ci viene assegnato un
database dal gestore e non possiamo crearne altri.
Tuttavia questa possibilità può essere comoda se
possiamo gestire direttamente MySQL.
Per creare
una tabella utilizziamo invece il generico
comando:
CREATE TABLE IF NOT EXISTS tbl_name
(definizioni)
Anche qui abbiamo la possibilità
di usare l'opzione IF NOT EXISTS. Le
definizioni indicano i tipi di colonne di cui deve
essere composta la tabella e la chiave primaria
che verrà utilizzata. Abbiamo già visto queste
caratteristiche nelle prime lezioni di questa
guida, quindi non ci tornerò un'altra
volta.
Per fare un po' di esempi, una query per
creare un database chiamato "mio_db" potrebbe
essere:
CREATE
DATABASE IF NOT EXISTS
my_db |
Una volta
impostate le operazioni su quel database, vi
creiamo una tabella (my_table) nella quale
inseriamo due colonne: la prima un contatore id e
la seconda una colonna nome (stringa di 20
caratteri):
CREATE
TABLE my_table (id INT UNSIGNED NOT NULL
AUTO_INCREMENT, nome varchar(20), primary
key(id)) |
DROP:
Così
come abbiamo creato database e tabelle, li
possiamo eliminare:
DROP DATABASE IF EXISTS
db_name
DROP TABLE IF EXISTS tbl_name
E'
consigliata la massima prudenza nell'usare questi
comandi, visto che elminando un database o una
tabella si elimina anche tutto il loro contenuto!
Anche in questo caso IF EXISTS è
facoltativo.
ALTER:
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 "tbl_name". La sintassi
di "definizione" è uguale a quella usata per la
creazione della tabella. In fondo al comando
possiamo aggiungere FIRST se vogliamo che
la colonna inserita sia la prima o AFTER
column_name per asseganre una posizione
diversa. Se non specifichiamo niente la colonna
verrà inserita in ultima posizione.
Per fare un
esemio inseriamo fra id e nome la
colonna cognome:
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 |
Possiamo
infine modificare il tipo di una colonna:
ALTER
TABLE tbl_name MODIFY colonna new_type
In
particolare per modificare la colonna nome da
VARCHAR(20) a VARCHAR (30):
ALTER
TABLE my_table MODIFY nome
VARCHAR(30) |
Vediamo
quindi le principali query per gestire il
contenuto di un
database:
INSERT:
Una volta
creato un database dovremo popolarlo inserendo i
record:
INSERT INTO tbl_name (cols) VALUES
(values)
Anche di questa query abbiamo già
visto la struttura nelle precedenti
lezioni.
UPDATE:
Tramite questa
funzione possiamo modificare alcuni valori di
determinate righe:
UPDATE tbl_name SET
col_name=expr WHERE where_definition
Questa
notazione è piuttosto generale: tbl_name
indica come sempre il nome della tabella,
col_name=expr indica la modifica da
apportare a una determinata colonna e
where_definition indica le condizioni che
si devono verificare in una riga perché questa
possa essere modificata.
Per fare un esempio,
possiamo assegnare il nome "Mario" a tutte le
persone che hanno il cognome "Rossi":
UPDATE
my_table SET nome='Mario' WHERE
cognome='Rossi' |
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 creare la
query:
UPDATE
my_table SET id=id*1000, nome='Mario' WHERE
(cognome='Rossi' OR cognome='Bianchi') AND
id>5 |
Questa
query più complicata ha lo scopo di cambiare il
nome in Mario e di moltiplicare la colonna 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 apportata solo alle righe in cui
cognome sia "Rossi" o "Bianchi" e comunque id sia
maggiore di 5. Tutta questa query non ha molto
senso pratico, ma mostra bene parecchie
possibilità...
DELETE:
Per
eliminare una o più righe ci basta indicare le
condizioni che devono verificarsi:
DELETE FROM
tbl_name WHERE condizioni
Anche qui possiamo
utilizzare condizioni composte:
DELETE
FROM my_table WHERE id<1000 AND (nome='Mario'
OR
nome='Luigi') |
SELECT:
Questo
genere di query è quella che probabilmente
utilizzerete più spesso, in quanto vi servirà per
ricavare i dati precedentemente inseriti in una
tabella:
SELECT colonne FROM tbl_name WHERE
condizioni opzioni
In precedenza abbiamo già
visto anche questa query, ma sarà meglio fare un
ripasso:
colonne indica tutte le colonne
di cui vogliamo il valore. Queste possono anche
essere operazioni, come vedremo
nell'esempio.
condizioni sono le
condizioni che devono verificarsi, perché una riga
sia visualizzata. Queste sono dello stesso tipo di
quelle viste nei casi UPDATE e
DELETE.
opzioni ci serviranno per
esempio per ordinare le righe.
Per fare un
esempio:
SELECT
id, cognome, nome, count(*) AS tot FROM my_table
WHERE cognome='Rossi' ORDER BY nome, id
DESC |
Con questa
query otterremo una tabella composta da quattro
colonne. Le prime tre saranno quelle 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 quella
colonna conterrà 32 volte il valore 32. Infine
abbiamo indicato che le righe devono essere
ordinate per nome e in caso di nomi uguali
per id decrescente.
Se vogliamo per
esempio sapere tutti i cognomi presenti nel
database usiamo l'opzione GROUP BY, grazie alla
quale le righe vengono raggruppate in base al loro
contenuto in una colonna:
SELECT
cognome FROM my_table GORUP BY
cognome |
Utilizzando
quest'opzione eviteremo di avere cognomi uguali
ripetuti.
Come condizione possiamo anche
utilizzare il metodo di confronto LIKE. Per
esempio posso creare la query:
SELECT
* FROM my_table WHERE cognome LIKE 'Ro%' OR nome
LIKE
'%ri%' |
L'asterisco
indica che voglio selezionare tutte le colonne. In
seguito ho indicato di scegliere tutte le righe in
cui il cognome inizi con "Ro" e finisca con
qualunque sequenza di caratteri (indicata con il
simbolo %),oppure il cui nome contenga "ri" (e
possa quindi iniziare e finire con qualunque
stringa).
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 scrivere gli
articoli sono generalmente un numero ristretto di
persone e soprattutto a ogni persona corrisponde
sempre lo stesso indirizzo e-mail. Ci ritroviamo
quindi con una serie di informazioni che vengono
ripetute più volte. Per risolvere questo problema
divideremo il nostro archivio di notizie su due
tabelle e vedremo come gestirle.
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.
Innanzi tutto vediamo come
devono essere suddivise le tabelle che
utilizzeremo. Quello che dovremo fare sarà
spezzare la tabella news in due parti:
prenderemo le colonne autore e mail e ne 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 farà corrispondere ogni riga
della tabella a una sola riga della tabella
autori. Dovremo quindi modificare il file
install.php in questo modo:
$query1
= "CREATE TABLE news (id INT (5) UNSIGNED not
null AUTO_INCREMENT, titolo VARCHAR (255) not null , testo TEXT not null , data INT (11) , nome VARCHAR (50) , PRIMARY KEY (id))"; $query2 = "CREATE TABLE autori (nome VARCHAR (50) not null, mail VARCHAR(50), PRIMARY KEY (nome))"; if (mysql_query($query1, $db) AND mysql_query($query2, $db)) echo "L'installazione è stata eseguita correttamente"; else echo "Errore durante l'installazione:<br>" . mysql_error(); |
Questa
parte va ovviamente inserita fra l'apertura e la
chiusura della connessione. Quello che abbiamo
fatto è creare due query per la creazione delle
due tabelle e inviarle entrambe tramite due
chiamate a mysql_create.
A questo
punto dovremo modificare l'inserimento
dell'articolo. La pagina insert.php resta
ovviamente uguale, visto che le modifiche che
stiamo apportando dovrebbero risultare trasparenti
all'utente. Modifichiamo quindi la pagina
save.php in modo da inserire le informaioni
nelle due tabelle.
Dopo le righe relative alla
connesione al database sostituiamo tutto il codice
rimanente con questo:
$query1
= "INSERT INTO news (titolo, testo, data, nome)
VALUES ('$titolo', '$testo', '$data',
'$autore')"; $query2 = "INSERT IGNORE INTO autori (nome, mail) VALUES ('$autore', '$mail')"; if (mysql_query($query1, $db) AND mysql_query($query2, $db)) echo "L'articolo è stato inserito correttamente"; else echo "Erorre durante l'inserimento $query"; endif; foot(); ?> |
Anche
in questo caso abbiamo utilizzato due query per la
modifica di due tabelle. In pratica le 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.
A questo punto non ci resta ch
vedere come visualizzare le informazioni in modo
tale da specificare che quando un articolo è
scritto da una certa persona, vogliamo che sia
visualizzato proprio il suo indirizzo mail. Per
fare questo abbiamo diversi metodi che vedremo
nella prossima lezione.
Il
nostro scopo sarà quello di unire due tabelle
(news e autori) e farle diventare una sola, in
modo da trattarla come abbiamo fatto nella prima
versione dello script. Per fare questo usiamo
particolari sintassi MySQL specifiche per questo
scopo.
Quello che dobbiamo fare è
modificare la query in view.php in modo
tale da ottenere l'effetto sopra descritto. Il
metodo più semplice è quello di selezionare le
singole colonne:
$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'"; |
In
questo modo abbiamo specificato di voler
selezionare tutte le colonne di news e la
sola colonna mail di autori (autori.mail). Abbiamo
poi indicato che la colonna nome verrà
gestita con l'alias 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 = autori.nome). In
questo modo otteniamo una tabella con le stesse
caratteristiche di quella che abbiamo utilizzato
in precedenza.
Con il metodo che abbiamo
visto otteniamo l'unione di due tabelle tramite
una relazione, ma questa è una scorciatoia per
semplificare il codice. Normalmente per ottenere
l'unione di due tabelle si usa JOIN:
$query
"SELECT titolo, testo, data, news.nome AS
autore, mail FROM news LEFT JOIN autori ON
news.nome = autori.nome WHERE
id='$id'"; |
Questa
query può sembrare incomprensibile, ma vediamo che
in realtà ha una struttura molto simile 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ù complicato: news LEFT JOIN autori
ON news.nome = autori.nome
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
LEFT JOIN otterremo una riga per ognuna della
tabella specificata a sinistra (news).
Abbiamo
dovuto solamente specificare da quale tabella
ricavare la colonna nome, anche se il risultato
sarebbe lo stesso utilizzando una o l'altra
tabella.
In
quest'ultima lezione vediamo quali sono le
principali funzioni Php per interagire con
MySQL.
mysql_affected_rows()
Dopo
aver inviato una query di modifica al database
(INSERT, UPDATE, o DELETE) possiamo utilizzare
questa funzione per ottenere il numero di righe su
cui la modifica ha avuto
effetto.
Esempio:
$query
= "UPDATE my_table SET nome='Mario' WHERE
cognome='Rossi'"; mysql_query($query); $num = mysql_affected_rows(); echo "Modificate $num righe"; |
mysql_num_rows($result)
Restituisce
il numero di righe di cui è composto il risultato
di una query. Questa funzione è valida solo per
query del tipo SELECT.
Esempio:
$query
= "SELECT * FROM my_table WHERE
cognome='Rossi'"; $result = mysql_query($query); $num = mysql_num_rows(); echo "Trovati $num Rossi"; |
mysql_insert_id()
Dopo
un inserimento, restituisce il valore utilizzato
per la colonna di tipo
AUTO_INCREMENT.
Esempio:
$query
= "INSERT INTO my_table (id, nome, cognome)
VALUES ('', 'Luigi',
'Bianchi')"; mysql_query($query); $num = mysql_insert_id(); echo "Luigi Rossi ha id: $num"; |
mysql_list_tables($nome_database)
Restituisce
una lista contenente i nomi delle tabelle nel
database specificato.
Esempio:
$result
= mysql_list_tables($my_db); while (list($table) = mysql_fetch_array($tables)) echo "$table "; |
mysql_escape_string($stringa)
Tramite
questa funzione vengono inseriti i caratteri di
escape nella stringa. Per fare un esempio, un
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 qualunque utente:
$nome
= "billy"; $pass= "' OR password !=
'"; |
e con una query
di questo tipo:
$query
= "SELECT * FROM utenti WHERE nome='$nome' AND
password='$pass'"; |
In
questo caso la query diventerebbe:
SELECT
* FOROM utenti WHERE nome='billy' AND
password='' OR password !=
'' |
Potremmo evitare
questo utilizzando mysql_escape_string:
$nome
= mysql_escape_string($nome); $pass = mysql_escape_string($pass); $query = "SELECT * FROM utenti WHERE nome='$nome' AND password='$pass'"; |
La
funzione non agisce sui simboli % e _ ed è stata
inserita a partire dalla versione 4.0.3 di
Php.
In Php possiamo nascondere gli
eventuali errori ottenuti da una funzione,
precedendo la stessa dal simbolo @. Questa
particolarità non riguarda soltanto le operazioni
MySQL, ma anche tutte le altre funzioni. Nel caso
di MySQL possiamo poi ricavare l'eventuale errore
tramite due
funzioni:
mysql_errno()
Otteniamo
il numero dell'errore dell'ultima operazione
eseguita da MySQL. Se non ci sono stati errori la
funzione restituisce 0.
Esempio:
$query
= "INSERT INTO my_table (id, nome, cognome)
VALUES (13, 'Luigi', 'Bianchi')"; if (!(@mysql_query($query))) echo "Errore nr ". mysql_errno() ." nell'inserimento"; |
mysql_error()
Come
la funzione precedente, ma invece di restituire il
numero dell'errore, ne restituisce una
descrizione.
$query
= "INSERT INTO my_table (id, nome, cognome)
VALUES (13, 'Luigi', 'Bianchi')"; if (!(@mysql_query($query))) echo "Errore nell'inserimento: ". mysql_error(); |