Repository 32bit  Forum
Repository 64bit  Wiki

PHP Tutorial - Un Semplice Sito: differenze tra le versioni

Da Slacky.eu.
(Organizzazione)
(Cenni sulle connessioni cifrate)
 
(20 revisioni intermedie di 2 utenti non mostrate)
Riga 56: Riga 56:
<pre>http://www.slacky.eu/index.php?option=com_content...</pre>
<pre>http://www.slacky.eu/index.php?option=com_content...</pre>
In questo caso, alla variabile ''option'' è stato passato il valore ''com_content''. Quindi per conoscerne il valore, noi dobbiamo riferirci a <code>$_GET["option"]</code>.
In questo caso, alla variabile ''option'' è stato passato il valore ''com_content''. Quindi per conoscerne il valore, noi dobbiamo riferirci a <code>$_GET["option"]</code>.
  +
  +
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">Ogni comando php '''deve''' terminare con un punto e virgola!</div>
La condizione ''if-else'' scritta sopra si può rendere in forma più breve:
La condizione ''if-else'' scritta sopra si può rendere in forma più breve:
Riga 75: Riga 77:
?>
?>
</pre>
</pre>
Le definzioni di ''array'' si sprecano in rete. Noi, semplicemente, consideriamole un insieme di variabili che stanno nello stesso contenitore. Con la funzione ''foreach'', sfogliamo queste variabili come se fossero pagine di un libro e per ognuna di esse facciamo una determinata operazione...
+
Le definizioni di ''array'' si sprecano in rete. Noi, semplicemente, consideriamole un insieme di variabili che stanno nello stesso contenitore. Con la funzione ''foreach'', sfogliamo queste variabili come se fossero pagine di un libro e per ognuna di esse facciamo una determinata operazione...
Prima di continuare con il php, inseriamo, subito prima dello script, il tag '''ul''' (''unordered list'') e chiudiamolo subito dopo lo script.
Prima di continuare con il php, inseriamo, subito prima dello script, il tag '''ul''' (''unordered list'') e chiudiamolo subito dopo lo script.
Riga 88: Riga 90:
echo "
echo "
<li>";
<li>";
if($pagina!=$voce) echo '<a href="index.php?pagina=$voce">';
+
if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
echo $voce;
echo $voce;
if($pagina!=$voce) echo "</a>";
if($pagina!=$voce) echo "</a>";
Riga 102: Riga 104:
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
Quando con ''echo'' bisogna far visualizzare una stringa contenente degli apici ("), bisogna racchiuderla in apici semplici ('); altrimenti, avremmo potuto usare la forma
+
Quando con ''echo'' bisogna far visualizzare una stringa contenente degli apici ("), bisogna racchiuderla in apici semplici ('); in questi casi, le variabili devono essere poste al di fuori della stringa, usando il carattere di concatenamento <code>.</code>. Altrimenti, avremmo potuto usare la forma
<pre>echo "<a href=\"index.php?pagina=$voce\">";</pre>
<pre>echo "<a href=\"index.php?pagina=$voce\">";</pre>
oppure ancora
oppure ancora
Riga 109: Riga 111:
EOT;
EOT;
</pre>
</pre>
Ma quest'ultima forma è preferibile per porzioni di testo più estese.
+
Ma quest'ultima forma (cosiddetta ''heredoc'') è preferibile per porzioni di testo più estese. A tale proposito, bisogna tener presente che il marcatore di chiusura (in questo caso ''EOT'', ma possiamo mettere quello che vogliamo...) non deve avere spazi né prima (niente indentazione, quindi) né dopo.
</div>
</div>
Riga 127: Riga 129:
echo "
echo "
<li>";
<li>";
if($pagina!=$voce) echo '<a href="index.php?pagina=$voce">';
+
if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
echo $voce;
echo $voce;
if($pagina!=$voce) echo "</a>";
if($pagina!=$voce) echo "</a>";
Riga 194: Riga 196:
echo "
echo "
<li>";
<li>";
if($pagina!=$voce) echo '<a href="index.php?pagina=$voce">';
+
if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
echo $voce;
echo $voce;
if($pagina!=$voce) echo "</a>";
if($pagina!=$voce) echo "</a>";
Riga 247: Riga 249:
</pre>
</pre>
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
Da notare come nella ''query-string'' <code>index.php?page=home&amp;amp;sezione=principale</code>, la prima variabile viene assegnata dopo il <code>?</code>, le altre dopo <code>&amp;amp;</code>. Sarebbe bastato scrivere '''&amp;''', ma vremmo potuto avere qualche problema di validazione della pagina...
+
Da notare come nella ''query-string'' <code>index.php?page=home&amp;amp;sezione=principale</code>, la prima variabile viene assegnata dopo il <code>?</code>, le altre dopo <code>&amp;amp;</code>. Sarebbe bastato scrivere '''&amp;''', ma avremmo avuto problemi di validazione della pagina...
</div>
</div>
Proviamo di nuovo il tutto...
Proviamo di nuovo il tutto...
Riga 267: Riga 269:
Se l'orologio del nostro server è settato correttamente, ad ogni collegamento visualizzeremo data e ora precise.
Se l'orologio del nostro server è settato correttamente, ad ogni collegamento visualizzeremo data e ora precise.
  +
  +
== Organizzazione ==
== Organizzazione ==
Prima di continuare con il PHP, diamo un po' di organizzazione al nostro ''sito''.
Prima di continuare con il PHP, diamo un po' di organizzazione al nostro ''sito''.
Una cosa consigliabile è quella di inserire tutte le pagine interne in una sotto-cartella: creiamo, dunque, una sotto-cartella ''pagine'' e spostiamo tutti i file (tranne <code>index.php</code>) in essa. nella root del sito, deve rimanere, pertanto, solo la index.
+
Una cosa consigliabile è quella di inserire tutte le pagine interne in una sotto-cartella: creiamo, dunque, una sotto-cartella ''pagine'' e spostiamo tutti i file (tranne <code>index.php</code>) in essa. Nella root del sito, deve rimanere, pertanto, solo la index.
Ora apriamo la index e sostituiamo:
Ora apriamo la index e sostituiamo:
Riga 301: Riga 305:
<body>
<body>
<h1>Tutorial PHP</h1>
<h1>Tutorial PHP</h1>
  +
<?php
  +
$giorni=array("Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato");
  +
$giorno=$giorni[date("w")];
  +
$data=date("d/m/Y");
  +
$ora=date("H:i");
  +
echo "<p><em>$giorno $data - ore $ora</em></p>\n";
  +
?>
<hr />
<hr />
<ul><?php
<ul><?php
Riga 308: Riga 319:
echo "
echo "
<li>";
<li>";
if($pagina!=$voce) echo '<a href="index.php?pagina=$voce">';
+
if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
echo $voce;
echo $voce;
if($pagina!=$voce) echo "</a>";
if($pagina!=$voce) echo "</a>";
Riga 323: Riga 334:
</pre>
</pre>
== ToDo ==
+
== MySQL ==
Finora abbiamo visto solo una minima parte degli immensi orizzonti che il php ci apre. Cionostante, abbiamo realizzato un piccolo sito dinamico abbastanza funzionale.
+
&Egrave; bene precisare che MySQL non è l'unico database gestibile da PHP, anzi: PHP può pilotare, più o meno nativamente, la maggior parte dei database esistenti; i suoi ottimi e consolidati rapporti con MySQL, tuttavia, ce lo fanno preferire per un tutorial (e non solo).
Sono molti i campi che ancora dobbiamo toccare.
 
Una delle interazioni più efficaci ed affascinanti del PHP è quella con i database, in particolare con il DBMS opensource '''MySQL'''. Vedremo come sfruttare le capacità dinamiche di questa meravigliosa accoppiata...
+
L'impatto migliore che si possa avere con MySQL potrebbe essere quello che si verifica per il tramite della sua console. Tuttavia, se la cosa potesse risultare ostica, almeno per le prime volte, è altrettanto produttivo utilizzare un gestore organizzato, PhpMyAdmin, per esempio. In ogni caso, piuttosto che istruire come utilizare questo o quel gestore, è preferibile indicare le ''query'' in SQL, che, come vedremo, è un linguaggio molto semplice ed intuitivo (se la nostra lingua fosse l'inglese, ci sembrerebbe di discorrere col database...).
Vedremo, poi, come gli stessi risultati possano esere ottenuti con modalità alternative e come sia produttivo realizzare le nostre funzioni o, meglio, le nostre ''classi''. Ci addentreremo, pertanto, nella OOP (''object-oriented programming'').
+
Anche in questo caso, si presuppone che abbiate a disposizione MySQL perfettamente configurato e che siate in possesso di valide credenziali d'accesso...
Tutto con estrema semplicità...
+
Per accedere alla console di MySQL, basta digitare:
  +
<pre>
  +
mysql -u NOME-AMMINISTRATORE -p
  +
</pre>
  +
Inserita la password relativa a NOME-AMMINISTRATORE, saremmo ammessi nella console di MySQL:
  +
  +
<pre>
  +
Welcome to the MySQL monitor. Commands end with ; or \g.
  +
Your MySQL connection id is 51
  +
Server version: 5.0.51-log Source distribution
  +
  +
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
  +
  +
mysql>
  +
</pre>
  +
A questo punto, possiamo digitare comandi, eseguire query, etc.
  +
=== Il Database ===
  +
Trovandoci nella console di MySQL, digitiamo:
  +
<pre>CREATE DATABASE tutorial;</pre>
  +
Da notare come ogni comando deve terminare con un <code>;</code> (punto e virgola).
  +
  +
Fatto! Il nostro database è già stato creato. Ora si tratta di organizzarlo in tabelle.
  +
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
  +
&Egrave; opportuno scrivere le parole chiave di SQL in maiuscolo. Tuttavia, non è obbligatorio: SQL non è un linguaggio ''case-sensitive''.
  +
</div>
  +
  +
=== Le Tabelle ===
  +
Adesso procediamo alla creazione delle tabelle.
  +
  +
La discussione in merito ad una corretta formulazione del database esula da questo tutorial. E' importante precisare, però, che un database ben formato può fare ''la differenza''! Ci limitiamo a precisare alcuni punti fondamentali:
  +
* è assolutamente sbagliato intendere un database come un unico tabellone in cui, magari, ripetere gli stessi valori o lasciare vuote le celle che non servono; è molto più produttivo, piuttosto, creare diverse tabelle, relazionate tra loro e organizzate con logica;
  +
* le relazioni tra diversi campi si possono ricondurre a tre tipi fondamentali: '''uno a uno''', '''uno a diversi''', '''diversi a diversi'''; nel primo caso, è sufficiente una sola tabella (pensiamo, ad esempio, ad una tabella ''utenti-codicefiscale''); nel secondo caso sono necessarie due tabelle (ad esempio, in una relazione ''utenti-impiego'', sapendo che un ''impiego'' può essere condiviso da diversi ''utenti'', è produttivo creare una tabella ''impieghi'' ed una ''utenti'', dove l'impiego è richiamato solo dall'ID corrispondente all'opportuno record della tabella ''impieghi''); nel terzo caso, le tabelle da creare sarebbero tre (ad esempio, pensiamo di avere impiegati organizzati in team, ma anche che lo stesso impiegato possa essere incluso in diversi team: allora avremo la tabella ''utenti'', la tabella ''team'' e la tabella ''utenti_team'', che conterrà le relazioni, indicate solo con gli ID, tra impiegato e team).
  +
  +
Partendo da questi presupposti, procediamo alla creazione di quattro tabelle: ''utenti'', ''impieghi'', ''team'' e ''utenti_team''.
  +
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
  +
I nomi delle tabelle non devono contenere né spazi né caratteri speciali (limitiamoci a qualche ''underscore'' _ ).
  +
</div>
  +
E' ovvio che adesso diventi più facile operare con phpMyAdmin (per esempio), ma prendere un po' di confidenza con l'SQL non è affatto male (oltretutto, le tabelle potremmo farle creare dallo script php stesso...). Procediamo, quindi, nella nostra console mysql:
  +
<pre>
  +
CREATE TABLE utenti(
  +
ID mediumint(8) unsigned NOT NULL auto_increment,
  +
Nome varchar(255) NOT NULL,
  +
Impiego smallint(4) NOT NULL,
  +
PRIMARY KEY (ID)
  +
);
  +
</pre>
  +
Abbiamo creato una semplice tabella ''utenti'' con solo tre campi: ''ID'', ''Nome'' e ''Impiego''. Naturalmente possiamo inserire quanti altri campi vogliamo; l'importante è non cadere nell'errore comune di creare colonne a iosa che poi corrono il rischio di rimanere vuote. Il campo ''ID'', che rappresenta l'identificativo o ''chiave primaria'' della tabella (indicata con quel ''PRIMARY KEY'' alla fine) è definito con ''mediumint(8)'', ovvero è un intero con 8 cifre massime (di fatto, avendo il parametro ''unsigned'', è un intero compreso tra 0 e 16777215); il ''NOT NULL'' sta a indicare che il campo è obbligatorio; il parametro ''auto_increment'' fa sì che il numero aumenti automaticamente di uno ogni nuovo inserimento. Il campo ''Nome'', invece, è definito quale ''varchar(255)'', ovvero una stringa alfanumerica variabile con un massimo di 255 caratteri. Il campo ''Impiego'', infine, è definito con un intero inferiore (vedremo il perché...). Naturalmente, non sono solo questi i tipi di campo ammissibili in MySql (vedere, a questo proposito, i link segnalati in calce). Continuiamo con le nostre tabelle...
  +
<pre>
  +
CREATE TABLE impieghi(
  +
ID smallint(4) unsigned NOT NULL auto_increment,
  +
Nome varchar(255) NOT NULL,
  +
PRIMARY KEY (ID)
  +
);
  +
CREATE TABLE team(
  +
ID tinyint(3) unsigned NOT NULL auto_increment,
  +
Nome varchar(255) NOT NULL,
  +
PRIMARY KEY (ID)
  +
);
  +
CREATE TABLE utenti_team(
  +
ID mediumint(8) unsigned NOT NULL auto_increment,
  +
Utente mediumint(8) unsigned NOT NULL,
  +
Team tinyint(3) unsigned NOT NULL,
  +
PRIMARY KEY (ID)
  +
);
  +
</pre>
  +
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
  +
Una ''mancanza'' che salta agli occhi degli utenti più esperti è quella relativa alla definizione del tipo di tabella: per il momento, è inutile crearci complicazioni ed è meglio lasciare fare a ''Mr. Default'' (di solito, il tipo predefinito è ''MyIsam'').
  +
</div>
  +
Lo ''smallint(4)'' che avevamo visto nella colonna ''Impiego'' della tabella ''utenti'' lo ritroviamo nella tabella ''impieghi'' quale ''ID''. Questo sta a significare che quel numero richiamato alla colonna ''Impiego'' della tabella ''utenti'' è un riferimento diretto al record identificato con lo stesso numero nella tabella ''impieghi''. Lo stesso discorso vale per le colonne della tabella ''utenti_team''...
  +
  +
Il nostro piccolo database è pronto. Ora si tratta di ''popolarlo''...
  +
  +
===L'inserimento===
  +
  +
Per l'inserimento di ''record'' nelle tabelle, procederemo con il nostro principale argomento di studio, ovvero il PHP.
  +
  +
====Primo metodo: semplice ed esplicito====
  +
  +
Creiamo una nuova pagina interna con un form di inserimento:
  +
<pre>
  +
<div>
  +
<fieldset>
  +
<legend>Inserimento impieghi</legend>
  +
<form action="pagine/raccoltadati.php?azione=inserimento" method="post">
  +
<p><label for="Nome">&nbsp;<input type="text" name="Nome" /></p>
  +
<p>
  +
<input type="hidden" name="tabella" value="impieghi" />
  +
<input type="submit" value="inserisci" />
  +
</p>
  +
</form>
  +
</fieldset>
  +
</div>
  +
</pre>
  +
Salviamo col nome <code>inserimentoimpieghi.php</code> nella cartella ''pagine''. Com'è (quasi) ovvio, si tratta di inserire record nella tabella ''impieghi''. Non ci dovrebbero essere dubbi sul form. L'unica cosa, forse, da puntualizzare è che il nome della tabella, invece che con il campo ''hidden'', avremmo anche potuto passarlo allo script di raccolta direttamente nella ''query-string'' della ''action'' del form (query-string che sarebbe diventata ''raccoltadati.php?azione=inserimento&amp;amp;tabella=impieghi'').
  +
  +
Prima di passare allo script di raccolta dei dati, scriviamo un piccolo file dove immagazzinare in ''costanti'' le nostre credenziali di accesso al database:
  +
<pre>
  +
<?php
  +
define("COSTANTE_HOST","localhost");
  +
define("COSTANTE_UTENTE","nomeutente");
  +
define("COSTANTE_PASSWORD","passwordutente");
  +
define("COSTANTE_DATABASE","tutorial");
  +
?>
  +
</pre>
  +
Naturalmente, sostituiremo ''nomeutente'' con il nome del nostro amministratore del database e ''passwordutente'' con la sua password. Se il database risiede sullo stesso web-server, come host va bene ''localhost'', altrimenti sostituiamo con l'indirizzo del server del database. Salviamolo con nome <code>configurazione.php</code> nella stessa cartella ''pagine''. Questo file dovrà essere incluso ogniqualvolta dovremo connetterci al database.
  +
  +
Procediamo ora con lo script <code>raccoltadati.php</code>, salvandolo sempre nella cartella ''pagine'' (le parti di commento non sono necessarie per il funzionamento dello script, ma fanno praticamente parte del presente tutorial):
  +
<pre>
  +
<?php
  +
include("configurazione.php");
  +
// incluso il file dove sono contenute le credenziali, tenta la connessione al db
  +
// oppure lo script si ferma ("die") visualizzando l'errore in parametro
  +
$connessione=mysql_connect(COSTANTE_HOST,COSTANTE_UTENTE,COSTANTE_PASSWORD) or
  +
die("Problemi di connessione: controlla le credenziali");
  +
// ora sceglie il database
  +
mysql_select_db(COSTANTE_DATABASE) or die("Database non presente");
  +
// raccoglie l'azione da intraprendere dalla query-string;
  +
// le variabili così passate sono raccolte nell'array associativo "$_GET".
  +
$azione=$_GET["azione"];
  +
// primo caso: inserimento
  +
if($azione=="inserimento") {
  +
// raccoglie la tabella dal form (che ha metodo "post"); in questo caso,
  +
// l'array associativo che raccoglie le variabili è "$_POST"
  +
$tabella=$_POST["tabella"];
  +
// scriviamo la "query", differenziandola in base alla tabella (occhio alla sintassi)
  +
// il primo valore è vuoto ('') e sta ad indicare l'ID, che, come abbiamo visto,
  +
// si crea automaticamente con "auto_increment"
  +
if($tabella=="impieghi") $query="INSERT INTO $tabella VALUES('',".$_POST["Nome"].")";
  +
// eseguiamo la query e quindi torniamo alla index con la funzione "header" (che è
  +
// sempre buona norma far seguire da "exit"
  +
mysql_query($query) or die("Inserimento fallito");
  +
header("Location: ../index.php");
  +
exit;
  +
}
  +
?>
  +
</pre>
  +
Ora aggiungiamo la nuova pagina al menu della nostra index. Magari, senza nulla togliere al grande Totò, possiamo sostituire una di quelle pagine (''bazzecole'' etc.) che abbiamo messo per scherzo. Sostituiamo, quindi, nell'array del menu, ''inserimento-impieghi'' a ''bazzecole'' (per esempio).
  +
  +
Divertiamoci ad inserire degli impieghi. Poi verifichiamo dalla console di mysql (per ora), con...
  +
<pre>SELECT * FROM tutorial.impieghi;</pre>
  +
Io ho inserito un solo record:
  +
<pre>
  +
+----+---------------+
  +
| ID | Nome |
  +
+----+---------------+
  +
| 1 | programmatore |
  +
+----+---------------+
  +
1 row in set (0,00 sec)
  +
</pre>
  +
Fermiamoci a riflettere. Cosa abbiamo fatto?
  +
  +
I dati immessi per mezzo dl form sono confluiti nello script <code>raccoltadati</code> che li ha inseriti nel database tramite una query, che, per ora, è unica, ma che, con questo metodo, è destinata a cambiare in relazione alla tabella su cui andremo ad incidere. Tutto qui! Naturalmente, il nostro script è volutamente stringato: avremmo dovuto mettere almeno qualche routine di controllo dei dati inseriti e avremmo dovuto rendere i dati medesimi più ''digeribili'' al database... Ma il problema, adesso, è un altro: c'è qualcosa che non va, non è questa la potenza dello scripting lato-server e del php in particolare. La nostra soluzione non è ''elegante''.
  +
  +
Proviamo un altro metodo...
  +
  +
====Secondo metodo: un po' di alchimia====
  +
  +
Cominciamo con la pagina di configurazione. Aggiungiamo lì la connessione a mysql (così da non doverla ripetere in ogni pagina dove ce ne fosse bisogno):
  +
<pre>
  +
<?php
  +
define("COSTANTE_HOST","localhost");
  +
define("COSTANTE_UTENTE","nomeutente");
  +
define("COSTANTE_PASSWORD","passwordutente");
  +
define("COSTANTE_DATABASE","tutorial");
  +
$connessione=mysql_connect(COSTANTE_HOST,COSTANTE_UTENTE,COSTANTE_PASSWORD)
  +
or die("Problemi di connessione: controlla le credenziali");
  +
mysql_select_db(COSTANTE_DATABASE) or die("Database non presente");
  +
?>
  +
</pre>
  +
Modifichiamo radicalmente la pagina di inserimento:
  +
<pre>
  +
<div>
  +
<?php
  +
# Visto che ora la connessione serve anche qui, includiamo la pagina di configurazione.
  +
  +
include("pagine/configurazione.php");
  +
  +
# estraiamo tutte le tabelle dal database e, sfogliandole,
  +
#+ creiamo un form per ognuna
  +
  +
$querytabelle="SHOW TABLES";
  +
$risultatotabelle=mysql_query($querytabelle);
  +
while($righetabelle=mysql_fetch_row($risultatotabelle)) {
  +
$nometabella=$righetabelle[0];
  +
  +
# abbiamo optato per la funzione mysql_fetch_row, la più veloce,
  +
#+ che ci restituisce un array a chiave numerica
  +
#+ per ogni tabella creiamo un form; usiamo, in questo caso,
  +
#+ la tecnica dell'heredoc per visualizzarlo...
  +
  +
echo <<<EOF
  +
<fieldset>
  +
<legend>Inserimento $nometabella</legend>
  +
<form action="pagine/raccoltadati.php?azione=inserimento" method="post">
  +
EOF;
  +
  +
# ora estraiamo tutte le colonne della tabella corrente e,
  +
#+ per ognuna, visualizziamo l'input relativo...
  +
  +
$querycolonne="SHOW COLUMNS FROM $nometabella";
  +
$risultatocolonne=mysql_query($querycolonne);
  +
while($righecolonne=mysql_fetch_row($risultatocolonne)) {
  +
$nomecolonna=$righecolonne[0];
  +
if($nomecolonna!="ID") echo <<<EOF1
  +
<p><label for="$nomecolonna">$nomecolonna</label>&nbsp;<input type="text" name="$nomecolonna" /></p>
  +
EOF1;
  +
}
  +
echo <<<EOF2
  +
<p>
  +
<input type="hidden" name="tabella" value="$nometabella" />
  +
<input type="submit" value="inserisci $nometabella" />
  +
</p>
  +
</form>
  +
</fieldset>
  +
EOF2;
  +
}
  +
  +
?>
  +
</div>
  +
</pre>
  +
Salviamola, chiamandola semplicemente <code>inserimento.php</code>. Modifichiamo anche la voce del menu della index (''inserimento'' invece di ''inserimento-impieghi'').
  +
  +
Proviamo il tutto. Visto che forza? Abbiamo ottenuto tutti i form di inserimento in una volta! Le tabelle sono solo quattro e quindi i form sono quattro. Fossero state 100 o 1000, il risultato sarebbe stato lo stesso!
  +
  +
<div style="border:1px solid #ccc; background:#ffe; padding:5px; font-size:90%">
  +
Qualche parola sulla query ''SHOW COLUMNS FROM nometabella'': questa query ci fornisce molte utili informazioni sulla tabella, non soltanto il nome delle colonne (a cui noi qui ci limitiamo), indicato dalla chiave '''0''' dell'array (o '''Field''' se avessimo usato un array associativo con ''mysql_fetch_array''); ci fornisce il tipo di campo (chiave '''1''' o '''Type'''), il valore ''Null'' (chiave '''2''' o, appunto '''Null'''), il tipo di chiave, se, ad esempio è primaria (chiave '''3''' o '''Key'''), il valore di default ('''4''' o '''Default'''), le informazioni ''extra'', ad esempio, se ''auto_increment'' ('''5''' o '''Extra'''). &Egrave;, insomma, una risorsa veramente preziosa!
  +
</div>
  +
  +
Ma ancora non basta: ci sono delle relazioni da tener presenti...
  +
  +
Alla fine del file di configurazione, aggiungiamo questo array:
  +
<pre>
  +
$relazioni=array("Impiego"=>"impieghi","Utente"=>"utenti","Team"=>"team");
  +
</pre>
  +
  +
Ora modifichiamo definitivamente la pagina <code>inserimento.php</code>:
  +
<pre>
  +
<div>
  +
<?php
  +
include("pagine/configurazione.php");
  +
$querytabelle="SHOW TABLES";
  +
$risultatotabelle=mysql_query($querytabelle);
  +
while($righetabelle=mysql_fetch_row($risultatotabelle)) {
  +
$nometabella=$righetabelle[0];
  +
echo <<<EOF
  +
<fieldset>
  +
<legend>Inserimento $nometabella</legend>
  +
<form action="pagine/raccoltadati.php?azione=inserimento" method="post">
  +
EOF;
  +
$querycolonne="SHOW COLUMNS FROM $nometabella";
  +
$risultatocolonne=mysql_query($querycolonne);
  +
while($righecolonne=mysql_fetch_row($risultatocolonne)) {
  +
$nomecolonna=$righecolonne[0];
  +
if($nomecolonna!="ID") {
  +
echo "
  +
<p>
  +
<label for=\"$nomecolonna\">$nomecolonna</label>&nbsp;";
  +
  +
# Fino a qui è uguale a prima; ora, invece, andiamo a vedere se il campo
  +
#+ corrente è chiave dell'array "$relazioni"; in tal caso, cerchiamo
  +
#+ tutti i record della tabella relazionata e li sistemiamo in un select;
  +
#+ altrimenti, visualizziamo un semplice input (come prima)...
  +
  +
if(array_key_exists($nomecolonna,$relazioni)) {
  +
echo "
  +
<select name=\"$nomecolonna\">
  +
<option value=\"\">scegli...</option>";
  +
$queryrelazione="SELECT ID,Nome FROM {$relazioni[$nomecolonna]} ORDER BY Nome";
  +
$risultatorelazione=mysql_query($queryrelazione);
  +
while($righerelazione=mysql_fetch_array($risultatorelazione)) echo "
  +
<option value=\"{$righerelazione["ID"]}\">".stripslashes($righerelazione["Nome"])."</option>";
  +
  +
# Abbiamo trattato la stringa con "stripslashes", una funzione che serve a togliere
  +
#+ gli eventuali slash davanti ai caratteri speciali; abituiamoci ad usare
  +
#+ sempre questa funzione in presenza di stringhe estratte dal database.
  +
# Da notare come, stavolta, abbiamo usato un array associativo (con mysql_fetch_array).
  +
  +
echo "
  +
</select>";
  +
} else echo "
  +
<input type=\"text\" name=\"$nomecolonna\" />";
  +
echo "
  +
</p>";
  +
}
  +
}
  +
echo <<<EOF2
  +
  +
<p>
  +
<input type="hidden" name="tabella" value="$nometabella" />
  +
<input type="submit" value="inserisci $nometabella" />
  +
</p>
  +
</form>
  +
</fieldset>
  +
EOF2;
  +
}
  +
  +
?>
  +
</div>
  +
</pre>
  +
Se riapriamo la pagina, noteremo come, al posto di alcuni input, abbiamo dei campi ''select'', che ci danno la possibilità di scegliere tra i record inseriti nelle tabelle corrispondenti. &Egrave; in casi come questi che salta all'occhio l'importanza di formare un database con un certo criterio. Anche la scelta dei nomi dei campi e delle tabelle dovrebbe essere fatta con cognizione di causa...
  +
  +
Un'altra cosa interessante da fare è controllare il codice XHTML generato...
  +
<div style="border:1px solid #ccc; background:#dadada; padding:5px; font-size:95%">
  +
<strong>Compito per casa</strong>
  +
  +
Sapendo che il terzo campo dell'array ottenuto dal risultato della query <code>SHOW COLUMNS FROM...</code>, riguarda l'essere o meno ammissibile come valore <code>NULL</code> del relativo campo e sapendo che, se lo è, il valore restituito è <code>YES</code>, scrivere una condizione che verifica se il campo è <code>NOT NULL</code> e, nel caso, visualizza un asterisco accanto al nome del campo.
  +
</div>
  +
  +
Passiamo alle modifiche dello script di raccolta (<code>raccoltadati.php</code>) che riguardano, essenzialmente, il fatto di renderlo ''polivalente'', ovvero efficace con tutte le tabelle con cui avremo a che fare. Toglieremo, inoltre, la parte relativa alla connessione MySQL (visto che l'abbiamo inclusa nel file di configurazione). I commenti allo script sono abbastanza esplicativi:
  +
<pre>
  +
<?php
  +
include("configurazione.php");
  +
$azione=$_GET["azione"];
  +
$tabella=$_REQUEST["tabella"];
  +
  +
# Abbiamo usato il "$_REQUEST" (che equivale sia a "$_POST" che a "$_GET")
  +
#+ perché in seguito ci servirà questa polivalenza...
  +
  +
# primo caso: INSERIMENTO
  +
  +
if($azione=="inserimento") {
  +
  +
# Estraiamo le informazioni sulle colonne della tabella e il loro numero
  +
  +
$risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");
  +
$numerocolonne=mysql_num_rows($risultatocolonne);
  +
  +
# Cominciamo a scrivere la query e settiamo un contatore di campi a 1
  +
#+ (infatti l'ID l'abbiamo praticamente inserito con quel '')...
  +
  +
$query="INSERT INTO $tabella VALUES('',";
  +
$campiinseriti=1;
  +
  +
# Sfogliamo le informazioni sulle colonne e, escludendo l'ID (che è automatico)
  +
#+ raccogliamo il valore, passato con il form d'inserimento, corrispondente
  +
#+ ad ogni campo e lo aggiungiamo alla query; stavolta, gli slash li aggiungiamo
  +
#+ al valore con "addslashes".
  +
  +
while($colonne=mysql_fetch_row($risultatocolonne)) {
  +
if($colonne[0]!="ID") {
  +
$nomecampo=$colonne[0];
  +
$valoredaaggiungere=addslashes($_POST[$nomecampo]);
  +
$query.="'".$valoredaaggiungere."'";
  +
  +
# Quel ".=" serve a concatenare le stringhe
  +
  +
# Incrementiamo il contatore dei campi (con ++, che equivale a +1) e,
  +
# se non siamo alla fine della query, aggiungiamo una virgola...
  +
  +
$campiinseriti++;
  +
if($campiinseriti<$numerocolonne) $query.=",";
  +
}
  +
}
  +
  +
# Completiamo la query, eseguiamola e quindi torniamo alla pagina di inserimento
  +
  +
$query.=")";
  +
mysql_query($query) or die("Inserimento fallito");
  +
header("Location: ../index.php?pagina=inserimento");
  +
exit;
  +
}
  +
?>
  +
</pre>
  +
Facciamo qualche prova: funziona, eh!? Lo vediamo già dai campi select che si arricchiscono di nuovi valori; oppure possiamo interrogare il database...
  +
  +
Ma è ora di fare le interrogazioni via web con il nostro PHP!
  +
  +
===Elencazione===
  +
  +
Per quanto riguarda le modalità di ricerca e i elencazione, ci sarebbe da sbizzarrirsi. Tutto è lasciato al senso logico dello sviluppatore, che dovrebbe almeno sforzarsi di connotare le sue realizzazioni soprattutto di una certa dose di ''usabilità''. Si dovrebbero aver presenti le finalità degli utilizzatori finali e sarebbe quantomeno opportuno valutare la struttura del database per organizzarne al meglio l'utilizzo.
  +
  +
Per ora ci limiteremo all'elencazione (da notare che useremo ancora un'altra forma di marcatura dei commenti)...
  +
<pre style="font-size:12px">
  +
<div>
  +
<ul>
  +
<?php
  +
include("pagine/configurazione.php");
  +
  +
/* Interroghiamo le tabelle del database e creiamo un elenco. */
  +
  +
$querytabelle="SHOW TABLES";
  +
$risultatotabelle=mysql_query($querytabelle);
  +
while($righetabelle=mysql_fetch_row($risultatotabelle)) {
  +
$nometabella=$righetabelle[0];
  +
echo "
  +
<li>";
  +
if(!isset($_GET["tabella"]) || $_GET["tabella"]!=$nometabella)
  +
echo "<a href=\"index.php?pagina=tabelle&amp;tabella=$nometabella\">";
  +
echo $nometabella;
  +
if(!isset($_GET["tabella"]) || $_GET["tabella"]!=$nometabella) echo "</a>";
  +
echo "</li>";
  +
}
  +
echo "
  +
</ul>
  +
<hr />";
  +
  +
/* Adesso verifichiamo se è stata selezionata una tabella e, nel caso,
  +
* procediamo all'interrogazione... */
  +
  +
if(isset($_GET["tabella"])) {
  +
$tabella=$_GET["tabella"];
  +
$colonne=array();
  +
$risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");
  +
  +
/* Siccome le colonne della tabella ci serviranno più volte,
  +
* riempiamo un array con i valori, mediante la funzione "array_push"... */
  +
  +
while($colonnetabella=mysql_fetch_row($risultatocolonne)) array_push($colonne,$colonnetabella[0]);
  +
  +
/* A livello di marcatura (X)HTML, le tabelle vengono spesso usate a sproposito,
  +
* anche, ad esempio, per ottenere il layout della pagina.
  +
* Nel nostro caso, invece, la tabella può essere una soluzione ottimale,
  +
* anche se non l'unica possibile. Organizziamo, quindi, i risultati in una tabella...*/
  +
  +
echo "
  +
<table summary=\"tabella $tabella\" border=\"1\" cellpadding=\"2\">
  +
<tr>";
  +
  +
/* Sfogliamo l'array delle colonne e, per ognuna, scriviamo l'intestazione. */
  +
  +
foreach($colonne as $colonna) echo "
  +
<th>$colonna</th>";
  +
  +
/* Aggiungiamo due colonne (qui unite in una) con intestazione "azioni"
  +
* Vedremo a cosa serviranno...*/
  +
  +
echo "
  +
<th colspan=\"2\"><em>azioni</em></th>
  +
</tr>";
  +
  +
/* Quella che segue è una query di selezione; l'asterisco (*)
  +
* sta ad indicare "tutti i campi" */
  +
  +
$risultatotabella=mysql_query("SELECT * FROM $tabella");
  +
while($righe=mysql_fetch_array($risultatotabella)) {
  +
echo "
  +
<tr>";
  +
  +
/* Risfogliamo l'array delle colonne... */
  +
  +
foreach($colonne as $colonna) {
  +
echo "
  +
<td>";
  +
  +
/* Verifichiamo se ci sono campi relazionati ad altre tabelle (non dimentichiamo
  +
* l'array "$relazioni" che abbiamo salvato nel file di configurazione)*/
  +
  +
if(array_key_exists($colonna,$relazioni)) {
  +
$risultatorelazione=mysql_query("SELECT Nome FROM {$relazioni[$colonna]} WHERE ID='{$righe[$colonna]}'");
  +
$campo=stripslashes(mysql_result($risultatorelazione,0,0));
  +
} else $campo=stripslashes($righe[$colonna]);
  +
echo "$campo</td>";
  +
}
  +
  +
/* Inseriamo i link per la modifica e cancellazione (le "azioni" di cui sopra...) */
  +
  +
echo "
  +
<td><a href=\"index.php?pagina=modifica&amp;tabella=$tabella&amp;record={$righe["ID"]}\">modifica</a></td>
  +
<td><a href=\"index.php?pagina=tabelle&amp;tabella=$tabella&amp;cancellarecord={$righe["ID"]}\">cancella</a></td>
  +
</tr>";
  +
}
  +
echo "
  +
</table>\n";
  +
}
  +
?>
  +
</div>
  +
</pre>
  +
I commenti dovrebbero essere sufficienti per una generale comprensione del codice...
  +
  +
Salviamo la pagina come <code>tabelle.php</code> (sempre nella cartella ''pagine'', naturalmente: non dimentichiamo che, al di fuori di questa cartella, dobbiamo avere solo <code>index.php</code>). Modifichiamo, inoltre, il menu della index, sostituendo una di quelle pagine che non servono.
  +
  +
===Modifica===
  +
La prima voce delle ''azioni'' relative ad ogni record riguardano la ''modifica'' del record stesso. Abbiamo visto come lo stesso sia un link ad una pagina, appunto, ''modifica'', che ancora non abbiamo creato. Risolviamo subito. Alcune parti sono molto simili a quelle del'inserimento, per cui possiamo risparmiare sui commenti...
  +
<pre>
  +
<div>
  +
<?php
  +
include("pagine/configurazione.php");
  +
  +
$tabella=$_GET["tabella"];
  +
$record=$_GET["record"];
  +
  +
echo <<<EOF
  +
<fieldset>
  +
<legend>Modifica record n. $record della tabella <em>$tabella</em></legend>
  +
<form action="pagine/raccoltadati.php?azione=modifica&amp;tabella=$tabella&amp;record=$record" method="post">
  +
EOF;
  +
  +
# Lanciamo la query sul record, per estrarre i valori inseriti
  +
#+ e assegniamo i valori, stavolta, non ad un array, ma ad un oggetto,
  +
#+ per mezzo della funzione "mysql_fetch_object". I valori, stavolta,
  +
#+ non saranno perciò richiamati con la forma "$array[$chiave]", ma con
  +
#+ la forma "$oggetto->$proprietà" (che è anche più semplice da scrivere)...
  +
  +
$risultatorecord=mysql_query("SELECT * FROM $tabella WHERE ID='$record'");
  +
$righerecord=mysql_fetch_object($risultatorecord);
  +
  +
$risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");
  +
  +
while($righecolonne=mysql_fetch_row($risultatocolonne)) {
  +
$nomecolonna=$righecolonne[0];
  +
if($nomecolonna!="ID") {
  +
echo "
  +
<p>
  +
<label for=\"$nomecolonna\">$nomecolonna</label>&nbsp;";
  +
  +
# Troviamo il valore corrente del campo, così da visualizzarlo
  +
#+ nel campo di input...
  +
  +
$value=stripslashes($righerecord->$nomecolonna);
  +
  +
if(array_key_exists($nomecolonna,$relazioni)) {
  +
echo "
  +
<select name=\"$nomecolonna\">
  +
<option value=\"\">scegli...</option>";
  +
  +
$queryrelazione="SELECT ID,Nome FROM {$relazioni[$nomecolonna]} ORDER BY Nome";
  +
$risultatorelazione=mysql_query($queryrelazione);
  +
  +
while($righerelazione=mysql_fetch_array($risultatorelazione)) {
  +
echo "
  +
<option value=\"{$righerelazione["ID"]}";
  +
if($value==$righerelazione["ID"]) echo "selected=\"selected\"";
  +
echo "\">".stripslashes($righerelazione["Nome"])."</option>";
  +
}
  +
  +
# Abbiamo verificato se la selezione corrisponde a quanto precedentemente inserito
  +
#+ e, nel caso affermativo, abbiamo aggiunto un "selected" all'opzione, che fa sì
  +
#+ che il valore corrente del campo sia quello visualizzato nel select.
  +
  +
echo "
  +
</select>";
  +
  +
} else echo "
  +
<input type=\"text\" name=\"$nomecolonna\" value=\"$value\" />";
  +
echo "
  +
</p>";
  +
}
  +
}
  +
  +
# In fondo alla pagina, aggiungiamo, per comodità, il link di ritorno alla tabella
  +
  +
echo <<<EOF2
  +
  +
<p>
  +
<input type="submit" value="modifica" />
  +
</p>
  +
<p><a href="index.php?pagina=tabelle&amp;tabella=$tabella">torna alla tabella <em>$tabella</em></a></p>
  +
</form>
  +
</fieldset>
  +
EOF2;
  +
?>
  +
</div>
  +
</pre>
  +
Salviamo come <code>modifica.php</code>.
  +
  +
Passiamo al file di raccolta dati. Alla fine della pagina aggiungiamo il ''secondo caso'':
  +
<pre>
  +
# secondo caso: MODIFICA
  +
  +
elseif($azione=="modifica") {
  +
$record=$_GET["record"];
  +
  +
# Quella che segue è una query di modifica...
  +
  +
$query="UPDATE $tabella SET ";
  +
  +
# Dopo averla iniziata, la completiamo in base al valore dei campi
  +
#+ passati col form e con la condizione "WHERE" che verifica l'identificativo
  +
#+ del record...
  +
  +
foreach($_POST as $chiave=>$valore) $query.="$chiave='$valore',";
  +
$query.=" WHERE ID='$record'";
  +
  +
# Nella query così composta, però, c'è una virgola in più dopo
  +
#+ l'ultimo campo e non funzionerebbe; con la funzione "ereg_replace",
  +
#+ pertanto, togliamo quella virgola...
  +
  +
$query=ereg_replace(", WHERE"," WHERE",$query);
  +
  +
# Eseguiamo la query e, quindi, torniamo alla pagina delle tabelle.
  +
  +
mysql_query($query) or die("aggiornamento fallito");
  +
header("Location: ../index.php?pagina=tabelle&tabella=$tabella");
  +
exit;
  +
}
  +
</pre>
  +
Salviamo il file e proviamo a fare qualche modifica, cliccando sul link ''modifica'' nella pagine delle tabelle.
  +
  +
===Cancellazione===
  +
  +
Procediamo ora alla cancellazione dei record, richiamabile con la seconda ''azione'' delle tabelle.
  +
  +
Una cosa sempre consigliabile è quella di predisporre una sorta di ''conferma'' alla richiesta di cancellazione. Possiamo farlo benissimo nella stessa pagina delle tabelle; infatti, si tratta di una piccola aggiunta: subito prima della visualizzazione della tabella (potremmo metterla anche dopo, ma, nel caso di una tabella voluminosa, la cosa sarebbe abbastanza scomoda...), inseriamo...
  +
<pre style="font-size:12px">
  +
# Se esiste "$_GET["cancellarecord"]" significa che è stata scelta la cancellazione
  +
#+ del record; in tal caso, visualizziamo una richiesta di conferma...
  +
  +
if(isset($_GET["cancellarecord"])) echo "
  +
<p>
  +
<em>Sei sicuro di voler cancellare il record n. <strong>{$_GET["cancellarecord"]}</strong>?</em>
  +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  +
<a href=\"index.php?pagina=tabelle&amp;tabella=$tabella\" title=\"annulla la cancellazione\">NO</a>
  +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  +
<a href=\"pagine/raccoltadati.php?azione=cancellazione&amp;tabella=$tabella&amp;record={$_GET["cancellarecord"]}\"
  +
title=\"conferma la cancellazione\">SI</a>
  +
</p>\n";
  +
</pre>
  +
Semplicemente: se clicchiamo su ''NO'', torniamo indietro alla pagina delle tabelle senza far nulla; se, invece, clicchiamo su ''SI'', veniamo dirottati sul file <code>raccoltadati.php</code> con azione, appunto, ''cancellazione''. Quindi, in tale file, inseriamo il ''terzo caso'':
  +
<pre>
  +
# terzo caso: CANCELLAZIONE
  +
  +
elseif($azione=="cancellazione") {
  +
$record=$_GET["record"];
  +
mysql_query("DELETE FROM $tabella WHERE ID='$record'") or die("cancellazione fallita");
  +
header("Location: ../index.php?pagina=tabelle&tabella=$tabella");
  +
exit;
  +
}
  +
</pre>
  +
Ogni commento è superfluo. Da notare come, ancora una volta, il linguaggio SQL ci sorprenda con la sua fluidità!
  +
  +
===Pausa di riflessione===
  +
Anche se ha molte limitazioni, col nostro sistema, di fatto, abbiamo realizzato un piccolo ''gestore di contenuti'', che, se ulteriormente limato e arricchito di funzionalità, potrebbe essere sufficiente per una quasi completa gestione di un database MySQL.
  +
  +
Tuttavia, un obiettivo, da non perdere mai di vista durante l'elaborazione di un qualsiasi software, dovrebbe essere quello di riuscire ad ottenere ''il massimo risultato col minor spreco di risorse''. E, allora, una cosa da verificare è se quello che abbiamo realizzato avremmo potuto ottenerlo con un minor numero di righe di codice. Se, scorrendo le nostre pagine, notiamo che ci sono troppe porzioni di codice ripetute, significa che non abbiamo sforzato abbastanza la meningi e che potremmo fare di meglio. '''Una''' soluzione potrebbe essere quella della ''definizione di funzioni''...
  +
  +
==Definizione di Funzioni==
  +
Come ogni buon linguaggio di programmazione (o di ''scripting''), oltre alle numerosissime funzioni predefinite (e che aumentano di versione in versione...), il PHP ci permette di definire le ''nostre'' funzioni, in base alle ''nostre'' esigenze. Come vedremo, la cosa ha numerosi vantaggi, non ultimo quello di snellire vistosamente le pagine di codice...
  +
  +
Facciamo subito qualche esempio...
  +
  +
Se scorriamo la pagina <code>raccoltadati.php</code>, notiamo, per esempio, come si ripeta il reindirizzamento fatto per il tramite della funzione <code>header</code>. Potrebbe essere il caso di definire una funzione, da richiamare ogni qual volta ci serva il reindirizzamento. La funzione potremmo inserirla nella stessa pagina, ma... consideriamo l'eventualità che la funzione ci serva anche in un'altra pagina: che facciamo, la ripetiamo anche lì? Assolutamente no! Allora creiamo una pagina a parte per le funzioni, così da poterla includere tutte le volte che ci serva.
  +
  +
Apriamo, quindi un nuovo file e scriviamo:
  +
<pre>
  +
<?php
  +
function reindirizza() {
  +
  +
}
  +
?>
  +
</pre>
  +
Per definire una funzione, si usa, pertanto, la parola chiave <code>function</code>. Quelle parentesi tonde (obbligatorie anche se vuote) servono a racchiudere eventuali parametri da passare alla funzione, perché bisogna tenere innanzitutto presente che:
  +
* quello che succede all'interno della funzione è indipendente dal resto della pagina;
  +
* eventuali variabili devono essere passate come parametri, da inserire, appunto, tra quelle parentesi tonde, oppure devono essere dichiarate quali <code>global</code> all'interno della stessa funzione;
  +
* se dobbiamo far fare il percorso inverso a delle variabili, ovvero se dobbiamo restituirle allo script, lo faremo tramite la parola chiave <code>return</code>.
  +
  +
Continuiamo,,,
  +
<pre>
  +
<?php
  +
function reindirizza() {
  +
header("Location: ../index.php");
  +
exit;
  +
}
  +
?>
  +
</pre>
  +
Salviamo il file come <code>funzioni.php</code> ed includiamolo in testa a <code>raccoltadati.php</code>. Ora, in quella pagina, laddove avevamo un <code>header...</code>, sostituiamo con <code>reindirizza()</code> (parentesi obbligatorie!). Naturalmente, toglieremo anche quell'<code>exit</code>, che ora non serve più.
  +
  +
Facciamo qualche prova: vedremo che veniamo sempre reindirizzati alla index. Allora dobbiamo fare qualche modifica: all'interno delle parentesi, mettiamo un parametro e richiamiamolo, se valido, all'interno della funzione, per completare la query-string...
  +
<pre>
  +
<?php
  +
function reindirizza($paginainterna=0) {
  +
$location="Location: ../index.php";
  +
if($paginainterna) $location.="?$paginainterna";
  +
header($location);
  +
exit;
  +
}
  +
?>
  +
</pre>
  +
Da notare quel <code>$paginainterna=0</code>, che serve a dare un valore di default al parametro, nel caso in cui la funzione venga richiamata senza parametro e quell'<code>if($paginainterna)</code>, senza alcun operatore, che sfrutta la ''dicotomia booleana'' di vero/falso (ovvero se il parametro ''paginainterna'' è vero, quindi ''non-falso'', quindi ''non 0''...).
  +
<div style="border:1px solid #ccc; background:#dadada; padding:5px; font-size:95%">
  +
<strong>Compito per casa</strong>
  +
  +
Proviamo a trovare altre parti ripetitive di codice e a definire con esse altre funzioni, da salvare nel file <code>funzioni.php</code>.
  +
</div>
  +
A ben guardare, non è che abbiamo risparmiato quel granché di codice, ma ci siamo limitati ad un solo, semplice, esempio.
  +
  +
Ci fermiamo comunque qui con le funzioni, ma non le abbandoneremo: le riprenderemo sucessivamente, per chiamarle, però, ''metodi'', in quanto parte di ''oggetti-contenitori'', le cosiddette ''classi'', che ci serviranno per rendere maggiormente produttivi i nostri script...
  +
  +
==Delle Variabili particolari==
  +
Le azioni del PHP (e dello scripting lato server in genere) si svolgono, appunto, sul server e destinano al client finale solo l'output dell'elaborazione. Esistono, tuttavia, delle particolari variabili che vanno invece ad incidere, in un certo qual modo, direttamente sul client e che hanno dei ruoli abbastanza importanti: i ''cookies'' e le ''sessioni''.
  +
  +
===I Cookies===
  +
I cookies sono dei minuscoli file di testo che, in condizioni normali (ovvero se non disabilitati dall'utente), possono essere scritti in una particolare directory della home (o del profilo) dell'utente. Hanno la funzione di lasciare una traccia, in base a determinate scelte dell'utente, per mantenere tali scelte anche agli accessi successivi. I cookies hanno una scadenza, impostabile all'atto della definizione.
  +
  +
Poniamo il caso che noi vogliamo che l'utente possa memorizzare una formula di saluto e che se la ritrovi ogni volta che apre il sito: questo è un lavoro da cookie.
  +
  +
Nella nostra home, anzi nella sezione ''principale'', sostituiamo il segnaposto latino con questo form:
  +
<pre style="font-size:12px">
  +
<form action="" method="post">
  +
<fieldset>
  +
<legend>imposta formula di saluto</legend>
  +
<label for="saluto">formula </label><input type="text" name="saluto" /> <input type="submit" value="imposta -> " />
  +
</fieldset>
  +
</form>
  +
</pre>
  +
Il fatto di aver lasciato vuota l'action, significa che il form ha effetto sulla stessa pagina in cui si trova...
  +
  +
Poi, in testa alla home, inseriamo questa riga:
  +
<pre>
  +
<h3 style="color:red"><?php if(isset($_COOKIE["saluto"])) echo $_COOKIE["saluto"] ?></h3>
  +
</pre>
  +
  +
E, in testa alla index (prima ancora della DOCTYPE), inseriamo la funzione per memorizzare il cookie (importante il successivo reindirizzamento):
  +
  +
<pre>
  +
<?php
  +
if(isset($_POST["saluto"])) {
  +
setcookie("saluto",$_POST["saluto"],time()+15*24*60*60);
  +
header("Location: index.php");
  +
exit;
  +
}
  +
?>
  +
</pre>
  +
Quel <code>time()+15*24*60*60</code> significa che memorizziamo il cookie per 15 giorni (15 per 24 per 60 per 60 secondi, ovvero 1296000 secondi).
  +
  +
Proviamo ad impostare una formula di saluto e ad inviare... Il nostro cookie (a meno che non li abbiamo disabilitati da browser) funziona!
  +
  +
===Le Sessioni===
  +
La sessione è un altro particolare tipo di variabile, che si mantiene assegnata per tutta la durata, appunto, della sessione dell'utente, ovvero finché l'utente non chiude il browser o non agisce direttamente sulla sua ''de-assegnazione''.
  +
  +
Per fare un esempio efficace sull'uso delle variabili di sessione, pensiamo al caso di un accesso autenticato al sito: alla eventuale possibilità, cioè, di permettere l'interazione con alcune pagine solo agli utenti in possesso di idonee credenziali di accesso.
  +
====Un accesso autenticato====
  +
Facciamo qualche modifica alle nostre pagine...
  +
  +
Nella sezione ''secondaria'' della home, inseriamo un form di ''login'', come segue:
  +
<pre>
  +
<form action="pagine/raccoltadati.php?azione=login" method="post">
  +
<fieldset>
  +
<legend>login</legend>
  +
<p>
  +
<label for="user">username </label>
  +
<input type="text" name="user" />
  +
</p>
  +
<p>
  +
<label for="pass">password </label>
  +
<input type="password" name="pass" />
  +
</p>
  +
<input type="submit" value="accedi -> " />
  +
</fieldset>
  +
</form>
  +
<p><a href="index.php?pagina=home&amp;sezione=principale">Vai alla sezione principale</a></p>
  +
</pre>
  +
Nella sezione principale, modifichiamo il testo del link alla sezione sezione secondaria in ''login'':
  +
<pre>
  +
<p><a href="index.php?pagina=home&amp;sezione=secondaria">Login</a></p>
  +
</pre>
  +
Adesso ci serve una nuova tabella nel database, che chiameremo ''amministratori''. Inseriremo anche un primo amministratore per avere la possibilità di accedere. Dalla console di MySQL, quindi...:
  +
<pre>
  +
CREATE TABLE amministratori (
  +
ID tinyint(3) unsigned NOT NULL auto_increment,
  +
User varchar(50) NOT NULL,
  +
Pass char(32) NOT NULL,
  +
PRIMARY KEY (ID)
  +
) ;
  +
INSERT INTO amministratori VALUES
  +
(1, 'admin', MD5('mypass'));
  +
</pre>
  +
Abbiamo usato la funzione di MySQL ''MD5'' per salvare la password su database in uno dei formati ''criptati''. Non è mai consigliabile salvare una password ''in chiaro'', anche se il nostro espediente non farà nient'altro che impedire la lettura immediata della password dal database, mentre gli acorgimenti di sicurezza dovrebbero essere ben altri e dovrebbero intervenire in momenti più delicati (ne accenneremo in seguito...).
  +
  +
Ora dobbiamo l'inserire l'azione di ''login'' nel file di raccolta dati. Innanzitutto (cosa molto importante), non dobbiamo assolutamente dimenticare di inserire, in testa alla stessa pagina, la funzione che ci permette di usare le variabili di sessione:
  +
<pre>
  +
session_start();
  +
</pre>
  +
E poi...:
  +
<pre style="font-size:12px">
  +
# quarto caso: LOGIN
  +
  +
elseif($azione=="login") {
  +
$user=$_POST["user"];
  +
$pass=md5($_POST["pass"]);
  +
$risultatoamministratore=mysql_query("SELECT ID FROM amministratori WHERE User='$user' AND Pass='$pass'");
  +
  +
# Se la query ci restituisce un insieme vuoto, significa che le credenziali non sono valide
  +
  +
if(mysql_num_rows($risultatoamministratore)==0)
  +
reindirizza("pagina=home&sezione=secondaria&messaggio=UTENTE-NON-AUTORIZZATO");
  +
  +
# Altrimenti registriamo le nostre variabili di sessione; per praticità, visto che la query,
  +
#+ in questo caso, ci restituisce un'unica riga, usiamo la funzione "mysql_result", coi parametri
  +
#+ "risorsa","riga","chiave", non essendoci bisogno di dover "sfogliare" più righe...
  +
  +
else {
  +
$_SESSION["utenteautorizzato"]=mysql_result($risultatoamministratore,0,0);
  +
reindirizza("pagina=home&sezione=secondaria&messaggio=ACCESSO-ESEGUITO");
  +
}
  +
}
  +
</pre>
  +
Abbiamo fatto riferimento, nelle query-string, ad una variabile ''messaggio'', che finora, però, non abbiamo visto. Nella nostra sezione secondaria, pertanto, all'interno del fieldset, aggiungiamo:
  +
<pre style="font-size:12px">
  +
<p style="color:red"><strong><?php if(isset($_GET["messaggio"])) echo $_GET["messaggio"] ?></strong></p>
  +
</pre>
  +
Abbiamo però bisogno anche del percorso inverso, ovvero il ''logout'' (o ''logoff'' che dir si voglia). Pertanto, alla fine del form, inseriamo questo link:
  +
<pre>
  +
<p><a href="pagine/raccoltadati.php?azione=logout">Logout</a></p>
  +
</pre>
  +
E aggiungiamo l'azione di ''logout'' nello script di raccolta:
  +
<pre>
  +
# quinto caso: LOGOUT
  +
  +
elseif($azione=="logout") {
  +
session_unset();
  +
  +
# Praticamente, abbiamo azzerato le variabili di sessione.
  +
  +
reindirizza("pagina=home&sezione=secondaria&messaggio=LOGOUT-ESEGUITO");
  +
}
  +
</pre>
  +
Adesso, diamo un senso al nostro accesso autenticato.
  +
  +
Prima, abbiamo visto come sia facile inserire o modificare dei record del database; non è opportuno, però, dare questa opportunità a chiunque e l'accesso autenticato può servirci, appunto, per consentire solo alle persone di fiducia questo tipo di intervento.
  +
  +
Apriamo, quindi, la nostra index e, anche in questo caso, in testa alla pagina, inseriamo:
  +
<pre>
  +
session_start();
  +
</pre>
  +
Poi, subito dopo (poi vedremo il perché lo mettiamo in testa alla pagina), inseriamo l'array che segue (e spostiamo da quelle parti anche l'assegnazione della pagina):
  +
<pre>
  +
$pagineriservate=array("inserimento","tabelle");
  +
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
  +
</pre>
  +
E modifichiamo il menu come segue:
  +
<pre>
  +
$vocimenu=array("home","inserimento","tabelle","pinzillacchere");
  +
foreach($vocimenu as $voce) {
  +
if(!in_array($voce,$pagineriservate) || isset($_SESSION["utenteautorizzato"])) {
  +
  +
# Cio&#232;: se la voce di menu non figura nell'array di quelle riservate,
  +
#+ oppure (tenere presente che quell'|| significa "or esclusivo"), se figura
  +
#+ ma, nello stesso tempo, &#232; assegnata la variabile di sessione che
  +
#+ indica che l'utente &#232; autorizzato...
  +
  +
echo "
  +
<li>";
  +
if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
  +
echo $voce;
  +
if($pagina!=$voce) echo "</a>";
  +
echo "</li>";
  +
}
  +
}
  +
echo "\n";
  +
</pre>
  +
Ora proviamo a ''switchare'' tra login e logout: noteremo come le due voci di menu ''inserimento'' e ''tabelle'' compaiono e scompaiano in relazione al fatto che siamo autenticati o meno.
  +
  +
Un furbetto, però, a quaesto punto, cosa farebbe? Inserirebbe direttamente la query-string nella barra dell'indirizzo del browser, in questo modo (per esempio)...
  +
<pre>
  +
index.php?pagina=inserimento
  +
</pre>
  +
...prendendoci in giro per la nostra ingenuità. Allora dobbiamo correre ai ripari e metteremo, in testa alla index, subito dopo l'array che abbiamo inserito prima (ecco spiegato il perché della sua posizione...) una bella condizione che vada a verificare se siamo utenti autorizzati:
  +
<pre>
  +
if(in_array($pagina,$pagineriservate) && !isset($_SESSION["utenteautorizzato"])) {
  +
  +
# Ovvero: se la pagina fa parte di quelle riservate e non (il ! significa "not")
  +
#+ &#232; sata assegnata la variabile di sessione "utenteautorizzato", ti sbatto
  +
#+ alla pagina di login...
  +
  +
header("Location: index.php?pagina=secondaria&messaggio=DEVI-AUTENTICARTI!");
  +
exit;
  +
}
  +
</pre>
  +
E il nostro furbetto può andare a farsi un giro...!
  +
  +
==Cenni sulle connessioni cifrate==
  +
Il momento particolarmente delicato (in termini di sicurezza) cui accennavamo prima è quello del login vero e proprio. Anche se noi abbiamo provveduto a criptare la password su database, non dobbiamo dimenticare che, prima i giungere al server, la nostra password fa un bel viaggetto in rete ''in chiaro'' e, durante questo tragitto, può essere bellamente ''sniffata'' da qualcuno che ne sa più di noi (e ce ne sono tanti in giro!).
  +
  +
Come fare? Beh, se i nostri dati non sono di importanza vitale, se dalla loro integrità e sicurezza non dipende la nostra vita e la sicurezza nazionale e (cosa importante) abbiamo predisposto un backup ricorrente del nostro database, allora possiamo anche correre il rischio. Altrimenti, sarebbe il caso di ricorrere ad una connessione cifrata, col protocollo (ad esempio) '''SSL''' (''Secure Sockets Layer''), che fa sì che i dati che noi spediamo per la rete siano criptati con tecniche raffinate, per cui possiamo permetterci di dormire sonni (quasi) tranquilli.
  +
  +
Il discorso è però troppo ampio per essere affrontato adeguatamente in questo tutorial...
  +
  +
== ToDo ==
  +
Quello che abbiamo visto finora, anche se interessante e discretamente efficace, non costituisce il nostro punto di arrivo.
  +
  +
Ancora c'è tanta strada da fare.
  +
  +
Pur non pretendendo di acquisire tutto lo scibile del PHP (sarebbe una bella presunzione), dobbiamo stabilire un traguardo: dobbiamo ''almeno'' introdurci nell'OOP (''Object Oriented Programming''), ovvero nel PHP ''ad oggetti''.
  +
  +
Alla prossima...
== Collegamenti esterni ==
== Collegamenti esterni ==
* [http://www.php.net/ www.php.net]
* [http://www.php.net/ www.php.net]
* [http://www.php.net/manual/it/ Il manuale ufficiale in italiano]
* [http://www.php.net/manual/it/ Il manuale ufficiale in italiano]
  +
* [http://www.mysql.com/ www.mysql.com]
[[category:Ufficio e Web]]
[[category:Ufficio e Web]]
  +
  +
----
  +
Autore: aschenaz

Versione attuale delle 12:23, 31 gen 2009

Questo mini-tutorial nasce con l'intento di dare l'input a chi si voglia avventurare nel web-building dinamico con PHP. Per questo motivo, è strutturato in modo da essere il più semplice possibile e immediatamente comprensibile anche da chi non ha molta dimestichezza con lo scripting lato-server.

E' organizzato in forma modulare, per cui cominceremo con l'essenziale, per poi aggiungere, di volta in volta, nuove sezioni.

Si presuppone che abbiate a disposizione un web-server con il supporto a php perfettamente installato e configurato...

Si presuppone, inoltre, che abbiate almeno una generica infarinatura di programmazione. Se, ad esempio, ci troviamo di fronte ad un array, dovreste almeno sapere di cosa stiamo parlando...

E' richiesta, infine, una minima conoscenza di (X)HTML. Nel caso, può essere utile questo tutorial: XHTML_1.1 CSS e Accessibilità da zero.

Indice

[modifica] Iniziamo

Costruiremo, per iniziare, un semplicissimo sito con una index e varie sezioni interne, richiamabili per mezzo dell'inclusione, organizzata in un menu.

Abbiamo, innanzitutto, bisogno di uno strumento adatto: io vi consiglio un editor testuale, preferibilmente semplicissimo. Successivamente, possiamo pensare di passare ad un ambiente di sviluppo meglio organizzato...

Primo passo obbligato è quello di creare una pagina html:

 
<html>
<head>
 <title>Tutorial php</title>
</head>
<body>
<h1>Tutorial PHP</h1>
<hr />
</body>
</html>

Salviamo la pagina in una cartella posta nella root del web-server (denominata, ad esempio, tutorial) con nome index.php (anche se, per ora, di php non c'è nulla...).

Posizioniamoci ora nel body della pagina, al di sotto della riga dell'intestazione e inseriamo:

 ...
<h1>Tutorial PHP</h1>
<hr />
<?php

?>
 ...

Abbiamo inserito i tag che dichiarano che stiamo usando lo scripting lato server in PHP. Si potrebbe marcare diversamente, ma la cosa è ininfluente ai nostri fini. Inoltre, è consigliabile usare sempre questo tipo di marcatura.

[modifica] Costruiamo un menu

Posizioniamoci all'interno dei tag php e scriviamo:

<?php
if(isset($_GET["pagina"]) $pagina=$_GET["pagina"];
else $pagina="home";
?>

Che tradotto significa: se è indicata una $_GET["pagina"] assegniamo alla variabile $pagina il valore di $_GET["pagina"]; altrimenti le assegniamo il valore "home". $_GET["pagina"] è una variabile passata attraverso una query-string alla pagina. Per fare un esempio, prendiamo questa url:

http://www.slacky.eu/index.php?option=com_content...

In questo caso, alla variabile option è stato passato il valore com_content. Quindi per conoscerne il valore, noi dobbiamo riferirci a $_GET["option"].

Ogni comando php deve terminare con un punto e virgola!

La condizione if-else scritta sopra si può rendere in forma più breve:

<?php
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
?>

Il significato è identico ma è esposta in modo più elegante.

Continuiamo..

<?php
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
$vocimenu=array("home","bazzecole","quisquilie","pinzillacchere");
foreach($vocimenu as $voce) {
// fermiamoci un attimo
}
?>

Le definizioni di array si sprecano in rete. Noi, semplicemente, consideriamole un insieme di variabili che stanno nello stesso contenitore. Con la funzione foreach, sfogliamo queste variabili come se fossero pagine di un libro e per ognuna di esse facciamo una determinata operazione...

Prima di continuare con il php, inseriamo, subito prima dello script, il tag ul (unordered list) e chiudiamolo subito dopo lo script.

Poi continuiamo con il php, inserendo ciò che deve succedere per ogni voce dell'array...

<ul>
<?php
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
$vocimenu=array("home","bazzecole","quisquilie","pinzillacchere");
foreach($vocimenu as $voce) {
  echo "
  <li>";
  if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
  echo $voce;
  if($pagina!=$voce) echo "</a>";
  echo "</li>";
}
echo "\n";
?>
</ul>

Praticamente, abbiamo:

  • definito una serie di pagine in un array (per aggiungere nuove pagine, basterà, quindi, aggiungere nuovi voci nell'array);
  • per ogni voce dell'array (per ogni pagina, quindi) abbiamo stabilito che si deve visualizzare un punto della lista e, se la pagina corrente nell'array è diversa da quella richiamata dalla query-string ($_GET["pagina"]) o impostata di default (nel caso home), viene visualizzato il tag <a> che ha l'effetto di linkare la voce del menu, secondo l'url che abbiamo fornito con href; altrimenti, se c'è corrispondenza tra le pagine, viene semplicemente visualizzata la voce del menu (non linkata). Sembra complicato, ma nella pratica è molto più semplice che non spiegarlo a parole.

Quando con echo bisogna far visualizzare una stringa contenente degli apici ("), bisogna racchiuderla in apici semplici ('); in questi casi, le variabili devono essere poste al di fuori della stringa, usando il carattere di concatenamento .. Altrimenti, avremmo potuto usare la forma

echo "<a href=\"index.php?pagina=$voce\">";

oppure ancora

echo <<<EOT
<a href="index.php?pagina=$voce">
EOT;

Ma quest'ultima forma (cosiddetta heredoc) è preferibile per porzioni di testo più estese. A tale proposito, bisogna tener presente che il marcatore di chiusura (in questo caso EOT, ma possiamo mettere quello che vogliamo...) non deve avere spazi né prima (niente indentazione, quindi) né dopo.

Abbiamo finito il nostro semplice menu; salviamo la pagina, che ora è così complessivamente formata:

<html>
<head>
  <title>Tutorial php</title>
</head>
<body>
<h1>Tutorial PHP</h1>
<hr />
<ul><?php
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
$vocimenu=array("home","bazzecole","quisquilie","pinzillacchere");
foreach($vocimenu as $voce) {
  echo "
  <li>";
  if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
  echo $voce;
  if($pagina!=$voce) echo "</a>";
  echo "</li>";
}
echo "\n";
?>
</ul>
</body>
</html>

Quell'echo "\n" serve per andare a capo e visualizzare correttamente il sorgente della pagina. Per lo scopo inverso, ma con identità finalità, abbiamo spostato il tag di apertura <?php sulla stessa linea di ul.

[modifica] Inclusione di file

Ora passiamo alla stesura delle nostre pagine interne.

Sfrutteremo una delle potenti feature di PHP (e dei linguaggi lato-server in genere): l'inclusione.

Al di sotto del menu della nostra index (quindi dopo </ul>) inseriamo queste righe:

<hr />
<h2><?php echo $pagina ?></h2>

Se non ci sta bene che il nome della pagina compaia in minuscolo sostituiamo con:

<h2><?php print(ucfirst($pagina)) ?></h2>

Poi, creiamo una nuova pagina con questo contenuto:

<p style="background:#eee">
  Lorem ipsum dolor sit amet, consectetaur adipisicing elit, sed do eiusmod tempor
  incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
  exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute 
  irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 
  pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui 
  officia deserunt mollit anim id est laborum.
</p>

Salviamola con il nome home.php.

Ricordiamoci sempre di terminare le pagine incluse con un'andata a capo: è un accorgimento opportuno per una buona visualizzazione del sorgente delle pagine.

Modifichiamo solo lo sfondo del paragrafo (prima con #ffa, poi con #aff e infine con #aaf, per esempio) e salviamo, rispettivamente con bazzecole.php, quisquilie.php e pinzillacchere.php. Abbiamo differenziato lo sfondo per notare subito la differenza tra le pagine.

L'estensione .php non è obbligatoria. Avremmo potuto usare .html, o .inc... L'importante è poi richiamare le pagine con l'estensione giusta...

Nella nostra cartella tutorial, dobbiamo, a questo punto, avere cinque file: index.php, home.php, bazzecole.php, quisquilie.php e pinzillacchere.php.

Ora, tornando alla index, al di sotto del titolo della pagina che abbiamo appena creato inseriamo:

<?php include("$pagina.php") ?>

Il codice complessivo della index, ora è questo:

<html>
<head>
  <title>Tutorial php</title>
</head>
<body>
<h1>Tutorial PHP</h1>
<hr />
<ul><?php
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
$vocimenu=array("home","bazzecole","quisquilie","pinzillacchere");
foreach($vocimenu as $voce) {
  echo "
  <li>";
  if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
  echo $voce;
  if($pagina!=$voce) echo "</a>";
  echo "</li>";
}
echo "\n";
?>
</ul>
<hr />
<h2><?php echo ucfirst($pagina) ?></h2>
<?php include("$pagina.php") ?>
</body>
</html>

Possiamo procedere alle nostre prime prove...

Se il nostro web-server gira in locale, apriamo il nostro browser preferito all'indirizzo localhost/tutorial; se, invece, la cartella sta di un server remoto, sostituiamo localhost con l'indirizzo del server.

Proviamo a navigare tra le diverse voci del menu. Forte, no?

[modifica] Ulteriore inclusione

E se noi volessimo richiamare un'ulteriore inclusione da una delle pagine (per esempio)?

Poniamo che la home abbia due sezioni: principale e secondaria.

Creiamo una nuova pagina interna con nome principale.php, con questo contenuto:

<p style="background:#008;color:#fff;">
  Lorem ipsum dolor sit amet, consectetaur adipisicing elit, sed do eiusmod tempor
  incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
  exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
<p><a href="index.php?page=home&amp;sezione=secondaria">Vai alla sezione secondaria</a></p>

E ora creiamone un'altra con nome secondaria.php e questo contenuto:

<p style="background:#800;color:#fff;">
  Lorem ipsum dolor sit amet, consectetaur adipisicing elit, sed do eiusmod tempor
  incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
  exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
<p><a href="index.php?page=home&amp;sezione=principale">Vai alla sezione principale</a></p>

Ora apriamo home.php e, alla fine, inseriamo questo codice:

<?php
isset($_GET["sezione"]) ? $sezione=$_GET["sezione"] : $sezione="principale";
echo "
<h3>Sezione $sezione </h3>\n";
include("$sezione.php");
?>

Da notare come nella query-string index.php?page=home&amp;sezione=principale, la prima variabile viene assegnata dopo il ?, le altre dopo &amp;. Sarebbe bastato scrivere &, ma avremmo avuto problemi di validazione della pagina...

Proviamo di nuovo il tutto...

Bene.

[modifica] Data e ora

Aggiungiamo data e ora alla nostra index. Subito dopo l'intestazione h1, inseriamo questo codice:

<?php
$giorni=array("Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato");
$giorno=$giorni[date("w")];
$data=date("d/m/Y");
$ora=date("H:i");
echo "<p><em>$giorno $data - ore $ora</em></p>\n";
?>

Il codice è abbastanza chiaro. Si rimanda alla funzione date del manuale PHP per le molteplici potenzialità della stessa.

Se l'orologio del nostro server è settato correttamente, ad ogni collegamento visualizzeremo data e ora precise.


[modifica] Organizzazione

Prima di continuare con il PHP, diamo un po' di organizzazione al nostro sito.

Una cosa consigliabile è quella di inserire tutte le pagine interne in una sotto-cartella: creiamo, dunque, una sotto-cartella pagine e spostiamo tutti i file (tranne index.php) in essa. Nella root del sito, deve rimanere, pertanto, solo la index.

Ora apriamo la index e sostituiamo:

include("$pagina.php");

con

include("pagine/$pagina.php");

L'ordine è sempre una cosa buona. Inoltre, organizzare i nostri file in sotto-cartelle ha anche altri vantaggi...

Altra cosa opportuna da fare, visto che, di fatto, stiamo lavorando in XHTML, di inserire le esatte dichiarazioni nel codice di marcatura. Al posto di <html> inseriamo, quindi...

<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it">

E, all'iterno della head, mettiamo...

<meta http-equiv="content-type" content="text/html;charset=iso-8859-15" />

A questo punto, il codice complessivo della index è questo:

<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it">
<head>
  <title>Tutorial php</title>
  <meta http-equiv="content-type" content="text/html;charset=iso-8859-15" />
</head>
<body>
<h1>Tutorial PHP</h1>
<?php
$giorni=array("Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato");
$giorno=$giorni[date("w")];
$data=date("d/m/Y");
$ora=date("H:i");
echo "<p><em>$giorno $data - ore $ora</em></p>\n";
?>
<hr />
<ul><?php
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";
$vocimenu=array("home","bazzecole","quisquilie","pinzillacchere");
foreach($vocimenu as $voce) {
  echo "
  <li>";
  if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
  echo $voce;
  if($pagina!=$voce) echo "</a>";
  echo "</li>";
}
echo "\n";
?>
</ul>
<hr />
<h2><?php echo ucfirst($pagina) ?></h2>
<?php include("pagine/$pagina.php") ?>
</body>
</html>

[modifica] MySQL

È bene precisare che MySQL non è l'unico database gestibile da PHP, anzi: PHP può pilotare, più o meno nativamente, la maggior parte dei database esistenti; i suoi ottimi e consolidati rapporti con MySQL, tuttavia, ce lo fanno preferire per un tutorial (e non solo).


L'impatto migliore che si possa avere con MySQL potrebbe essere quello che si verifica per il tramite della sua console. Tuttavia, se la cosa potesse risultare ostica, almeno per le prime volte, è altrettanto produttivo utilizzare un gestore organizzato, PhpMyAdmin, per esempio. In ogni caso, piuttosto che istruire come utilizare questo o quel gestore, è preferibile indicare le query in SQL, che, come vedremo, è un linguaggio molto semplice ed intuitivo (se la nostra lingua fosse l'inglese, ci sembrerebbe di discorrere col database...).

Anche in questo caso, si presuppone che abbiate a disposizione MySQL perfettamente configurato e che siate in possesso di valide credenziali d'accesso...

Per accedere alla console di MySQL, basta digitare:

mysql -u NOME-AMMINISTRATORE -p

Inserita la password relativa a NOME-AMMINISTRATORE, saremmo ammessi nella console di MySQL:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 51
Server version: 5.0.51-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

A questo punto, possiamo digitare comandi, eseguire query, etc.

[modifica] Il Database

Trovandoci nella console di MySQL, digitiamo:

CREATE DATABASE tutorial;

Da notare come ogni comando deve terminare con un ; (punto e virgola).

Fatto! Il nostro database è già stato creato. Ora si tratta di organizzarlo in tabelle.

È opportuno scrivere le parole chiave di SQL in maiuscolo. Tuttavia, non è obbligatorio: SQL non è un linguaggio case-sensitive.

[modifica] Le Tabelle

Adesso procediamo alla creazione delle tabelle.

La discussione in merito ad una corretta formulazione del database esula da questo tutorial. E' importante precisare, però, che un database ben formato può fare la differenza! Ci limitiamo a precisare alcuni punti fondamentali:

  • è assolutamente sbagliato intendere un database come un unico tabellone in cui, magari, ripetere gli stessi valori o lasciare vuote le celle che non servono; è molto più produttivo, piuttosto, creare diverse tabelle, relazionate tra loro e organizzate con logica;
  • le relazioni tra diversi campi si possono ricondurre a tre tipi fondamentali: uno a uno, uno a diversi, diversi a diversi; nel primo caso, è sufficiente una sola tabella (pensiamo, ad esempio, ad una tabella utenti-codicefiscale); nel secondo caso sono necessarie due tabelle (ad esempio, in una relazione utenti-impiego, sapendo che un impiego può essere condiviso da diversi utenti, è produttivo creare una tabella impieghi ed una utenti, dove l'impiego è richiamato solo dall'ID corrispondente all'opportuno record della tabella impieghi); nel terzo caso, le tabelle da creare sarebbero tre (ad esempio, pensiamo di avere impiegati organizzati in team, ma anche che lo stesso impiegato possa essere incluso in diversi team: allora avremo la tabella utenti, la tabella team e la tabella utenti_team, che conterrà le relazioni, indicate solo con gli ID, tra impiegato e team).

Partendo da questi presupposti, procediamo alla creazione di quattro tabelle: utenti, impieghi, team e utenti_team.

I nomi delle tabelle non devono contenere né spazi né caratteri speciali (limitiamoci a qualche underscore _ ).

E' ovvio che adesso diventi più facile operare con phpMyAdmin (per esempio), ma prendere un po' di confidenza con l'SQL non è affatto male (oltretutto, le tabelle potremmo farle creare dallo script php stesso...). Procediamo, quindi, nella nostra console mysql:

CREATE TABLE utenti(
ID mediumint(8) unsigned NOT NULL auto_increment,
Nome varchar(255) NOT NULL,
Impiego smallint(4) NOT NULL,
PRIMARY KEY  (ID)
);

Abbiamo creato una semplice tabella utenti con solo tre campi: ID, Nome e Impiego. Naturalmente possiamo inserire quanti altri campi vogliamo; l'importante è non cadere nell'errore comune di creare colonne a iosa che poi corrono il rischio di rimanere vuote. Il campo ID, che rappresenta l'identificativo o chiave primaria della tabella (indicata con quel PRIMARY KEY alla fine) è definito con mediumint(8), ovvero è un intero con 8 cifre massime (di fatto, avendo il parametro unsigned, è un intero compreso tra 0 e 16777215); il NOT NULL sta a indicare che il campo è obbligatorio; il parametro auto_increment fa sì che il numero aumenti automaticamente di uno ogni nuovo inserimento. Il campo Nome, invece, è definito quale varchar(255), ovvero una stringa alfanumerica variabile con un massimo di 255 caratteri. Il campo Impiego, infine, è definito con un intero inferiore (vedremo il perché...). Naturalmente, non sono solo questi i tipi di campo ammissibili in MySql (vedere, a questo proposito, i link segnalati in calce). Continuiamo con le nostre tabelle...

CREATE TABLE impieghi(
ID smallint(4) unsigned NOT NULL auto_increment,
Nome varchar(255) NOT NULL,
PRIMARY KEY  (ID)
);
CREATE TABLE team(
ID tinyint(3) unsigned NOT NULL auto_increment,
Nome varchar(255) NOT NULL,
PRIMARY KEY  (ID)
);
CREATE TABLE utenti_team(
ID mediumint(8) unsigned NOT NULL auto_increment,
Utente mediumint(8) unsigned NOT NULL,
Team tinyint(3) unsigned NOT NULL,
PRIMARY KEY  (ID)
);

Una mancanza che salta agli occhi degli utenti più esperti è quella relativa alla definizione del tipo di tabella: per il momento, è inutile crearci complicazioni ed è meglio lasciare fare a Mr. Default (di solito, il tipo predefinito è MyIsam).

Lo smallint(4) che avevamo visto nella colonna Impiego della tabella utenti lo ritroviamo nella tabella impieghi quale ID. Questo sta a significare che quel numero richiamato alla colonna Impiego della tabella utenti è un riferimento diretto al record identificato con lo stesso numero nella tabella impieghi. Lo stesso discorso vale per le colonne della tabella utenti_team...

Il nostro piccolo database è pronto. Ora si tratta di popolarlo...

[modifica] L'inserimento

Per l'inserimento di record nelle tabelle, procederemo con il nostro principale argomento di studio, ovvero il PHP.

[modifica] Primo metodo: semplice ed esplicito

Creiamo una nuova pagina interna con un form di inserimento:

<div>
<fieldset>
<legend>Inserimento impieghi</legend>
<form action="pagine/raccoltadati.php?azione=inserimento" method="post">
  <p><label for="Nome"> <input type="text" name="Nome" /></p>
  <p>
    <input type="hidden" name="tabella" value="impieghi" />
    <input type="submit" value="inserisci" />
  </p>
</form>
</fieldset>
</div>

Salviamo col nome inserimentoimpieghi.php nella cartella pagine. Com'è (quasi) ovvio, si tratta di inserire record nella tabella impieghi. Non ci dovrebbero essere dubbi sul form. L'unica cosa, forse, da puntualizzare è che il nome della tabella, invece che con il campo hidden, avremmo anche potuto passarlo allo script di raccolta direttamente nella query-string della action del form (query-string che sarebbe diventata raccoltadati.php?azione=inserimento&amp;tabella=impieghi).

Prima di passare allo script di raccolta dei dati, scriviamo un piccolo file dove immagazzinare in costanti le nostre credenziali di accesso al database:

<?php
define("COSTANTE_HOST","localhost");
define("COSTANTE_UTENTE","nomeutente");
define("COSTANTE_PASSWORD","passwordutente");
define("COSTANTE_DATABASE","tutorial");
?>

Naturalmente, sostituiremo nomeutente con il nome del nostro amministratore del database e passwordutente con la sua password. Se il database risiede sullo stesso web-server, come host va bene localhost, altrimenti sostituiamo con l'indirizzo del server del database. Salviamolo con nome configurazione.php nella stessa cartella pagine. Questo file dovrà essere incluso ogniqualvolta dovremo connetterci al database.

Procediamo ora con lo script raccoltadati.php, salvandolo sempre nella cartella pagine (le parti di commento non sono necessarie per il funzionamento dello script, ma fanno praticamente parte del presente tutorial):

<?php
include("configurazione.php");
// incluso il file dove sono contenute le credenziali, tenta la connessione al db
// oppure lo script si ferma ("die") visualizzando l'errore in parametro
$connessione=mysql_connect(COSTANTE_HOST,COSTANTE_UTENTE,COSTANTE_PASSWORD) or 
  die("Problemi di connessione: controlla le credenziali");
// ora sceglie il database
mysql_select_db(COSTANTE_DATABASE) or die("Database non presente");
// raccoglie l'azione da intraprendere dalla query-string;
// le variabili così passate sono raccolte nell'array associativo "$_GET".
$azione=$_GET["azione"];
// primo caso: inserimento
if($azione=="inserimento") {
  // raccoglie la tabella dal form (che ha metodo "post"); in questo caso,
  // l'array associativo che raccoglie le variabili è "$_POST"
  $tabella=$_POST["tabella"];
  // scriviamo la "query", differenziandola in base alla tabella (occhio alla sintassi)
  // il primo valore è vuoto ('') e sta ad indicare l'ID, che, come abbiamo visto,
  // si crea automaticamente con "auto_increment"
  if($tabella=="impieghi") $query="INSERT INTO $tabella VALUES('',".$_POST["Nome"].")"; 
  // eseguiamo la query e quindi torniamo alla index con la funzione "header" (che è 
  // sempre buona norma far seguire da "exit"
  mysql_query($query) or die("Inserimento fallito");
  header("Location: ../index.php");
  exit;
}
?>

Ora aggiungiamo la nuova pagina al menu della nostra index. Magari, senza nulla togliere al grande Totò, possiamo sostituire una di quelle pagine (bazzecole etc.) che abbiamo messo per scherzo. Sostituiamo, quindi, nell'array del menu, inserimento-impieghi a bazzecole (per esempio).

Divertiamoci ad inserire degli impieghi. Poi verifichiamo dalla console di mysql (per ora), con...

SELECT * FROM tutorial.impieghi;

Io ho inserito un solo record:

+----+---------------+
| ID | Nome          |
+----+---------------+
|  1 | programmatore |
+----+---------------+
1 row in set (0,00 sec)

Fermiamoci a riflettere. Cosa abbiamo fatto?

I dati immessi per mezzo dl form sono confluiti nello script raccoltadati che li ha inseriti nel database tramite una query, che, per ora, è unica, ma che, con questo metodo, è destinata a cambiare in relazione alla tabella su cui andremo ad incidere. Tutto qui! Naturalmente, il nostro script è volutamente stringato: avremmo dovuto mettere almeno qualche routine di controllo dei dati inseriti e avremmo dovuto rendere i dati medesimi più digeribili al database... Ma il problema, adesso, è un altro: c'è qualcosa che non va, non è questa la potenza dello scripting lato-server e del php in particolare. La nostra soluzione non è elegante.

Proviamo un altro metodo...

[modifica] Secondo metodo: un po' di alchimia

Cominciamo con la pagina di configurazione. Aggiungiamo lì la connessione a mysql (così da non doverla ripetere in ogni pagina dove ce ne fosse bisogno):

<?php
define("COSTANTE_HOST","localhost");
define("COSTANTE_UTENTE","nomeutente");
define("COSTANTE_PASSWORD","passwordutente");
define("COSTANTE_DATABASE","tutorial");
$connessione=mysql_connect(COSTANTE_HOST,COSTANTE_UTENTE,COSTANTE_PASSWORD) 
  or die("Problemi di connessione: controlla le credenziali");
mysql_select_db(COSTANTE_DATABASE) or die("Database non presente");
?>

Modifichiamo radicalmente la pagina di inserimento:

<div>
<?php
# Visto che ora la connessione serve anche qui, includiamo la pagina di configurazione.

include("pagine/configurazione.php");

#  estraiamo tutte le tabelle dal database e, sfogliandole,
#+ creiamo un form per ognuna

$querytabelle="SHOW TABLES";
$risultatotabelle=mysql_query($querytabelle);
while($righetabelle=mysql_fetch_row($risultatotabelle)) {
  $nometabella=$righetabelle[0];

#  abbiamo optato per la funzione mysql_fetch_row, la più veloce,
#+ che ci restituisce un array a chiave numerica
#+ per ogni tabella creiamo un form; usiamo, in questo caso,
#+ la tecnica dell'heredoc per visualizzarlo...

  echo <<<EOF
<fieldset>
<legend>Inserimento $nometabella</legend>
<form action="pagine/raccoltadati.php?azione=inserimento" method="post">
EOF;

#  ora estraiamo tutte le colonne della tabella corrente e,
#+ per ognuna, visualizziamo l'input relativo...

  $querycolonne="SHOW COLUMNS FROM $nometabella";
  $risultatocolonne=mysql_query($querycolonne);
  while($righecolonne=mysql_fetch_row($risultatocolonne)) {
    $nomecolonna=$righecolonne[0];
    if($nomecolonna!="ID") echo <<<EOF1
  <p><label for="$nomecolonna">$nomecolonna</label> <input type="text" name="$nomecolonna" /></p>
EOF1;
  }
  echo <<<EOF2
  <p>
    <input type="hidden" name="tabella" value="$nometabella" />
    <input type="submit" value="inserisci $nometabella" />
  </p>
</form>
</fieldset>
EOF2;
}

?>
</div>

Salviamola, chiamandola semplicemente inserimento.php. Modifichiamo anche la voce del menu della index (inserimento invece di inserimento-impieghi).

Proviamo il tutto. Visto che forza? Abbiamo ottenuto tutti i form di inserimento in una volta! Le tabelle sono solo quattro e quindi i form sono quattro. Fossero state 100 o 1000, il risultato sarebbe stato lo stesso!

Qualche parola sulla query SHOW COLUMNS FROM nometabella: questa query ci fornisce molte utili informazioni sulla tabella, non soltanto il nome delle colonne (a cui noi qui ci limitiamo), indicato dalla chiave 0 dell'array (o Field se avessimo usato un array associativo con mysql_fetch_array); ci fornisce il tipo di campo (chiave 1 o Type), il valore Null (chiave 2 o, appunto Null), il tipo di chiave, se, ad esempio è primaria (chiave 3 o Key), il valore di default (4 o Default), le informazioni extra, ad esempio, se auto_increment (5 o Extra). È, insomma, una risorsa veramente preziosa!

Ma ancora non basta: ci sono delle relazioni da tener presenti...

Alla fine del file di configurazione, aggiungiamo questo array:

$relazioni=array("Impiego"=>"impieghi","Utente"=>"utenti","Team"=>"team");

Ora modifichiamo definitivamente la pagina inserimento.php:

<div>
<?php
include("pagine/configurazione.php");
$querytabelle="SHOW TABLES";
$risultatotabelle=mysql_query($querytabelle);
while($righetabelle=mysql_fetch_row($risultatotabelle)) {
  $nometabella=$righetabelle[0];
  echo <<<EOF
<fieldset>
<legend>Inserimento $nometabella</legend>
<form action="pagine/raccoltadati.php?azione=inserimento" method="post">
EOF;
  $querycolonne="SHOW COLUMNS FROM $nometabella";
  $risultatocolonne=mysql_query($querycolonne);
  while($righecolonne=mysql_fetch_row($risultatocolonne)) {
    $nomecolonna=$righecolonne[0];
    if($nomecolonna!="ID") {
      echo "
  <p>
    <label for=\"$nomecolonna\">$nomecolonna</label> ";

#  Fino a qui è uguale a prima; ora, invece, andiamo a vedere se il campo
#+ corrente è chiave dell'array "$relazioni"; in tal caso, cerchiamo
#+ tutti i record della tabella relazionata e li sistemiamo in un select;
#+ altrimenti, visualizziamo un semplice input (come prima)...

      if(array_key_exists($nomecolonna,$relazioni)) {
	echo "
    <select name=\"$nomecolonna\">
      <option value=\"\">scegli...</option>";
        $queryrelazione="SELECT ID,Nome FROM {$relazioni[$nomecolonna]} ORDER BY Nome";
        $risultatorelazione=mysql_query($queryrelazione);
        while($righerelazione=mysql_fetch_array($risultatorelazione)) echo "
      <option value=\"{$righerelazione["ID"]}\">".stripslashes($righerelazione["Nome"])."</option>";

#  Abbiamo trattato la stringa con "stripslashes", una funzione che serve a togliere
#+ gli eventuali slash davanti ai caratteri speciali; abituiamoci ad usare
#+ sempre questa funzione in presenza di stringhe estratte dal database.
#  Da notare come, stavolta, abbiamo usato un array associativo (con mysql_fetch_array).

        echo "
    </select>";
      } else echo "
    <input type=\"text\" name=\"$nomecolonna\" />";
      echo "
  </p>";
    }
  }
  echo <<<EOF2

  <p>
    <input type="hidden" name="tabella" value="$nometabella" />
    <input type="submit" value="inserisci $nometabella" />
  </p>
</form>
</fieldset>
EOF2;
}

?>
</div>

Se riapriamo la pagina, noteremo come, al posto di alcuni input, abbiamo dei campi select, che ci danno la possibilità di scegliere tra i record inseriti nelle tabelle corrispondenti. È in casi come questi che salta all'occhio l'importanza di formare un database con un certo criterio. Anche la scelta dei nomi dei campi e delle tabelle dovrebbe essere fatta con cognizione di causa...

Un'altra cosa interessante da fare è controllare il codice XHTML generato...

Compito per casa

Sapendo che il terzo campo dell'array ottenuto dal risultato della query SHOW COLUMNS FROM..., riguarda l'essere o meno ammissibile come valore NULL del relativo campo e sapendo che, se lo è, il valore restituito è YES, scrivere una condizione che verifica se il campo è NOT NULL e, nel caso, visualizza un asterisco accanto al nome del campo.

Passiamo alle modifiche dello script di raccolta (raccoltadati.php) che riguardano, essenzialmente, il fatto di renderlo polivalente, ovvero efficace con tutte le tabelle con cui avremo a che fare. Toglieremo, inoltre, la parte relativa alla connessione MySQL (visto che l'abbiamo inclusa nel file di configurazione). I commenti allo script sono abbastanza esplicativi:

<?php
include("configurazione.php");
$azione=$_GET["azione"];
$tabella=$_REQUEST["tabella"];

#  Abbiamo usato il "$_REQUEST" (che equivale sia a "$_POST" che a "$_GET")
#+ perché in seguito ci servirà questa polivalenza...

#  primo caso: INSERIMENTO

if($azione=="inserimento") {

#  Estraiamo le informazioni sulle colonne della tabella e il loro numero

  $risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");
  $numerocolonne=mysql_num_rows($risultatocolonne);

#  Cominciamo a scrivere la query e settiamo un contatore di campi a 1
#+ (infatti l'ID l'abbiamo praticamente inserito con quel '')...

  $query="INSERT INTO $tabella VALUES('',";
  $campiinseriti=1;

#  Sfogliamo le informazioni sulle colonne e, escludendo l'ID (che è automatico)
#+ raccogliamo il valore, passato con il form d'inserimento, corrispondente 
#+ ad ogni campo e lo aggiungiamo alla query; stavolta, gli slash li aggiungiamo
#+ al valore con "addslashes".

  while($colonne=mysql_fetch_row($risultatocolonne)) {
    if($colonne[0]!="ID") {
      $nomecampo=$colonne[0];
      $valoredaaggiungere=addslashes($_POST[$nomecampo]);
      $query.="'".$valoredaaggiungere."'"; 

#  Quel ".=" serve a concatenare le stringhe

#  Incrementiamo il contatore dei campi (con ++, che equivale a +1) e,
#  se non siamo alla fine della query, aggiungiamo una virgola...

      $campiinseriti++;
      if($campiinseriti<$numerocolonne) $query.=",";
    }
  }

#  Completiamo la query, eseguiamola e quindi torniamo alla pagina di inserimento

  $query.=")";
  mysql_query($query) or die("Inserimento fallito");
  header("Location: ../index.php?pagina=inserimento");
  exit;
}
?>

Facciamo qualche prova: funziona, eh!? Lo vediamo già dai campi select che si arricchiscono di nuovi valori; oppure possiamo interrogare il database...

Ma è ora di fare le interrogazioni via web con il nostro PHP!

[modifica] Elencazione

Per quanto riguarda le modalità di ricerca e i elencazione, ci sarebbe da sbizzarrirsi. Tutto è lasciato al senso logico dello sviluppatore, che dovrebbe almeno sforzarsi di connotare le sue realizzazioni soprattutto di una certa dose di usabilità. Si dovrebbero aver presenti le finalità degli utilizzatori finali e sarebbe quantomeno opportuno valutare la struttura del database per organizzarne al meglio l'utilizzo.

Per ora ci limiteremo all'elencazione (da notare che useremo ancora un'altra forma di marcatura dei commenti)...

<div>
  <ul>
<?php
include("pagine/configurazione.php");

/* Interroghiamo le tabelle del database e creiamo un elenco. */

$querytabelle="SHOW TABLES";
$risultatotabelle=mysql_query($querytabelle);
while($righetabelle=mysql_fetch_row($risultatotabelle)) {
  $nometabella=$righetabelle[0];
  echo "
    <li>";
  if(!isset($_GET["tabella"]) || $_GET["tabella"]!=$nometabella) 
    echo "<a href=\"index.php?pagina=tabelle&tabella=$nometabella\">";
  echo $nometabella;
  if(!isset($_GET["tabella"]) || $_GET["tabella"]!=$nometabella) echo "</a>";
  echo "</li>";
}
echo "
  </ul>
  <hr />";

/* Adesso verifichiamo se è stata selezionata una tabella e, nel caso,
*  procediamo all'interrogazione... */

if(isset($_GET["tabella"])) {
  $tabella=$_GET["tabella"];
  $colonne=array();
  $risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");

/* Siccome le colonne della tabella ci serviranno più volte, 
*  riempiamo un array con i valori, mediante la funzione "array_push"... */

  while($colonnetabella=mysql_fetch_row($risultatocolonne)) array_push($colonne,$colonnetabella[0]);

/* A livello di marcatura (X)HTML, le tabelle vengono spesso usate a sproposito,
*  anche, ad esempio, per ottenere il layout della pagina.
*  Nel nostro caso, invece, la tabella può essere una soluzione ottimale, 
*  anche se non l'unica possibile. Organizziamo, quindi, i risultati in una tabella...*/

  echo "
  <table summary=\"tabella $tabella\" border=\"1\" cellpadding=\"2\">
    <tr>";

/* Sfogliamo l'array delle colonne e, per ognuna, scriviamo l'intestazione. */

  foreach($colonne as $colonna) echo "
      <th>$colonna</th>";

/* Aggiungiamo due colonne (qui unite in una) con intestazione "azioni"
*  Vedremo a cosa serviranno...*/

  echo "
      <th colspan=\"2\"><em>azioni</em></th>
    </tr>";

/* Quella che segue è una query di selezione; l'asterisco (*)
*  sta ad indicare "tutti i campi" */

  $risultatotabella=mysql_query("SELECT * FROM $tabella");
  while($righe=mysql_fetch_array($risultatotabella)) {
    echo "
    <tr>";

/* Risfogliamo l'array delle colonne... */

    foreach($colonne as $colonna) {
      echo "
      <td>";

/* Verifichiamo se ci sono campi relazionati ad altre tabelle (non dimentichiamo
*  l'array "$relazioni" che abbiamo salvato nel file di configurazione)*/

      if(array_key_exists($colonna,$relazioni)) {
        $risultatorelazione=mysql_query("SELECT Nome FROM {$relazioni[$colonna]} WHERE ID='{$righe[$colonna]}'");
        $campo=stripslashes(mysql_result($risultatorelazione,0,0));
      } else $campo=stripslashes($righe[$colonna]);
      echo "$campo</td>";
    }

/* Inseriamo i link per la modifica e cancellazione (le "azioni" di cui sopra...) */

    echo "
      <td><a href=\"index.php?pagina=modifica&tabella=$tabella&record={$righe["ID"]}\">modifica</a></td>
      <td><a href=\"index.php?pagina=tabelle&tabella=$tabella&cancellarecord={$righe["ID"]}\">cancella</a></td>
    </tr>";
  }
  echo "
  </table>\n";
}
?>
</div>

I commenti dovrebbero essere sufficienti per una generale comprensione del codice...

Salviamo la pagina come tabelle.php (sempre nella cartella pagine, naturalmente: non dimentichiamo che, al di fuori di questa cartella, dobbiamo avere solo index.php). Modifichiamo, inoltre, il menu della index, sostituendo una di quelle pagine che non servono.

[modifica] Modifica

La prima voce delle azioni relative ad ogni record riguardano la modifica del record stesso. Abbiamo visto come lo stesso sia un link ad una pagina, appunto, modifica, che ancora non abbiamo creato. Risolviamo subito. Alcune parti sono molto simili a quelle del'inserimento, per cui possiamo risparmiare sui commenti...

<div>
<?php
include("pagine/configurazione.php");

$tabella=$_GET["tabella"];
$record=$_GET["record"];

echo <<<EOF
<fieldset>
<legend>Modifica record n. $record della tabella <em>$tabella</em></legend>
<form action="pagine/raccoltadati.php?azione=modifica&tabella=$tabella&record=$record" method="post">
EOF;

#  Lanciamo la query sul record, per estrarre i valori inseriti
#+ e assegniamo i valori, stavolta, non ad un array, ma ad un oggetto,
#+ per mezzo della funzione "mysql_fetch_object". I valori, stavolta,
#+ non saranno perciò richiamati con la forma "$array[$chiave]", ma con 
#+ la forma "$oggetto->$proprietà" (che è anche più semplice da scrivere)...

$risultatorecord=mysql_query("SELECT * FROM $tabella WHERE ID='$record'");
$righerecord=mysql_fetch_object($risultatorecord);

$risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");

while($righecolonne=mysql_fetch_row($risultatocolonne)) {
  $nomecolonna=$righecolonne[0];
  if($nomecolonna!="ID") {
    echo "
  <p>
    <label for=\"$nomecolonna\">$nomecolonna</label> ";

#  Troviamo il valore corrente del campo, così da visualizzarlo
#+ nel campo di input...

    $value=stripslashes($righerecord->$nomecolonna);
    
    if(array_key_exists($nomecolonna,$relazioni)) {
      echo "
    <select name=\"$nomecolonna\">
      <option value=\"\">scegli...</option>";

      $queryrelazione="SELECT ID,Nome FROM {$relazioni[$nomecolonna]} ORDER BY Nome";
      $risultatorelazione=mysql_query($queryrelazione);

      while($righerelazione=mysql_fetch_array($risultatorelazione)) {
        echo "
      <option value=\"{$righerelazione["ID"]}";
        if($value==$righerelazione["ID"]) echo "selected=\"selected\"";
        echo "\">".stripslashes($righerelazione["Nome"])."</option>";
      }

#  Abbiamo verificato se la selezione corrisponde a quanto precedentemente inserito
#+ e, nel caso affermativo, abbiamo aggiunto un "selected" all'opzione, che fa sì 
#+ che il valore corrente del campo sia quello visualizzato nel select.

      echo "
    </select>";

    } else echo "
    <input type=\"text\" name=\"$nomecolonna\" value=\"$value\" />";
    echo "
  </p>";
  }
}

#  In fondo alla pagina, aggiungiamo, per comodità, il link di ritorno alla tabella

echo <<<EOF2

  <p>
    <input type="submit" value="modifica" />
  </p>
  <p><a href="index.php?pagina=tabelle&tabella=$tabella">torna alla tabella <em>$tabella</em></a></p>
</form>
</fieldset>
EOF2;
?>
</div>

Salviamo come modifica.php.

Passiamo al file di raccolta dati. Alla fine della pagina aggiungiamo il secondo caso:

#  secondo caso: MODIFICA

elseif($azione=="modifica") {
  $record=$_GET["record"];

#  Quella che segue è una query di modifica...

  $query="UPDATE $tabella SET ";

#  Dopo averla iniziata, la completiamo in base al valore dei campi
#+ passati col form e con la condizione "WHERE" che verifica l'identificativo
#+ del record...

  foreach($_POST as $chiave=>$valore) $query.="$chiave='$valore',";
  $query.=" WHERE ID='$record'";

#  Nella query così composta, però, c'è una virgola in più dopo
#+ l'ultimo campo e non funzionerebbe; con la funzione "ereg_replace",
#+ pertanto, togliamo quella virgola...

  $query=ereg_replace(", WHERE"," WHERE",$query);

#  Eseguiamo la query e, quindi, torniamo alla pagina delle tabelle.

  mysql_query($query) or die("aggiornamento fallito");
  header("Location: ../index.php?pagina=tabelle&tabella=$tabella");
  exit;
}

Salviamo il file e proviamo a fare qualche modifica, cliccando sul link modifica nella pagine delle tabelle.

[modifica] Cancellazione

Procediamo ora alla cancellazione dei record, richiamabile con la seconda azione delle tabelle.

Una cosa sempre consigliabile è quella di predisporre una sorta di conferma alla richiesta di cancellazione. Possiamo farlo benissimo nella stessa pagina delle tabelle; infatti, si tratta di una piccola aggiunta: subito prima della visualizzazione della tabella (potremmo metterla anche dopo, ma, nel caso di una tabella voluminosa, la cosa sarebbe abbastanza scomoda...), inseriamo...

#  Se esiste "$_GET["cancellarecord"]" significa che è stata scelta la cancellazione
#+ del record; in tal caso, visualizziamo una richiesta di conferma...

if(isset($_GET["cancellarecord"])) echo "
   <p>
     <em>Sei sicuro di voler cancellare il record n. <strong>{$_GET["cancellarecord"]}</strong>?</em>
           
     <a href=\"index.php?pagina=tabelle&tabella=$tabella\" title=\"annulla la cancellazione\">NO</a>
           
     <a href=\"pagine/raccoltadati.php?azione=cancellazione&tabella=$tabella&record={$_GET["cancellarecord"]}\" 
       title=\"conferma la cancellazione\">SI</a>
  </p>\n";

Semplicemente: se clicchiamo su NO, torniamo indietro alla pagina delle tabelle senza far nulla; se, invece, clicchiamo su SI, veniamo dirottati sul file raccoltadati.php con azione, appunto, cancellazione. Quindi, in tale file, inseriamo il terzo caso:

#  terzo caso: CANCELLAZIONE

elseif($azione=="cancellazione") {
  $record=$_GET["record"];
  mysql_query("DELETE FROM $tabella WHERE ID='$record'") or die("cancellazione fallita");
  header("Location: ../index.php?pagina=tabelle&tabella=$tabella");
  exit;
}

Ogni commento è superfluo. Da notare come, ancora una volta, il linguaggio SQL ci sorprenda con la sua fluidità!

[modifica] Pausa di riflessione

Anche se ha molte limitazioni, col nostro sistema, di fatto, abbiamo realizzato un piccolo gestore di contenuti, che, se ulteriormente limato e arricchito di funzionalità, potrebbe essere sufficiente per una quasi completa gestione di un database MySQL.

Tuttavia, un obiettivo, da non perdere mai di vista durante l'elaborazione di un qualsiasi software, dovrebbe essere quello di riuscire ad ottenere il massimo risultato col minor spreco di risorse. E, allora, una cosa da verificare è se quello che abbiamo realizzato avremmo potuto ottenerlo con un minor numero di righe di codice. Se, scorrendo le nostre pagine, notiamo che ci sono troppe porzioni di codice ripetute, significa che non abbiamo sforzato abbastanza la meningi e che potremmo fare di meglio. Una soluzione potrebbe essere quella della definizione di funzioni...

[modifica] Definizione di Funzioni

Come ogni buon linguaggio di programmazione (o di scripting), oltre alle numerosissime funzioni predefinite (e che aumentano di versione in versione...), il PHP ci permette di definire le nostre funzioni, in base alle nostre esigenze. Come vedremo, la cosa ha numerosi vantaggi, non ultimo quello di snellire vistosamente le pagine di codice...

Facciamo subito qualche esempio...

Se scorriamo la pagina raccoltadati.php, notiamo, per esempio, come si ripeta il reindirizzamento fatto per il tramite della funzione header. Potrebbe essere il caso di definire una funzione, da richiamare ogni qual volta ci serva il reindirizzamento. La funzione potremmo inserirla nella stessa pagina, ma... consideriamo l'eventualità che la funzione ci serva anche in un'altra pagina: che facciamo, la ripetiamo anche lì? Assolutamente no! Allora creiamo una pagina a parte per le funzioni, così da poterla includere tutte le volte che ci serva.

Apriamo, quindi un nuovo file e scriviamo:

<?php
function reindirizza() {

}
?>

Per definire una funzione, si usa, pertanto, la parola chiave function. Quelle parentesi tonde (obbligatorie anche se vuote) servono a racchiudere eventuali parametri da passare alla funzione, perché bisogna tenere innanzitutto presente che:

  • quello che succede all'interno della funzione è indipendente dal resto della pagina;
  • eventuali variabili devono essere passate come parametri, da inserire, appunto, tra quelle parentesi tonde, oppure devono essere dichiarate quali global all'interno della stessa funzione;
  • se dobbiamo far fare il percorso inverso a delle variabili, ovvero se dobbiamo restituirle allo script, lo faremo tramite la parola chiave return.

Continuiamo,,,

<?php
function reindirizza() {
  header("Location: ../index.php");
  exit;
}
?>

Salviamo il file come funzioni.php ed includiamolo in testa a raccoltadati.php. Ora, in quella pagina, laddove avevamo un header..., sostituiamo con reindirizza() (parentesi obbligatorie!). Naturalmente, toglieremo anche quell'exit, che ora non serve più.

Facciamo qualche prova: vedremo che veniamo sempre reindirizzati alla index. Allora dobbiamo fare qualche modifica: all'interno delle parentesi, mettiamo un parametro e richiamiamolo, se valido, all'interno della funzione, per completare la query-string...

<?php
function reindirizza($paginainterna=0) {
  $location="Location: ../index.php";
  if($paginainterna) $location.="?$paginainterna";
  header($location);
  exit;
}
?>

Da notare quel $paginainterna=0, che serve a dare un valore di default al parametro, nel caso in cui la funzione venga richiamata senza parametro e quell'if($paginainterna), senza alcun operatore, che sfrutta la dicotomia booleana di vero/falso (ovvero se il parametro paginainterna è vero, quindi non-falso, quindi non 0...).

Compito per casa

Proviamo a trovare altre parti ripetitive di codice e a definire con esse altre funzioni, da salvare nel file funzioni.php.

A ben guardare, non è che abbiamo risparmiato quel granché di codice, ma ci siamo limitati ad un solo, semplice, esempio.

Ci fermiamo comunque qui con le funzioni, ma non le abbandoneremo: le riprenderemo sucessivamente, per chiamarle, però, metodi, in quanto parte di oggetti-contenitori, le cosiddette classi, che ci serviranno per rendere maggiormente produttivi i nostri script...

[modifica] Delle Variabili particolari

Le azioni del PHP (e dello scripting lato server in genere) si svolgono, appunto, sul server e destinano al client finale solo l'output dell'elaborazione. Esistono, tuttavia, delle particolari variabili che vanno invece ad incidere, in un certo qual modo, direttamente sul client e che hanno dei ruoli abbastanza importanti: i cookies e le sessioni.

[modifica] I Cookies

I cookies sono dei minuscoli file di testo che, in condizioni normali (ovvero se non disabilitati dall'utente), possono essere scritti in una particolare directory della home (o del profilo) dell'utente. Hanno la funzione di lasciare una traccia, in base a determinate scelte dell'utente, per mantenere tali scelte anche agli accessi successivi. I cookies hanno una scadenza, impostabile all'atto della definizione.

Poniamo il caso che noi vogliamo che l'utente possa memorizzare una formula di saluto e che se la ritrovi ogni volta che apre il sito: questo è un lavoro da cookie.

Nella nostra home, anzi nella sezione principale, sostituiamo il segnaposto latino con questo form:

<form action="" method="post">
<fieldset>
<legend>imposta formula di saluto</legend>
<label for="saluto">formula </label><input type="text" name="saluto" /> <input type="submit" value="imposta -> " />
</fieldset>
</form>

Il fatto di aver lasciato vuota l'action, significa che il form ha effetto sulla stessa pagina in cui si trova...

Poi, in testa alla home, inseriamo questa riga:

<h3 style="color:red"><?php if(isset($_COOKIE["saluto"])) echo $_COOKIE["saluto"] ?></h3>

E, in testa alla index (prima ancora della DOCTYPE), inseriamo la funzione per memorizzare il cookie (importante il successivo reindirizzamento):

<?php
if(isset($_POST["saluto"])) {
  setcookie("saluto",$_POST["saluto"],time()+15*24*60*60);
  header("Location: index.php");
  exit;
}
?>

Quel time()+15*24*60*60 significa che memorizziamo il cookie per 15 giorni (15 per 24 per 60 per 60 secondi, ovvero 1296000 secondi).

Proviamo ad impostare una formula di saluto e ad inviare... Il nostro cookie (a meno che non li abbiamo disabilitati da browser) funziona!

[modifica] Le Sessioni

La sessione è un altro particolare tipo di variabile, che si mantiene assegnata per tutta la durata, appunto, della sessione dell'utente, ovvero finché l'utente non chiude il browser o non agisce direttamente sulla sua de-assegnazione.

Per fare un esempio efficace sull'uso delle variabili di sessione, pensiamo al caso di un accesso autenticato al sito: alla eventuale possibilità, cioè, di permettere l'interazione con alcune pagine solo agli utenti in possesso di idonee credenziali di accesso.

[modifica] Un accesso autenticato

Facciamo qualche modifica alle nostre pagine...

Nella sezione secondaria della home, inseriamo un form di login, come segue:

<form action="pagine/raccoltadati.php?azione=login" method="post">
<fieldset>
<legend>login</legend>
<p>
  <label for="user">username </label>
  <input type="text" name="user" />
</p>
<p>
  <label for="pass">password </label>
  <input type="password" name="pass" />
</p>
<input type="submit" value="accedi -> " />
</fieldset>
</form>
<p><a href="index.php?pagina=home&sezione=principale">Vai alla sezione principale</a></p>

Nella sezione principale, modifichiamo il testo del link alla sezione sezione secondaria in login:

<p><a href="index.php?pagina=home&sezione=secondaria">Login</a></p>

Adesso ci serve una nuova tabella nel database, che chiameremo amministratori. Inseriremo anche un primo amministratore per avere la possibilità di accedere. Dalla console di MySQL, quindi...:

CREATE TABLE amministratori (
  ID tinyint(3) unsigned NOT NULL auto_increment,
  User varchar(50) NOT NULL,
  Pass char(32) NOT NULL,
  PRIMARY KEY  (ID)
) ;
INSERT INTO amministratori VALUES
(1, 'admin', MD5('mypass'));

Abbiamo usato la funzione di MySQL MD5 per salvare la password su database in uno dei formati criptati. Non è mai consigliabile salvare una password in chiaro, anche se il nostro espediente non farà nient'altro che impedire la lettura immediata della password dal database, mentre gli acorgimenti di sicurezza dovrebbero essere ben altri e dovrebbero intervenire in momenti più delicati (ne accenneremo in seguito...).

Ora dobbiamo l'inserire l'azione di login nel file di raccolta dati. Innanzitutto (cosa molto importante), non dobbiamo assolutamente dimenticare di inserire, in testa alla stessa pagina, la funzione che ci permette di usare le variabili di sessione:

session_start();

E poi...:

#  quarto caso:  LOGIN

elseif($azione=="login") {
  $user=$_POST["user"];
  $pass=md5($_POST["pass"]);
  $risultatoamministratore=mysql_query("SELECT ID FROM amministratori WHERE User='$user' AND Pass='$pass'");

#  Se la query ci restituisce un insieme vuoto, significa che le credenziali non sono valide

  if(mysql_num_rows($risultatoamministratore)==0) 
     reindirizza("pagina=home&sezione=secondaria&messaggio=UTENTE-NON-AUTORIZZATO");

#  Altrimenti registriamo le nostre variabili di sessione; per praticità, visto che la query,
#+ in questo caso, ci restituisce un'unica riga, usiamo la funzione "mysql_result", coi parametri
#+ "risorsa","riga","chiave", non essendoci bisogno di dover "sfogliare" più righe... 

  else {
    $_SESSION["utenteautorizzato"]=mysql_result($risultatoamministratore,0,0);
    reindirizza("pagina=home&sezione=secondaria&messaggio=ACCESSO-ESEGUITO");
  }
}

Abbiamo fatto riferimento, nelle query-string, ad una variabile messaggio, che finora, però, non abbiamo visto. Nella nostra sezione secondaria, pertanto, all'interno del fieldset, aggiungiamo:

<p style="color:red"><strong><?php if(isset($_GET["messaggio"])) echo $_GET["messaggio"] ?></strong></p>

Abbiamo però bisogno anche del percorso inverso, ovvero il logout (o logoff che dir si voglia). Pertanto, alla fine del form, inseriamo questo link:

<p><a href="pagine/raccoltadati.php?azione=logout">Logout</a></p>

E aggiungiamo l'azione di logout nello script di raccolta:

#  quinto caso: LOGOUT

elseif($azione=="logout") {
  session_unset();

#  Praticamente, abbiamo azzerato le variabili di sessione.

  reindirizza("pagina=home&sezione=secondaria&messaggio=LOGOUT-ESEGUITO");
}

Adesso, diamo un senso al nostro accesso autenticato.

Prima, abbiamo visto come sia facile inserire o modificare dei record del database; non è opportuno, però, dare questa opportunità a chiunque e l'accesso autenticato può servirci, appunto, per consentire solo alle persone di fiducia questo tipo di intervento.

Apriamo, quindi, la nostra index e, anche in questo caso, in testa alla pagina, inseriamo:

session_start();

Poi, subito dopo (poi vedremo il perché lo mettiamo in testa alla pagina), inseriamo l'array che segue (e spostiamo da quelle parti anche l'assegnazione della pagina):

$pagineriservate=array("inserimento","tabelle");
isset($_GET["pagina"]) ? $pagina=$_GET["pagina"] : $pagina="home";

E modifichiamo il menu come segue:

$vocimenu=array("home","inserimento","tabelle","pinzillacchere");
foreach($vocimenu as $voce) {
  if(!in_array($voce,$pagineriservate) || isset($_SESSION["utenteautorizzato"])) {

#  Cioè: se la voce di menu non figura nell'array di quelle riservate,
#+ oppure (tenere presente che quell'|| significa "or esclusivo"), se figura
#+ ma, nello stesso tempo, è assegnata la variabile di sessione che
#+ indica che l'utente è autorizzato...

    echo "
  <li>";
    if($pagina!=$voce) echo '<a href="index.php?pagina='.$voce.'">';
    echo $voce;
    if($pagina!=$voce) echo "</a>";
    echo "</li>";
  }
}
echo "\n";

Ora proviamo a switchare tra login e logout: noteremo come le due voci di menu inserimento e tabelle compaiono e scompaiano in relazione al fatto che siamo autenticati o meno.

Un furbetto, però, a quaesto punto, cosa farebbe? Inserirebbe direttamente la query-string nella barra dell'indirizzo del browser, in questo modo (per esempio)...

index.php?pagina=inserimento

...prendendoci in giro per la nostra ingenuità. Allora dobbiamo correre ai ripari e metteremo, in testa alla index, subito dopo l'array che abbiamo inserito prima (ecco spiegato il perché della sua posizione...) una bella condizione che vada a verificare se siamo utenti autorizzati:

if(in_array($pagina,$pagineriservate) && !isset($_SESSION["utenteautorizzato"])) {

#  Ovvero: se la pagina fa parte di quelle riservate e non (il ! significa "not")
#+ è sata assegnata la variabile di sessione "utenteautorizzato", ti sbatto
#+ alla pagina di login...

  header("Location: index.php?pagina=secondaria&messaggio=DEVI-AUTENTICARTI!");
  exit;
}

E il nostro furbetto può andare a farsi un giro...!

[modifica] Cenni sulle connessioni cifrate

Il momento particolarmente delicato (in termini di sicurezza) cui accennavamo prima è quello del login vero e proprio. Anche se noi abbiamo provveduto a criptare la password su database, non dobbiamo dimenticare che, prima i giungere al server, la nostra password fa un bel viaggetto in rete in chiaro e, durante questo tragitto, può essere bellamente sniffata da qualcuno che ne sa più di noi (e ce ne sono tanti in giro!).

Come fare? Beh, se i nostri dati non sono di importanza vitale, se dalla loro integrità e sicurezza non dipende la nostra vita e la sicurezza nazionale e (cosa importante) abbiamo predisposto un backup ricorrente del nostro database, allora possiamo anche correre il rischio. Altrimenti, sarebbe il caso di ricorrere ad una connessione cifrata, col protocollo (ad esempio) SSL (Secure Sockets Layer), che fa sì che i dati che noi spediamo per la rete siano criptati con tecniche raffinate, per cui possiamo permetterci di dormire sonni (quasi) tranquilli.

Il discorso è però troppo ampio per essere affrontato adeguatamente in questo tutorial...

[modifica] ToDo

Quello che abbiamo visto finora, anche se interessante e discretamente efficace, non costituisce il nostro punto di arrivo.

Ancora c'è tanta strada da fare.

Pur non pretendendo di acquisire tutto lo scibile del PHP (sarebbe una bella presunzione), dobbiamo stabilire un traguardo: dobbiamo almeno introdurci nell'OOP (Object Oriented Programming), ovvero nel PHP ad oggetti.

Alla prossima...

[modifica] Collegamenti esterni


Autore: aschenaz

Strumenti personali
Namespace

Varianti