Il sito per imparare gratuitamente a fare pagine Web

Corso PHP














Questa guida non è stampabile per volontà del suo stesso autore Claudio Curci.



Guida PHP scritta da Claudio Curci - Aggiornamenti di Max Kiusso

lezione 9: Un guestbook PHP "robusto"

Sommario lezione

. "Attacchiamo" il nostro guestbook
. Primo attacco: leggiamo un guest vuoto..
. Secondo attacco: messaggi "velenosi"
. terzo attacco: errore nella query
. Reference mysql - campi numerici
. compitini



"Attacchiamo" il nostro guestbook

Nella scorsa lezione abbiamo creato un guestbook. L'applicazione funziona, ma necessita di modifiche. Quello che manca è il controllo degli errori, la cosidetta "gestione delle eccezioni".
Prendiamo spunto dal nostro guestbook per introdurre un concetto fondamentale quanto trascurato (almeno sui manuali che leggete di solito in Italia) della programmazione: il testing.
E' abitudine diffusa quella di eseguire test e verifiche superficiali, o addirittura di controllare un programma soltanto quando è terminata la stesura del codice.

Il test (almeno così insegnano nei college americani..) è invece una parte integrante del processo di sviluppo del programma. Due docenti del Brooklyn College, David Arnow e Gerald Weiss, dichiarano senza mezzi termini: "se non effettuerete la verifica vi garantirete il fallimento del vostro programma e di tutti gli sforzi che gli avete dedicato". Nella scorsa lezione abbiamo creato un guestbook: vediamo se quanto affermato da questi due professori ("fallimento del programma e degli sforzi") è vero.

Un test va effettuato ipotizzando diverse operazioni e contesti. Per prima cosa andiamo a cancellare dal database tutti i dati finora inseriti nella tabella dei messaggi. Uno dei test che andremo ad eseguire sarà, infatti, proprio quello di verificare cosa accade quando un utente accede alla pagina di lettura "read_guest.php" senza che sia stato inserito un messaggio.

Riepiloghiamo i tre file del nostro guestbook:

. il file form.html per l'inserimento dei dati;

<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Inserisci dati</title>
</head>
<body>
<form name="moduloGuest" action="elabora_guest.php" method="post">
<table>
<tr>
<td>Il tuo nome:</td><td><input type="text" name="nome_utente" size="30" maxlength="40"></td>
</tr>
<tr>
<td valign="top">Il tuo messaggio:</td><td><textarea name="testo" cols="30" rows="6"></textarea></td>
</tr>
<tr>
<td align="center" colspan="2"><input type="submit" value="Invia il messaggio!"></td>
</tr>
</table>
</form>
</body>
</html>

. il file elabora_guest.php per l'elaborazione dei dati provenienti da form.html;

<?php
$connessione=mysql_connect("localhost", "root", "");
$selezione_db=mysql_select_db("guestbook", $connessione);
?>
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Corso PHP</title>
</head>
<body>
<?php
$inserimento=mysql_query("insert into messaggi (nome_utente, messaggio, data_ora) values ('" . $_POST['nome_utente'] . "', '" . $_POST['testo'] . "', now())");
echo "messaggio inviato con successo";
?>
</body>
</html>

. il file read_guest.php per la lettura del database

<?php
$connessione=mysql_connect("localhost", "root", "");
$selezione_db=mysql_select_db("guestbook", $connessione);
?>
<html>
<head>
<title>Leggi il guestbook!</title>
</head>
<body>
<?php
$lettura_risultati=mysql_query("select nome_utente, messaggio, date_format(data_ora, 'in data %d/%m/%Y - ore %H:%i:%s') as data_formattata from messaggi order by data_ora");
  while($scatola_temporanea=mysql_fetch_array($lettura_risultati)){
    echo "L'utente " . $scatola_temporanea['nome_utente'] . ", " . $scatola_temporanea['data_formattata'] . ", ha scritto:<br><br>" . $scatola_temporanea['messaggio'] . "<br><br><br>";
  } //fine ciclo while che scorre la query e piazza i risultati nell'array temporaneo
?>
</body>
</html>

Primo attacco: leggiamo un guest vuoto..

Lanciate adesso easyphp e collegatevi con phpMyAdmin al database "guestbook". Nella textarea digitate la query che svuota tutta la tabella dei messaggi. L'istruzione da eseguire, in SQL, è:

DELETE FROM nomeTabella

Quindi, nel nostro caso:



ATTENZIONE: come detto in un'altra lezione, le operazioni eseguite con un database non possono essere annullate. Non credo ci siano problemi in questo caso (se avete un guestbook in locale, si tratta di sicuro di una prova.. a meno che non vi scriviate messaggi da soli :), ma tenetelo presente per il futuro.

Lanciamo adesso il file read_guest.php. Cosa accade? Viene mostrata una pagina bianca. Non trovando più record nella query, il ciclo while non inizia (la variabile nella quale avevamo memorizzato il risultato è vuota).
Anche se non abbiamo ricevuto messaggi di errore, ci troviamo di fronte ad un codice carente. Intanto è uno spreco di risorse dire a PHP di eseguire un ciclo while su un insieme vuoto. Sarebbe come dire a qualcuno di andare a comprare qualcosa al supermercato proprio nel giorno di chiusura settimanale.
Sarebbe inoltre corretto e professionale mostrare all'utente un messaggio di avvertimento, del tipo "il guestbook per ora è vuoto.. perchè non corri tu ad inserire il primo messaggio?".

Risolviamo il primo problema della giornata. Questa sarà una lezione particolare, perchè vedremo diverse "piccole" ma fondamentali istruzioni che ci serviranno per tutte le applicazioni che svilupperemo (in questo corso e fuori). Inoltre, illustreremo alcune tecniche di testing. Una lezione da stampare, ripiegare e.. tenere dentro al portafoglio, come la foto di Maradona insomma :)

PHP offre diverse funzioni per l'accesso ai database. Ne abbiamo già utilizzate alcune, per la connessione e selezione db, per l'esecuzione di una query, per l'analisi dei risultati.
mysql_num_rows() restituisce il numero di record risultanti da una query. Grazie a questa funzione e alle istruzioni condizionali IF viste nelle prime lezioni, possiamo "istruire" la nostra pagina read_guest in questo modo:

se la query ha trovato record (evidentemente ci sono messaggi nella tabella), esegui il ciclo while e stampa i risultati;
altrimenti mostra un messaggio a video per avvertire l'utente.

Il costrutto IF/ELSE valuta ovviamente la prima condizione. Se questa è vera, l'else non viene neanche letto.
E' bene quindi, per ottimizzare le risorse e rendere il codice più leggibile, inserire nel primo IF l'istruzione che presumiamo venga valutata vera più frequentemente. Nel nostro caso, appena un utente avrà inserito un messaggio nel guestbook, l' IF che valuta se la query è vuota non sarà mai più eseguito. Ha senso quindi inserire nel primo IF il caso in cui la query restituisce risultati, visto che dopo il primo messaggio sarà sempre vera.

Il nostro codice read_guest.php diventa (per comodità inserisco solo la parte PHP della query, ovviamente non dimenticate i normali tag html e lo script iniziale di connessione):

<?php
$lettura_risultati=mysql_query("select nome_utente, messaggio, date_format(data_ora, 'in data %d/%m/%Y - ore %H:%i:%s') as data_formattata from messaggi order by data_ora");
if(mysql_num_rows($lettura_risultati)>0){
  while($scatola_temporanea=mysql_fetch_array($lettura_risultati)){
    echo "L'utente " . $scatola_temporanea['nome_utente'] . ", " . $scatola_temporanea['data_formattata'] . ", ha scritto:<br><br>" . $scatola_temporanea['messaggio'] . "<br><br><br>";
  } //fine ciclo while che scorre la query e piazza i risultati nell'array temporaneo
}
else{ //se non ha trovato record
  echo "complimenti! nessuno ha finora inserito un messaggio.. tu puoi essere il primo!! <a href=\"form.html\">che aspetti??</a>";
}
?>

Lanciate adesso, con la tabella messaggi ancora vuota, il file read_guest.php e sperimentate il vostro guest... più robusto.

Secondo attacco: messaggi "velenosi"

Provate a lanciare il vostro guestbook e a digitare, anzichè un normale messaggio, del codice javascript:



Andate adesso a leggere i messaggi.. lo script viene inserito nell'html e quindi normalmente interpretato! Questo è un bug non indifferente.. basta un normale javascript per reindirizzare la pagina verso un altro sito, far scaricare dialer, virus.. E' necessario correre subito ai ripari!!!
In realtà la soluzione è semplice. E' la stessa che utilizzo per questa guida. Se date un'occhiata all'html di questa pagina, trovate che i tag inseriti come esempio nel corso (quelli su sfondo verdino per intenderci) vengono stampati come tali e non interpretati. Invece di scrivere "<?php", utilizzo il carattere "&lt;".
Per evitare che un'istruzione html venga interpretata, basterà sostituire tutti i segni di inizio e fine tag con i corrispettivi codici speciali. PHP offre due funzioni per questo scopo: htmlspecialchars e htmlentities. Sono due funzioni pressochè identiche, la prima converte i tag e i caratteri speciali, la seconda anche le lettere accentate.
Ad esempio, con htmlentites, se un utente scrivesse "è", il testo verrebbe trasformato in &egrave. Con htmlspecialchars verrebbe lasciato comunque il carattere accentato. L'utente non si accorgerebbe della differenza se non visualizzando l'html della pagina. Se abbiamo a che fare con utenti e browser stranieri, conviene usare htmlentities.
Per i nostri esempi useremo htmlspecialchar, ma la procedura è la stessa.

A questo punto abbiamo due possibilità: usare la funzione htmlspecialchars prima dell'inserimento nel database oppure dopo, in fase di lettura.
La prima soluzione è migliore perchè viene eseguita una volta per tutte. Una volta che abbiamo inserito nel db la stringa corretta ed "innocua", possiamo leggerla in read_guest senza problemi. Usando l'approccio inverso, memorizzeremmo la stringa "pericolosa" nel db, e la formatteremmo ogni volta in read_guest. Nel nostro caso, conviene il primo approccio.
Per un guestbook va bene così, ma per un forum o per qualsiasi altro strumento che deve mettere a disposizione anche la possibilità di modificare il testo, conviene memorizzare la stringa cosi come è stata inserita. In fase di modifica, infatti, avremmo di sicuro un'altra textarea, che a differenza del resto della pagina scrive il codice cosi come lo trova. Un tag "<script>" "immunizzato" verrebbe stampato in una textarea cosi come nel codice, ovvero &lt;script&gt;. In fase di modifica dati sarebbe davvero difficile cambiare qualcosa del testo precedentemente inserito.
Quando abbiamo a che fare con qualcosa che andrà modificato, possiamo memorizzare nel db la stringa originale, e formattarla ogni volta in fase di lettura. A voi la scelta.
Torniamo al nostro guest e cambiamo il codice di inserimento in questo modo:

<?php
$nome_utente_formattato=htmlspecialchars($_POST['nome_utente']);
$messaggio_formattato=htmlspecialchars($_POST['testo']);
$inserimento=mysql_query("insert into messaggi (nome_utente, messaggio, data_ora) values ('" . $nome_utente_formattato . "', '" . $messaggio_formattato . "', now())");
echo "messaggio inviato con successo";
?>

Provate, anche in questo caso, ad inserire un javascript nel messaggio e valutate la risposta del book.
PHP dispone di un'altra istruzione, strip_tags, che consente di eliminare i tag html/php inseriti in una stringa.
A differenza di htmlspecialchars però, i tag non vengono convertiti in codice, ma completamente eliminati. Potete utilizzare strip_tags quando avete a che fare con stringhe che sicuramente non conterranno codice html scritto per scopi legittimi. In un sito come web-link sarebbe assurdo utilizzare strip_tags nel forum, visto che si parla proprio di codice ed è bene che gli utenti possano postare i loro script. Se avete un sito in cui gli utenti non discuteranno mai di programmazione, potete utilizzare strip_tags.
Un esempio veloce di questa funzione (il meccanismo è lo stesso di htmlspecialchars):

<?php
$nome_utente_formattato=strip_tags($_POST['nome_utente']);
$messaggio_formattato=strip_tags($_POST['testo']);
$inserimento=mysql_query("insert into messaggi (nome_utente, messaggio, data_ora) values ('" . $nome_utente_formattato . "', '" . $messaggio_formattato . "', now())");
echo "messaggio inviato con successo";
?>

Testate questo script inserendo il solito javascript. Nel database verrà memorizzata soltanto l'istruzione "alert(messaggio)", ma non i tag di apertura e chiusura script.
strip_tags dispone di un parametro opzionale che permette di specificare eventuali tag consentiti:

<?php
$nome_utente_formattato=strip_tags($_POST['nome_utente'],"<i>,</i>");
$messaggio_formattato=strip_tags($_POST['testo'],"<i>,</i>");
$inserimento=mysql_query("insert into messaggi (nome_utente, messaggio, data_ora) values ('" . $nome_utente_formattato . "', '" . $messaggio_formattato . "', now())");
echo "messaggio inviato con successo";
?>

Eseguite il testing inserendo, in uno stesso messaggio, un javascript e un tag di apertura/chiusura corsivo. Nel read_guest troverete il corsivo interpretato, lo script no.

Altra cosa da considerare sono eventuali apici all'interno delle stringhe; questo potrebbe compromettere la query, quindi andrebbe sempre utilizzato addslashes()

$inserimento=mysql_query("insert into messaggi (nome_utente, messaggio, data_ora) values ('" . addslashes( $nome_utente_formattato ) . "', '" . addslashes( $messaggio_formattato ) . "', now())");

In fase di estrazione dei dati, poi, andrebbe sempre usato il suo antagonista, ovvero stripslashes()

echo "L'utente " . stripslashes( $scatola_temporanea['nome_utente'] ) . ", " . $scatola_temporanea['data_formattata'] . ", ha scritto:<br><br>" . stripslashes( $scatola_temporanea['messaggio'] ) . "<br><br><br>";
terzo attacco: errore nella query

Proviamo a commettere, volutamente, un errore in fase di query. Cambiamo ad esempio in elabora_guest.php la stringa "storpiando" il nome della tabella:

$inserimento=mysql_query("insert into messaggisss (nome_utente, messaggio, data_ora) values ('" . addslashes( $nome_utente_formattato ) . "', '" . addslashes( $messaggio_formattato ) . "', now())");

Cosa accade? Il messaggio non viene ovviamente inserito (abbiamo cercato di interagire con la tabella "messaggisss"), eppure viene stampato a video il testo di invio avvenuto con successo.
Dobbiamo far capire al nostro script che, in caso di errore sulla query, deve restituire il messaggio relativo e magari aiutarci a risalire all'errore provocato.
Esiste in php una funzione, die() che "uccide" la pagina. Provate questo script:

<?php
echo "stampo la riga 1<br>\n";
echo "stampo la riga 2<br>\n";
die();
echo "stampo la riga 3<br>\n";
echo "stampo la riga 4<br>\n";
echo "stampo la riga 5<br>\n";
?>

Quando PHP trova l'istruzione die(), cessa l'esecuzione. In questo caso, vengono stampate solo le prime due righe. Attenzione: l'istruzione die() "uccide" l'intera pagina, quindi non vengono eseguite neanche eventuali istruzioni html successive. E' come se il file venisse troncato in quel punto.
die(), come ogni "assassino" che si rispetti, concede però al condannato un'ultimo desiderio.. ovvero l'istruzione che trova tra parentesi. Prima di far "spirare" la pagina, esegue l'eventuale comando che trova come parametro.
Esiste in PHP un'altra istruzione, mysql_error(), che stampa a video l'eventuale errore derivante da una query mysql appena eseguita. Combinando le due funzioni in questo modo: die(mysql_error()), possiamo risalire all'errore ed evitare che la pagina continui l'esecuzione e magari mostri imperterrita il messaggio di "invio riuscito".
Resta un problema.. come far capire a php che in caso di errore deve "uccidere" la pagina e, in caso di successo, andare avanti? Solitamente una funzione, oltre ad eseguire un compito, ritorna un valore. Se è andata a buon fine, ritorna valore 1, altrimenti zero.
mysql_query() non fa eccezione. Guardate questo codice:

<?php
$nome_utente_formattato=htmlspecialchars($_POST['nome_utente']);
$messaggio_formattato=htmlspecialchars($_POST['testo']);
$inserimento=mysql_query("insert into messaggisss (nome_utente, messaggio, data_ora) values ('" . addslashes( $nome_utente_formattato ) . "', '" . addslashes( $messaggio_formattato ) . "', now())"); if($inserimento==1){
echo "tutto ok";
}
else{
echo mysql_error();
}
?>

Il valore di ritorno di una funzione è un cosidetto booleano. In PHP un booleano può essere identificato indistintamente da zero/uno o da false/true. Se sostituite "$inserimento==1" con "$inserimento==true", ottenete lo stesso risultato.
Nell'esempio sopra non abbiamo utilizzato l'istruzione die(). In effetti si tratta di un file semplice: una volta stampato a video il messaggio (errore o successo che sia), non ci sono altre istruzioni da eseguire. Come ogni assassino che si rispetti, non ce la prendiamo con.. chi ha vita breve :)

Immaginate però di avere a che fare con un file che, oltre ad elaborare una form, continui eseguendo altre operazioni sul database (magari altre query su altre tabelle in caso di un modulo complesso).. se è andata male la prima query, non ha senso che la pagina continui l'esecuzione. In casi come questo è bene usare die(). A titolo d'esempio, lo utilizziamo anche nel nostro elabora_guest. Eseguite questo codice (ovviamente, sempre inviando prima dati dalla form):

<?php
$nome_utente_formattato=htmlspecialchars($_POST['nome_utente']);
$messaggio_formattato=htmlspecialchars($_POST['testo']);
$inserimento=mysql_query("insert into messaggisss (nome_utente, messaggio, data_ora) values ('" . addslashes( $nome_utente_formattato ) . "', '" . addslashes( $messaggio_formattato ) . "', now())"); if($inserimento==1){
echo "tutto ok";
}
else{
echo mysql_error();
die();
}
?>

Unica differenza, rispetto al codice precedente, è che dopo l'istruzione die() la pagina non continua (non trovate neanche i tag body e html di chiusura).

Abbiamo accennato prima al fatto che die() può ricevere come parametro un'ultima istruzione da eseguire, quindi le due righe del costrutto "else" possono essere riunite in una sola:

die(mysql_error());

Quanto al messaggio restituito dalla pagina, è eloquente: "Table 'guestbook.messaggis' doesn't exist". Un bell'aiuto in fase di sviluppo e testing.
Approfittiamo del discorso per introdurre un altro costrutto del linguaggio PHP: l'operatore or.
In realtà non si tratta di nulla di nuovo, solo di una scorciatoia per evitare, in casi come il precedente, di utilizzare diversi if derivanti dal risultato di una funzione.
Il senso è facilmente intuibile: "esegui quest'operazione, se va bene metti il risultato in una variabile, altrimenti..".
Credo che un'occhiata al codice sia più eloquente:

<?php
$nome_utente_formattato=htmlspecialchars($_POST['nome_utente']);
$messaggio_formattato=htmlspecialchars($_POST['testo']);
$inserimento=mysql_query("insert into messaggisss (nome_utente, messaggio, data_ora) values ('" . addslashes( $nome_utente_formattato ) . "', '" . addslashes( $messaggio_formattato ) . "', now())") or die( mysql_error() );
?>

L'utilizzo dell'operatore or rende più rapide alcune istruzioni (immaginate di avere a che fare con decine di query in un'unica pagina e di dover scrivere, per ciascuna, i vari if..else) ma, in caso di operazioni complesse (finora ci siamo limitati alla stampa di un messaggio..) diventa improponibile.
Quando impareremo ad interagire con le function, potremo tornare sull'argomento. Per ora limitatevi (come fanno molti, tra l'altro.. basta dare un'occhiata agli script in giro per la rete) ad usare l'operatore die(mysql_error()).
La nuova release dei file elabora_guest e read_guest diventa pertanto:

<?php
$nome_utente_formattato=htmlspecialchars($_POST['nome_utente']);
$messaggio_formattato=htmlspecialchars($_POST['testo']);
$inserimento=mysql_query("insert into messaggi (nome_utente, messaggio, data_ora) values ('" . addslashes( $nome_utente_formattato ) . "', '" . addslashes( $messaggio_formattato ) . "', now())") or die( mysql_error() );
?>


$lettura_risultati=mysql_query("select nome_utente, messaggio, date_format(data_ora, 'in data %d/%m/%Y - ore %H:%i:%s') as data_formattata from messaggi order by data_ora")or(die(mysql_error()));
if(mysql_num_rows($lettura_risultati)>0){
  while($scatola_temporanea=mysql_fetch_array($lettura_risultati)){
    echo "L'utente " . stripslashes( $scatola_temporanea['nome_utente'] ) . ", " . $scatola_temporanea['data_formattata'] . ", ha scritto:<br><br>" . stripslashes( $scatola_temporanea['messaggio'] ) . "<br><br><br>";
  } //fine ciclo while che scorre la query e piazza i risultati nell'array temporaneo
}
else{ //se non ha trovato record
echo "complimenti! nessuno ha finora inserito un messaggio.. tu puoi essere il primo!! <a href=\"form.html\">che aspetti??</a>";
}
?>

Reference mysql - campi numerici

Trovate in questa sezione un'utilissima tabella riepilogativa delle principali funzioni PHP e mysql. E' una parte da tenere sempre a portata di.. mouse, almeno finchè non avete sviluppato tanto codice da saper tutto a memoria :)
Come ho spesso ricordato, questo non è un corso teorico o accademico, ma uno strumento che possa consentire agli utenti di diventare il più operativi possibile. In questa reference non trovate quindi la lunghezza e il massimo valore che può contenere un campo, ma suggerimenti e commenti per farvi capire quando va usato. Se volete sapere che un campo BIGINT può contenere un valore fino a 18446744073709551615, potete consultare mysql.com nella sezione "documentation". E' in inglese, ma la sezione sui tipi di campo è molto schematica.
Riepilogare tutte le funzioni e i tipi di campo mysql è un'operazione che, da sola, necessita di una lezione intera.
Già vedo tazzine di caffè e sbadigli..
Tranquilli, da questa lezione "spalmeremo" l'argomento, rendendolo più digeribile.

1) Tipi di campo mysql: valori numerici
I tipi numerici possono contenere numeri interi, positivi e negativi, e decimali. A questo scopo, mysql offre diversi tipi di campo, dal tynint (che contiene valori fino a 255) al bigint (fino a 18446744073709551615..).
Sta quindi al programmatore scegliere accuratamente, in fase di progettazione, il giusto campo. Ricordate che se scegliete un campo troppo piccolo, qualsiasi valore superiore al range viene troncato al massimo. Ad esempio, se inserite il valore 567 in un campo tynint, troverete memorizzato 255.
D'altra parte, scegliere un campo eccessivamente ampio danneggia le prestazioni del database e occupa memoria. Un campo BIGINT utilizzerà sempre gli stessi byte, sia che memorizziate il numero di soldi di Berlusconi sia che memorizziate il numero di scudetti vinti dalla Fiorentina.

Questi sono i campi numerici mysql (a fianco ho messo qualche consiglio):

. tinyint, memorizza fino a 255. Può essere utile quando dobbiamo memorizzare piccole cifre, ad esempio i punti delle squadre del nostro campionato di calcio. Se una squadra vincesse tutte le 34 partite del calendario, non arriverebbe nemmeno alla metà del range di un tinyint;

. mediumint, arriva fino a 65535;

. int,(o integer) memorizza valori oltre i 4 miliardi. Se dovete creare un contatore auto_increment, utilizzate questo campo. Ricordate che un contatore viene incrementato anche se create un record e lo eliminate subito dopo. In questo caso, è bene "spendere" memoria;

. bigint, memorizza valori enormi, come detto in precedenza;

. float, numero a precisione singola. Potete utilizzare questo campo per valori con virgola e decimali (classico esempio, valute euro);

. double, a precisione doppia. Offre maggiore precisione di float ma occupa più spazio;

. decimal, memorizza numeri decimali trattandoli però come stringhe. Ogni cifra viene trattata come un carattere, cosi come il separatore dei decimali e l'eventuale segno.

I valori numerici accettano degli attributi. Un numero può infatti essere dichiarato:

. auto_increment, tipico campo utilizzato per creare chiavi univoche;

. zerofill (solo per interi). In questo campo i numeri vengono riempiti, da sinistra, con degli zeri.

Esempio pratico:
se dichiariamo un campo INT(4) zerofill, e inseriamo il numero 427, nel db verrà memorizzato "0427". Se lo dichiariamo int(11), avremo "00000000427". Attenzione: quando trovate un numero tra parentesi, dopo un campo intero, questo non incide sulla memorizzazione delle cifre. Un INT(11) ha lo stesso range di un INT(4). Se il campo è dichiarato zerofill, cambierà il numero di zeri che precede il valore inserito. Tutto qui.

. unsigned / signed. Se un campo è dichiarato "signed", può memorizzare valori positivi e negativi. Il range viene però dimezzato. Ad esempio, un campo tinyint può memorizzare, unsigned, da 0 a 255. Un tinyint signed invece ha come range -128 e 127.

. not null, ovvero "campo obbligatorio". Se cercate di inserire nella tabella un record con un campo vuoto dove invece è richiesto "not null", la query genera errore.



Compitini

Ecco qualche esercizio per questa settimana:

. realizzate un modulo per l'iscrizione degli utenti al vostro sito. La form deve contenere nome/cognome, username e password. I dati devono ovviamente essere memorizzati nel db. Attenzione: non deve essere possibile inserire utenti con stesso username. Se già esiste un username "maradona", e un utente prova ad iscriversi con quell'alias, deve apparire un messaggio di "iscrizione rifiutata". Difficile? Rileggete bene questa lezione, avete già tutti gli strumenti per farlo...

. quiz! :)

1) In un database, voglio memorizzare l'elenco di tutti gli abitanti del mio paese (più o meno 10mila persone). Che campo devo utilizzare per la chiave ID contatore?

2) In un database abbiamo una tabella "alunni" con questi campi:
. id (int, auto_increment);
. numero_matricola (int not null);
. nome (char 50),
. data_nascita (date)
la seguente query:
INSERT INTO alunni (numero_matricola,nome,data_nascita) values('23','Pinco Pallo','2012/01/21')
genera errore?

3) stessa tabella:

INSERT INTO alunni (id,numero_matricola,nome,data_nascita) values(11, 23,'Pinco Pallo','2012/01/21')
Cosa accade?

4) Ipotizziamo di voler integrare, in read_guest.php, lo script di stampa tabelle alternate delle prime lezioni. Ricordate? Lo script che ci permetteva di stampare delle righe di colore diverse. Senza lanciarlo con easyPhp/XAMPP, riuscite a capire se questo script funziona?

<?php
$lettura_risultati=mysql_query("select nome_utente, messaggio, date_format(data_ora, 'in data %d/%m/%Y - ore %H:%i:%s') as data_formattata from messaggi order by data_ora")or(die(mysql_error()));
if(mysql_num_rows($lettura_risultati)>0){
echo "<table>";
while($scatola_temporanea=mysql_fetch_array($lettura_risultati)){
$flag_colore=0;
echo "<tr>";
if($flag_colore==0){
echo "<td bgcolor=\"#FFFF00\">";
}
else{
echo "<td bgcolor=\"#C0C0C0\">";
}
echo "L'utente " . stripslashes( $scatola_temporanea['nome_utente'] ) . ", " . $scatola_temporanea['data_formattata'] . ", ha scritto:<br><br>" . stripslashes( $scatola_temporanea['messaggio'] ) . "</td>";
echo "</tr>";
} //fine ciclo while che scorre la query e piazza i risultati nell'array temporaneo
echo "</table>";
}
else{ //se non ha trovato record
echo "complimenti! nessuno ha finora inserito un messaggio.. tu puoi essere il primo!! <a href=\"form.html\">che aspetti??</a>";
}
?>


Se avete domande potete scrivere sul forum di supporto, gratuito e aperto a tutti.



Claudio Curci e Max Kiusso per Web-Link.it 


stampa per stampare questa pagina