AJAX, PHP – Le basi di ajax: cos’è e come farlo interagire con php – Esempio completo

Da quando è venuto alla luce, Ajax ha dimostrato subito il suo potenziale. Il suo stesso nome – acronimo di “Asynchronous Javascript and Xml” – lascia un indizio su cosa è capace di fare: chiamate “asincrone”.
Cosa significa? Ajax è stato progettato per creare applicazioni web interattive, cioè per aggiornare in modo dinamico una pagina web senza che l’utente debba ricaricarla. Una volta chiamata la richiesta, non dobbiamo aspettare che finisca per eseguire altre operazioni. In parole povere, può chiamare pagine php, eseguirle e stampare a video il risultato senza dover ricaricare la pagina.

Il potenziale è enorme. Come sappiamo, il javascript è eseguito lato client (cioè direttamente dal browser dell’utente, tant’è che è possibile far funzionare in locale una pagina html contenente script in javascript, senza bisogno di una connessione internet e di un server apposito), mentre il php è lato server (l’uso corretto in locale è possibile solo attraverso un programma che simuli un server adatto). Per eseguire un codice javascript non serve il caricamento della pagina, mentre il php ha bisogno di inviare i dati al server, elaborarli e rimandarli indietro, mostrandoli solo se la pagina viene ricaricata.
Ajax, quindi, è una vera rivoluzione.

L’unica pecca di questa meraviglia – come sempre – è che il browser deve essere aggiornato per supportarlo, anche se ai nostri giorni qualsiasi browser si prodiga per restare al passo con i tempi e raramente ne incontreremo uno “inabile”.

In questo articolo mostrerò un esempio completo su come far interagire Ajax con il php.
Prenderemo una select contenente le regioni italiane e faremo in modo che, in base al valore scelto, appaia in tempo reale una seconda select prima nascosta, contenente le province della regione. Le province saranno prese da un database, che sarà interrogato tramite php.

Nell’articolo dò per scontato che si abbia una conoscenza delle basi di PHP e di come interagisce con un database di tipo MySQL. Utile sarà anche avere una base di Javascript e di Ajax (anche minima), ma non è indispensabile: ogni parte, infatti, sarà dovutamente commentata in modo che possiate eventualmente approfondire con delle ricerche personali.

Download script

Il database

Nel database ci basteranno solo due tabelle: l’elenco delle regioni italiane e l’elenco delle province, che avranno un campo di join con la tabella delle regioni. Qui sotto i dump delle due tabelle, con alcuni valori inseriti (si tratta di un esempio minimale, lo stretto necessario per capire l’esempio).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
CREATE TABLE IF NOT EXISTS `regioni` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

INSERT INTO `regioni` (`id`, `nome`) VALUES
(1, 'Lazio'),
(2, 'Sardegna'),
(3, 'Veneto');

CREATE TABLE IF NOT EXISTS `province` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_regione` tinyint(4) NOT NULL DEFAULT '0',
  `nome` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=111;

INSERT INTO `province` (`id`, `id_regione`, `nome`) VALUES
(1, 3, 'Verona'),
(2, 3, 'Vicenza'),
(3, 3, 'Belluno'),
(4, 3, 'Treviso'),
(5, 3, 'Venezia'),
(6, 3, 'Padova'),
(7, 3, 'Rovigo');

Il codice html per la select

Fingiamo per un momento che lo script in Ajax sia già stato predisposto e creiamo le componenti della pagina come se fosse fatta semplicemente in php.
Creiamo una pagina index.php. Lascio a voi il compito di costruire il layout, l’header e il footer. Quello che importa è che, con il php, apriate una connessione con il database in cui avete appena creato le tabelle.

Il corpo della nostra pagina conterrà una select come questa (ho preparato le classi css, che dovrete occuparvi di formattare a seconda del bisogno):

1
2
3
4
5
6
7
8
9
10
11
12
13
<form id="form" class="formquery" action="" method="post" name="form">
<div class="titolo">Scegli la regione</div>
<div class="riga"><?php
$select = "SELECT * FROM regioni";
$query = mysql_query($select);
?><select id="regione" class="select1" name="regione" onchange="caricaProvince(this.value)"> <?php
while($regioni = mysql_fetch_array($query)){
	?><option value="<?=$regioni['id']?>"><?=$regioni['nome']?></option> <?php
}
?>
</select></div>
<div class="titolo">Scegli la provincia</div>
</form>

In pratica avremo “in chiaro” la select contenente le nostre regioni, prese dalla tabella del database.
La parte contenuta nel div che ha id=”provincia” sarà invece caricata dinamicamente: in base al valore scelto nella prima select, cercheremo le province legate alla regione e le stamperemo qui come una nuova select.

Il file “carica_province.php”

Lo script incaricato di prelevare le province in base alla regione scelta sarà in file php a parte, che chiameremo carica_province.php.
Il suo contenuto sarà questo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
//qua va il codice per aprire una connessione al db
if(isset($_POST['regione'])){
	$select = "SELECT * FROM province WHERE id_regione=".$_POST['regione']." order by nome";
	$query = mysql_query($select);
	?><select id="select_province" class="select1" name="province"> <?php
	while($province=mysql_fetch_array($query)){
		?><option value="<?=$province['id']?>"><?=$province['nome'] ?></option>
        <?php
	}
	?>
        </select>
<?php
}
?>

Niente di complicato, è una comunissima pagina php. In base al valore della regione passata, eseguo una query ed estraggo le sue province.
Da notare che, essendo un file esterno al precedente, dobbiamo ripetere lo script in php che apre la connessione con il database.

Poniamo che la regione scelta sia il Veneto. Se stampassimo a video questa pagina come siamo abituati a fare di solito, vedremmo semplicemente una select contenente l’elenco delle province del Veneto; ma avremmo dovuto ricaricare la pagina.
Con Ajax, invece, la select sarà stampata senza ricaricare la pagina, nel div con id=”provincia” che abbiamo visto sopra.

La parte in html è pronta, non c’è altro da aggiungere.
A questo punto occupiamoci del vero “core” dello script: Ajax.

La chiamata ad Ajax

Il mio primo utilizzo di Ajax è stato traumatico, a causa del solito Internet Explorer, che sembrava voler ostacolarmi a tutti i costi. Dopo diversi esperimenti, sono riuscito a trovare uno script ottimale, che uso ormai da diverso tempo senza problemi.
Perché Ajax funzioni anche su Explorer, è necessario includere a inizio pagina questo codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript" language="javascript">// <![CDATA[

var myRequest = null;

function CreateXmlHttpReq(handler) {
  var xmlhttp = null;
  try {
	xmlhttp = new XMLHttpRequest();
  } catch(e) {
	try {
		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch(e) {
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
  }
  xmlhttp.onreadystatechange = handler;
  return xmlhttp;
}
// ]]></script>

La funzione CreateXmlHttpReq() sarà da richiamare ogni volta che dovremo fare uso di Ajax.
Sotto a questa funzione, inserite queste altre due funzioni (al momento ignorate i commenti, li vedremo subito sotto):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">// <![CDATA[

function caricaProvince(valore){
	myRequest = CreateXmlHttpReq(appendi_province); //apre la funzione appendi_province
	myRequest.open("POST","carica_province.php"); //apre carica_province.php e gli indica che i valori passati devono essere considerati POST
	myRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //indica che il contenuto di risposta sarà di tipo html-utf8
	myRequest.send("regione="+valore); //fa passare $_POST['regione']=valore al file carica_regione.php
	myRequest.setRequestHeader("connection", "close"); //chiude la connessione ajax
}

function appendi_province(){
	if(myRequest.readyState==4 &#038;& myRequest.status==200){
		var a=document.getElementById("provincia");
		a.innerHTML="";
		a.innerHTML=myRequest.responseText; //stampa il contenuto html passato all'interno dell'elemento con id="provincia"
		$(".select1").selectbox(); //è una funzione fittizia in js che formatta l'aspetto della select (usata solo ai fini dell'esempio)
	}
}
// ]]></script>

Cosa abbiamo fatto?
Ho commentato ogni riga, ma vanno fatte delle precisazioni. Chi è abituato a pensare in modo sincrono (come nel php), dovrà fare uno sforzo.

Una volta aperta la richiesta, Ajax passa attraverso quattro stadi:
1) richiesta aperta, ma i dati non sono ancora stati inviati
2) richiesta (dati) inviata
3) i dati sono ricevuti e comincia la loro lettura
4) operazione completata

Usando l’esempio qui sopra, in sequenza:
* apre la funzione appendi_province();
* apre il file carica_province.php;
* fa passare a carica_province.php la variabile “regione”: il valore di questa variabile viene fatto passare come parametro della funzione caricaProvince(). La variabile “regione” è stata fatta passare come post, ma nulla vieta di farla passare come get, apportando le dovute modifiche al file php.
* esegue il cotenuto di carica_province.php, che stamperà l’elenco delle province in una select.
* appendi_province() viene eseguita quattro volta: una per ogni stato in cui passa l’Ajax (1, 2, 3, 4); poiché ho messo la condizione if(myRequest.readyState==4) nella funzione, il contenuto html di carica_province.php verrà mostrato solo al raggiungimento del quarto stadio. Questa funzione immetterà il contenuto html (elenco delle option) nella select con id=”provincia”
* quando appendi_province() ha finito, chiude la connessione ajax

Notate che, poiché la pagina non viene caricata una volta eseguito lo script, sarà necessario richiamare esplicitamente le eventuali funzioni javascript che vengono applicate sulla select appena fatta comparire. Nell’esempio qui sopra, ho aggiunto la riga:

1
$(".select1").selectbox();

che formatta con una funzione javascript (più precisamente jquery) tutte le select aventi classe con valore “select1” (cioè entrambe le select che abbiamo creato). Se non l’avessi richiamata, sarebbe stata formatta la select delle regioni, ma non quella delle province. Nel vostro caso questa funzione è utile solo ai fini dell’esempio (a meno che non creiate una funzione js chiamata selectbox() ), per cui potete eliminare la riga.

Ringraziamenti

Ringrazio Michele Mirandola per l’aiuto nella realizzazione dell’articolo

Ultimi Commenti
  1. enrico
  2. Davide
  3. Davide
  4. Davide
  5. Davide
    • Davide
  6. Giuseppe Ferrara

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *