MODULO 1
PARTE 3
Programmazione (scripting)
server-side con PHP
3.b
Interazione con un database
(MySQL Server)
Goy - a.a. 2009/2010
Programmazione Web
1
Informazione persistente
Se vogliamo tener traccia di varie informazioni (per
esempio dati sull'utente) in modo persistente, rendendole
cioè disponibili al di là della singola interazione (e
potenzialmente anche al di là dell'esistenza dell'applicazione
stessa)
t
) dobbiamo
d bbi
salvarle
l l su file
fil system
t
In un'architettura client-server abbiamo due possibilità:
• il file system del server
• file di testo [che non vedremo...]
• database
• il file system del client: cookie
Goy - a.a. 2009/2010
Programmazione Web
2
1
Ripasso di database - I
L'utilizzo di un database ci permette di salvare i dati in
modo strutturato
Quando progettiamo un database relazionale, dobbiamo
definire quali informazioni conterrà e quali saranno le
relazioni tra le informazioni → questo può essere fatto a
vari livelli:
vista 1 vista 2
vista n
livello concettuale
livello logico
livello fisico
Goy - a.a. 2009/2010
Programmazione Web
3
Ripasso di database - II
Livello logico: rappresentazione tabellare dei dati
colonna/campo
Tabella: LIBRI
N Inv
N.Inv
Autore
Titolo
Anno ed
Anno_ed
Casa ed
Casa_ed
riga/record
Quando vogliamo costruire una tabella, dobbiamo
innanzitutto definire la sua struttura: i nomi dei campi
(colonne) e i tipi di dati in essi contenuti
Goy - a.a. 2009/2010
Programmazione Web
4
2
Ripasso di database - III
Interazione con un database:
• interrogazione
• inserimento di dati
• cancellazione di dati
• aggiornamento (update)
Ogni interazione con la base di dati:
– viene interpretata, analizzata ed eseguita dal DBMS
(DataBase Management System)
– costituisce una query, espressa (direttamente oppure
tradotta) in SQL
– restituisce come risultato un insieme di record
(recordset)
Goy - a.a. 2009/2010
Programmazione Web
5
Ripasso di database: SQL
SQL (Structured Query Language) - casi semplici:
• interrogazione
SELECT colonna1 [, colonna2, ecc] FROM tabella
[WHERE condizione] [ORDER BY colonna]
↓
nella condizione si possono usare i soliti operatori:
=, >, <, >=, <=, <>; AND, OR, NOT
• inserimento
INSERT INTO tabella [(colonna1, ecc)]
VALUES (valore1, ecc)
• cancellazione
DELETE FROM tabella
[WHERE condizione]
• aggiornamento (modifica)
UPDATE tabella
SET colonna1=valore1 [colonna2=valore2, ecc]
[WHERE condizione]
Goy - a.a. 2009/2010
Programmazione Web
6
3
Ripasso di database: MySQL Server - I
Nel corso utilizzeremo MySQL Server (con PHP) per la
costruzione di un piccolo database di esempio, che gestisce
le informazioni sugli utenti di una ipotetica bacheca di annunci
on-line
• MySQL (www.mysql.com) è un database Server, basato su
SQL, multi-processo, multi-utente; è veloce e robusto
• MySQL Server è distribuito gratuitamente, con una licenza
GNU (www.gnu.org/gnu/thegnuproject.it.html)
• La distribuzione di MySQL Server include il database
server (DBMS) e diversi client: il database server
– risiede sulla macchina su cui si trovano i dati
– riceve le richieste (query) dai client
– accede ai database
– fornisce le risposte (risultati delle query)
Goy - a.a. 2009/2010
Programmazione Web
7
Ripasso di database: MySQL Server - II
Attenzione!
• Il DBMS MySQL funziona con un’architettura
client-server
MySQL
Server
MySQL client
MySQL client
MySQL client
• Non confondete MySQL Server con il Web (HTTP)
Server (per es. Apache)
• Aprire una connessione al DB significa aprire una
connessione con MySQL Server e poi chiedergli di
selezionare un database
⇒ connessione al DB Server e selezione del database
su cui operare sono due operazioni diverse!
Se devo effettuare due interazioni con due database
distinti, mi occorre una sola connessione al DB
Server!
Goy - a.a. 2009/2010
Programmazione Web
8
4
MySQL Server: XAMPP
Se avete installato XAMPP, MySQL Server dovrebbe già
essere installato sul vostro PC e avviando il pannello di
controllo di XAMPP potete avviare o fermare MySQL
Server:
phpMyAdmin
[vedi prossima slide]
Goy - a.a. 2009/2010
Programmazione Web
9
MySQL Server: phpMyAdmin
XAMPP comprende anche phpMyAdmin, un'interfaccia
utente web-based (scritta in PHP), per interagire con
MySQL Server:
• Potete accedere a pphpMyAdmin,
p y
, cliccando sul ppulsante
Admin (di fianco a MySql), nel pannello di controllo
• oppure dal browser, potete connettervi direttamente a:
http://localhost/phpmyadmin/
• Cliccando su Privilegi, in alto nella home page di
phpMyAdmin, potete controllare gli utenti abilitati ad
accedere al DB Server
NB: la configurazione di default di XAMPP prevede,
su localhost, un utente root, senza password (come
vi dice phpMyAdmin stesso, questa non è una
configurazione sicura, ma in fase di sviluppo va bene…)
Goy - a.a. 2009/2010
Programmazione Web
10
5
MySQL/phpMyAdmin - creazione di un DB - I
lo creiamo
indichiamo il nome di un
nuovo db ("bacheca")
Goy - a.a. 2009/2010
Programmazione Web
11
MySQL/phpMyAdmin - creazione di un DB - II
creiamo una nuova
tabella (("utenti")...
utenti )...
Goy - a.a. 2009/2010
...con 5 campi
(colonne)
(co
o e)
Programmazione Web
12
6
MySQL/phpMyAdmin - creazione di un DB - III
1) digitiamo i 2) selezioniamo il tipo
nomi dei campi del valore [vedi prox slide]
3) impostiamo
le proprietà che
desideriamo
[vedi prox slide]
4) salviamo
la tabella
Goy - a.a. 2009/2010
Programmazione Web
13
MySQL/phpMyAdmin - creazione di un DB - IV
Tipi principali:
• INT = numero intero
• VARCHAR = stringa a lunghezza variabile (lunghezza massima
specificata nella proprietà Lunghezza/Set)
• TEXT = testo
• DATE = data
Varianti di INT (NUMERIC):
• TINYINT, SMALLINT, MEDIUMINT, BIGINT = interi con
lunghezze max predefinite
• DECIMAL, FLOAD, DOUBLE, REAL = decimali
• BIT = 0/1, BOOL = true/false, …
Varianti di DATE (DATE and TIME):
• …
Varianti di VARCHAR (STRING):
• CHAR = stringa a lunghezza fissa (specificata nella proprietà
Lunghezza/Set)
• ENUM/SET = valori compresi in un elenco fornito dalla proprietà
Lunghezza/Set
• …
Goy - a.a. 2009/2010
Programmazione Web
14
7
MySQL/phpMyAdmin - creazione di un DB - V
Proprietà principali:
•
Lunghezza/Set = numero (max) di caratteri ammessi (o
lista dei possibili valori, se il tipo è ENUM/SET)
•
Null = indica se il valore del campo è opzionale o
obbligatorio (cioè se può avere valore null)
•
Predefinito = imposta un valore predefinito per il campo
•
A_I = auto_increment, proprietà generalmente usata con
numeri interi: ad ogni inserimento di un nuovo record
nella tabella, assegna il valore precedente+1
•
Indice → PRIMARY = chiave primaria = identificatore
univoco di record; non può essere null! (nel nostro es.
impostiamo user_id come chiave primaria)
Altri possibili valori: UNIQUE/INDEX/FULLTEXT
Goy - a.a. 2009/2010
Programmazione Web
15
MySQL/phpMyAdmin - creazione di un DB - VI
inseriamo dei valori…
NB: query SQL
corrispondente
all'operazione
(inserimento di
campi) appena
fatta
NB: struttura
della tabella
utenti
Goy - a.a. 2009/2010
Programmazione Web
16
8
MySQL/phpMyAdmin - creazione di un DB - VII
inseriamo degli utenti nel database
NB: non inseriamo lo user_id (viene inserito automaticamente)
Goy - a.a. 2009/2010
Programmazione Web
17
Ripasso di database: note su SQL - I
NOTE su SQL:
INSERT: se non inserite tutti i campi (come nel nostro es:
user_id è auto_increment quindi non lo inseriamo noi ma
automaticamente il DBMS!), dovete obbligatoriamente
indicare quali campi inserite (e nell'ordine corretto); per es:
INSERT INTO utenti (cognome, nome, email,
data_n) VALUES ('Caio', 'Tizio', '[email protected]',
'1999-09-29')
SELECT: se volete selezionate tutte le colonne, potete
usare l'*; per es:
SELECT * FROM utenti WHERE email='[email protected]'
Goy - a.a. 2009/2010
Programmazione Web
18
9
Ripasso di database: note su SQL - II
NB: attenzione ai tipi di dati e alla struttura del database!
INSERT INTO utenti VALUES ('Caio', 'Tizio',
'[email protected]')
→ ERRORE! (mancano user_id e data_n!)
INSERT INTO utenti (cognome, nome, email) VALUES
('Caio', 'Tizio', '[email protected]')
→ OK
INSERT INTO utenti (cognome, nome, email, data_n)
VALUES ('Caio', 'Tizio', [email protected], '1999-09-29')
→ ERRORE! (il tipo del campo email è stringa: ci vogliono le
virgolette!)
INSERT INTO utenti (cognome, nome, email, data_n)
VALUES ('Caio', 'Tizio', '1999-09-29', '[email protected]')
→ ERRORE! (l'ordine è sbagliato!)
Goy - a.a. 2009/2010
Programmazione Web
19
MySQL/phpMyAdmin: esportare un DB - I
I file che contengono i database si trovano in:
C:\xampp\mysql\data\
Da phpMyAdmin è possibile esportare un database come
query SQL:
sulla sinistra selezionate
il database che volete
esportare
fate click su Esporta
Goy - a.a. 2009/2010
Programmazione Web
20
10
MySQL/phpMyAdmin: esportare un DB - II
eseguite l'esportazione
(creazione della query
che costruisce il db)
Goy - a.a. 2009/2010
Programmazione Web
21
MySQL/phpMyAdmin: esportare un DB - III
compare una pagina
con la query SQL che
permette di ricostruire
il database
fate copia&incolla e
salvatela in un file:
nome-db.sql
(per es. bacheca.sql)
(p
q)
Goy - a.a. 2009/2010
Programmazione Web
22
11
MySQL/phpMyAdmin: importare un DB
Da phpMyAdmin è possibile importare un database come
query SQL:
• Aprite il file nome-db.sql (per es. bacheca.sql) e
leggete il nome del DB; create un DB con quel nome
• Cliccate il alto su SQL
• Fate copia&incolla del contenuto di nome-db.sql nella
finestra e cliccate sul pulsante Esegui
Goy - a.a. 2009/2010
Programmazione Web
23
PHP: interazione con un database - I
Vi ricordate lo schema standard di elaborazione di una pagina
web dinamica server-side (per es. PHP)?
elaborazione
(
(interpretazione
p
del codice PHP)
⇓
HTML (+
Javascript)
Server
request
(pag.php)
client ?
Server
Server
client
response
HTML (+
Javascript)
client
Se lo script PHP contiene istruzioni di interazione con un
database, la fase di "elaborazione"
elaborazione (interpretazione dello script)
implicherà anche una connessione con tale database:
elaborazione
(interpretazione
del codice PHP)
Goy - a.a. 2009/2010
=
...
<?php
conn. DB
?>
...
Programmazione Web
DB
24
12
PHP e MySQL: interazione – I
Cosa si deve fare per accedere ad un DB (MySQL) da
una pagina web (PHP)?
All'interno di uno script PHP dobbiamo:
1.
2.
Aprire una connessione con MySQL Server
Selezionare un database
3.
Inviare al DB Server una query SQL
4.
Eventualmente, estrarre (e visualizzare) i dati
contenuti nel risultato della query (recordset)
5
5.
Chiudere la connessione
Goy - a.a. 2009/2010
Programmazione Web
25
PHP e MySQL: interazione – II
1.
Aprire una connessione con MySQL Server
Per connettersi a MySQL Server bisogna avere:
•
•
il nome dell'host (o l'indirizzo IP) su cui risiede il DB Server
un nome-utente e una password
$conn = mysql_connect("localhost", "root", "")
or die ("Non riesco a creare la connessione");
apro una connessione a MySQL Server: la funzione
mysql_connect ha 3 argomenti: db server, user-id, password
NB: Se avete installato XAMPP (senza modificare le
impostazioni di default) MySQL Server è accessibile su
localhost con user-id="root" e ppassword = ""
Per verificare: nella prima pagina di phpMyAdmin cliccate su
Privilegi
Goy - a.a. 2009/2010
Programmazione Web
26
13
PHP e MySQL: interazione – III
$conn = mysql_connect("localhost", "root", "")
or die ("Non riesco a creare la connessione");
vi ricordate
A
B
t
true
t
true
true
false
false
true
false false
A | | B se A è true non è necessario
va uta e B...
valutare
... tanto
ta to il risultato
su tato farà
aà
comunque true!
true ⇒l'interprete non lo valuta
true ⇒B viene valutato (interpretato)
solo se A è false
false
t
true
⇒ se mysql_connect riesce a creare una connessione:
• valore di ritorno = id della connessione, assimilabile a true
• la funzione die non viene valutata
⇒ se mysql_connect non riesce a creare una connessione:
• valore di ritorno = false
• la funzione die viene valutata (termina il processo e scrive il
messaggio)
Goy - a.a. 2009/2010
Programmazione Web
27
PHP e MySQL: interazione – III
2.
Selezionare un database
mysql_select_db("bacheca") or die ("Non trovo il DB");
seleziono un database: la funzione mysql_select_db
ha 2 argomenti: il nome del db (obbligatorio) e la
connessione (opzionale: se non viene specificata si
usa l'ultima connessione aperta); restituisce true in
caso di successo, false in caso di fallimento (posso
invocarla assegnando il suo risultato ad una variabile:
$db_selected = mysql_select_db("bacheca") or...
ma non è necessario...)
se la funzione mysql_select_db provoca un errore
(restituisce false), allora viene eseguita (valutata) la
funzione die, che termina il processo e scrive il
messaggio
Goy - a.a. 2009/2010
Programmazione Web
28
14
PHP e MySQL: lettura – I
3.
VEDI provaDB1.php
Inviare al DB Server una query SQL:
a. definire la query
b. inviarla al DB Server
$sql = "SELECT user_id, nome, cognome FROM utenti
WHERE cognome = 'Rossi'";
Rossi ;
$ris = mysql_query($sql) or die ("Query fallita!");
creo una stringa contenente
la query SQL…
...e la invio al DB Server: la funzione mysql_query ha 2
argomenti: la query sql (stringa, obbligatorio) e la
connessione (opzionale: se non viene specificata si usa
l' lti connessione
l'ultima
i
aperta)
t )
$ris conterrà il risultato della query (diverso a seconda
del tipo di query: SELECT, INSERT, UPDATE, DELETE, ...)
Se abbiamo inviato una SELECT $ris contiene un recordset,
cioè una lista di record
Goy - a.a. 2009/2010
Programmazione Web
29
VEDI provaDB1.php
PHP e MySQL: lettura – II
4.
Eventualmente [nel caso di una SELECT], estrarre (e
visualizzare) i dati contenuti nel risultato della query
(recordset = lista di record):
while ($riga = mysql_fetch_array($ris)) {
echo
h $
$riga["nome"]
i ["
"] . " "
";
echo $riga["cognome"] . "<br>";
}
con un ciclo, leggo uno per uno i record contenuti nel risultato
della query: la funzione mysql_fetch_array estrae dal suo
argomento ($ris) i record uno per volta (ad ogni ciclo);
il record estratto di volta in volta viene messo nella variabile
$riga; quando non ci sono più record da estrarre,
mysql_fetch_array restituisce false, la condizione
del while diventa falsa e il ciclo termina
il record corrente è una lista (array) associativa:
$riga[nomecampo] estrae il valore del campo
nomecampo; echo lo scrive sulla pagina
Goy - a.a. 2009/2010
Programmazione Web
30
15
PHP e MySQL: lettura – III
tabella utenti:
user_id cognome nome
email
1
2
3
data_n
Rossi
Mario
[email protected] 1999-04-25
Bianchi
Maria
[email protected]
1997-02-28
Rossi
Paola
[email protected]
1980-12-03
SELECT user_id, nome, cognome FROM utenti
WHERE cognome = 'Rossi'
$ris:
user_id cognome nome
1
3
Rossi
Mario
Rossi
oss
Paola
ao a
$riga = mysql_fetch_array($ris)
user_id cognome nome
$riga:
1
Rossi
Mario
user_id cognome nome
3
Rossi
Paola
1
Goy - a.a. 2009/2010
Rossi
Mario
Programmazione Web
31
PHP e MySQL: lettura – IV
$riga = mysql_fetch_array($ris)
$ris:
user_id cognome nome
$riga:
1
R i
Rossi
M i
Mario
user id cognome nome
user_id
3
Rossi
Paola
3
Rossi
Paola
eof
$riga = mysql_fetch_array($ris)
$riga: false ⇒ il ciclo si ferma (condizione falsa)
[NB while (pippo=false) è equivalente a while (false)
e while (pippo=true) è equivalente a while (true)]
NB Un record ($riga) in PHP è un array associativo ⇒
$riga['user_id'] → 3
$riga['cognome'] → Rossi
$riga['nome'] → Paola
Goy - a.a. 2009/2010
Programmazione Web
32
16
PHP e MySQL: interazione – IV
5.
Chiudere la connessione:
mysql_close();
chiudo la connessione a MySQL Server (la funzione
mysql
ysq _c
close
ose haa un
u argomento
a go e to opzionale,
op o a e, laa co
connnessione:
ess o e:
se non viene specificata si usa l'ultima connessione aperta)
Abbiamo visto l'uso di una query di tipo SELECT, cioè abbiamo
letto dei dati dal database (e li abbiamo visualizzati sulla
pagina web) = interrogazione del database
Vediamo adesso come fare a:
•
inserire nuovi dati (un nuovo record)
•
modificare
difi
d ti in
dati
i un recordd esistente
it t
•
cancellare dati (cancellare un record)
NB: l'unica cosa che cambia è il passo 3, cioè la formulazione
della query SQL (e viene omesso il passo 4)
Goy - a.a. 2009/2010
Programmazione Web
33
VEDI formDB2.html
PHP e MySQL: inserimento
VEDI provaDB2.php
Inserimento di un nuovo record:
$co = $_POST["cognome_ut"];
ipotizziamo che l'utente
$no = $_POST["nome_ut"];
abbia riempito un form
$em = $_POST["email_ut"];
con questi dati...
_
_
$dn = $_POST["nascita_ut"];
$conn = ...
mysql_select_db("bacheca")...
$sql = "INSERT INTO utenti (cognome,nome,email,data_n)
VALUES ('$co','$no','$em','$dn')";
$ris = mysql_query($sql)...
if (!$ris) {
echo "Query fallita!";
}
else {
echo "Inserito utente ".$co." ".$no;
}
mysql_close();
se $ris contiene false (!$ris vale true), significa
che l'inserimento ha prodotto un errore...
Goy - a.a. 2009/2010
Programmazione Web
34
17
VEDI formDB3.html
PHP e MySQL: modifica
Modifica di dati in un record:
VEDI provaDB3.php
ipotizziamo che l'utente
$old_em = $_POST["old_email"];
abbia cambiato l'email
$new_em = $_POST["new_email"];
attraverso un form...
$conn = ...
mysql select db("bacheca")
mysql_select_db(
bacheca )...
$sql = "UPDATE utenti SET email='$new_em'
WHERE email='$old_em'";
$ris = mysql_query($sql)...
if (!$ris) {
echo "Query fallita!";
}
else {
echo "Modificato email".$old_em." in ".$new_em;
}
mysql_close();
se $ris contiene false (!$ris vale true), significa
che l'aggiornamento ha prodotto un errore...
Goy - a.a. 2009/2010
Programmazione Web
35
VEDI formDB4.html
PHP e MySQL: modifica
Cancellazione di un record:
VEDI provaDB4.php
ipotizziamo che l'utente abbia
$em = $_POST["email_todel"]; chiesto la cancellazione dei
$conn = ...
suoi dati indicando l'email...
mysql_select_db("bacheca")...
$sql = "DELETE
DELETE FROM utenti WHERE email='$em'";
email= $em ;
$ris = mysql_query($sql)...
if (!$ris) {
echo "Query fallita!";
}
else {
echo "Cancellato utente ".$em;
}
mysql_close();
se $ris contiene
i
f l (!$ris vale
false
l true),
) significa
i ifi
che la cancellazione ha prodotto un errore...
Goy - a.a. 2009/2010
Programmazione Web
36
18
PHP e MySQL: parametri connessione - I
Per evitare di avere i parametri necessari alla connessione
(nome dell'host, nome-utente e password: parametri della
dalla funzione mysql_connect e nome del DB: parametro
della funzione mysql_select_db)
mysql select db) ripetuti in molti file (per
modificarli, occorrerebbe editare e modificare tutti i file che
li contengono) è buona norma definire, in un file separato,
quattro variabili; tale file viene incluso quando necessario
Per es, definiamo un file, varDB.inc, in cui:
<?php
$host="localhost";
$user="root";
$user=
root ;
$pwd="";
$db="bacheca"
?>
Goy - a.a. 2009/2010
Programmazione Web
37
PHP e MySQL: parametri connessione - II
... e dall'interno della pagine che accedono ai database
includiamo il file:
Per es:
<?php
include("varDB.inc");
...
$conn = mysql_connect($host, $user, $pwd) or die...
mysql_select_db($db)...
...
?>
NB: le variabili $host, $user, $pwd e $db sono definite
nel file varDB.inc
varDB inc
Attenzione! Questa modalità è obbligatoria nel progetto
d'esame!
Goy - a.a. 2009/2010
Programmazione Web
38
19
PHP e MySQL: miglioramenti... necessari! - I
Le interazioni viste sin qui sono i "mattoncini" di base; affinché
un'interazione sia "corretta" sono necessari maggiori controlli
Per es, quando inseriamo un nuovo utente nel database è bene
controllare se è già presente
⇒ il passo 3 diventa:
$sql_1 = "SELECT * FROM utenti WHERE email='$em'";
$ris_1 = mysql_query($sql_1) or die ("Query 1 fallita!");
if (mysql_num_rows($ris_1) != 0) {
echo "un utente con questa email è già presente nel DB";
}
else {
$ l 2 = "INSERT INTO utenti
$sql_2
t ti (
(cognome,nome,email,data_n)
il d t
)
VALUES ('$co','$no','$em','$dn')";
$ris_2 = mysql_query($sql_2) or die ("Query 2 fallita!");
}
Goy - a.a. 2009/2010
Programmazione Web
39
PHP e MySQL: miglioramenti... necessari! - II
NB1:
• mysql_num_rows(risID) restituisce il numero di righe
(record) presenti nel risultato della query (recordset = risID)
* usato con SELECT *
• mysql_affected_rows() restituisce il numero di righe
(record) modificate dalla query
* usato con INSERT, UPDATE, DELETE *
Per es, se volete controllare l'esito di un'UPDATE:
$sql = "UPDATE utenti SET email='$new_em'
WHERE email='$old_em'";
$ris = mysql
$
y q _q
query($sql)
y($ q ) or die (
("Query
Q
y fallita!");
);
if (mysql_affected_rows() = = 0) {
echo "Attenzione! L'update non è stato effettuato";
}
Goy - a.a. 2009/2010
Programmazione Web
40
20
PHP e MySQL: miglioramenti... necessari! - III
NB2: Anche quando fate un'update o una delete è comunque
opportuno controllare prima se il record da modificare/cancellare
esiste... :
$sql_1 = "SELECT * FROM utenti WHERE email='$em'";
$ris 1 = m
$ris_1
mysql_query($sql_1)
sql q er ($sql 1) or die ("Q
("Query
er 1 fallita!")
fallita!");
if (mysql_num_rows($ris_1) = = 0) {
echo "L'utente con l'email indicta non esiste";
}
else {
$sql_2 = "UPDATE utenti SET email='$new_em'
WHERE email='$old_em'";
/* oppure
$sql_2 = "DELETE FROM utenti WHERE email='$em'";
*/
$ris_2 = mysql_query($sql_2) or die ("Query 2 fallita!");
}
Goy - a.a. 2009/2010
Programmazione Web
41
21