Blog

Search by tag: php

July 08, 2009 16:57 - 15 comments

Ok, vi risparmio la battuta sugli insetti :)

Facebook DeveloperFacebook mette a disposizione di tutti gli utenti/programmatori un comodo set di funzioni, che in gergo si chiamano API (Application Programming Interface), scritte in vari linguaggi web, per interagire con la piattaforma del popolare social network e sviluppare le proprie applicazioni, siano esse integrate in Facebook (la maggior parte sono così) oppure applicazioni “stand-alone”, cioè fruibili da un sito esterno ma collegate alla banca dati di Facebook.

Fb rende l’impatto tra il programmatore e le API molto semplice, ponendolo di fronte ad un’interfaccia per gli sviluppatori che guida passo passo nella creazione delle applicazioni, integrandosi con utili strumenti come il Wiki ed una Test Console, che permette di effettuare chiamate di prova alle varie funzioni, specificandone i parametri, e ricevendo in risposta il relativo output in formato leggibile.

Le API si compongono di una parte che gira lato server dell’utente, le librerie client, ed una parte in formato markup che viene processata dal server di Facebook, il quale produce normali tag HTML interpretando un linguaggio ideato da Facebook chiamato FBML.

Il programmatore potrà utilizzare le librerie client ufficiali in PHP oppure una di quelle non ufficiali, disponibili in tantissimi linguaggi tra cui Java, Ruby on Rails, Perl, Python, .Net.
Con queste librerie bisognerà produrre un codice sorgente, che avrà un output in HTML, XML oppure FBML e che, anche nel caso di applicazioni da integrare in Facebook, dovrà essere ospitato presso un server web esterno per poi essere collegato a Facebook tramite l’interfaccia di amministrazione dell’applicazione. Quindi bisognerà trovare un hosting web, anche gratuito, che fornisca lo spazio per l’applicazione.

Facebook non chiede nient’altro, perchè consente ai programmatori di salvare le informazioni utilizzate dalle applicazioni in un vero e proprio database, il DataStore, in cui è possibile memorizzare i dati necessari a ciascun utente, senza doversi procurare un database su un server esterno, che costituirebbe una spesa sicuramente più grossa dello spazio web.
Anche per quanto riguarda il database Facebook ha “inventato” qualcosa: si chiama FQL, ed è un derivato del SQL che ha lo scopo di interrogare il database di Facebook ponendo alcune restrizioni sui permessi di accesso alle tabelle, perchè ogni utente può accedere solo alle informazioni proprie e dei propri amici che le condividono, non di più.

Per iniziare, una applicazione di esempio potrebbe essere questa:


<?php
require_once ‘client/facebook.php’;

$appapikey = ‘YOUR_API_KEY’;
$appsecret = ‘YOUR_APP_SECRET’;
$facebook = new Facebook($appapikey, $appsecret);

$user_id = $facebook→require_login();
$friends = $facebook→api_client→friends_get();
?>

<p>Ciao, !</p>

<p>I tuoi amici:
<ul>
<? foreach ($friends as $friend) { ?>
<li><fb:name uid=“<?= $friend ?>” useyou=“false” /></li>
<? } ?>
</ul></p>
?>

YOUR_API_KEY e YOUR_APP_SECRET vanno sostituiti con i codici assegnati da Facebook, che identificano univocamente l’applicazione e le consentono di effettuare le chiamate alle API per le quali è stata autorizzata inizialmente.

L’oggetto $facebook diventa l’interfaccia verso la piattaforma, la quale viene interrogata tramite le varie funzioni in PHP5 (ad oggetti).

I tag che inziano con <fb: sono i tag FBML di cui parlavo prima: essi verranno interpretati da Facebook e diventeranno, in questo caso, dei collegamenti ai profili specificati nell’attributo uid. Il particolare il primo diventerà un link al profilo dell’utente dell’applicazione ($user_id) e l’altro sarà un link al profilo di uno degli amici ($friend).

Per iniziare può bastare quanto detto finora, ma l’appetito vien mangiando… le possibilità sono infinite!

Per esempio utilizzando la seguente chiamata

$facebook→api_client→call_method(“facebook.status.get”,
array(‘uid’=>$user_id, ‘limit’=>10));

ho ottenuto tutto il necessario per realizzare sul mio sito la parte del modulo Social Networks relativa a Facebook (beh… in realtà ho dovuto realizzare un wrapper RSS perchè il sito è in Ruby On Rails, mentre la libreria è in PHP).

Buon divertimento! :)


Mi capita sempre + spesso di parlare di AJAX e descriverlo come “facile da programmare” a persone che ancora non si sono avvicinate alla programmazione web avanzata. E’ ovvio che in questo caso non riesco ad essere molto credibile! :)
Quindi ecco qui una ppppiiiiccola guida passo passo per comprendere cosa veramente ci permette di fare questa nuova tecnologia. Credo che per leggere tutto senza fatica serva un minimo di conoscenza della programmazione web… o una bella fantasia! :P
Ah, per realizzare il tutto è necessario avere installati sulla propria macchina, o anche su una macchina remota, un server HTTP (io uso Apache 2.2) funzionante con PHP ed un server MySQL. Tutto open source naturalmente… basta scaricare ed installare! ;)

AJAX (Asynchronous Javascript and XML)… tutto si basa sul concetto di “comunicazione asincrona” con il server: noi clicchiamo su un link o un pulsante per eseguire un’azione su dei dati remoti (che possono essere righe di database, file sul disco del server, ecc…) e ne vediamo subito le conseguenze, ancor prima che le azioni siano comunicate al server.
Quindi, mentre noi andiamo avanti a navigare e a fare altro, un javascript si occupa (con molta tranquillità) di comunicare al server l’azione che abbiamo eseguito “virtualmente”… sicchè il server capisce il da farsi ed esegue di fatto le azioni.
Il vantaggio? E’ stato eliminato il tempo di latenza della comunicazione client-server ed anche il reload della pagina! :)

Inoltre, sempre grazie ad AJAX, possiamo cambiare radicalmente il contenuto di una pagina web (tramite manipolazione DOM), richiedendo dati al server in formato XML o testo semplice, e sempre senza ricaricare la pagina… che per siti abbastanza complessi è una vera seccatura!

Andiamo al lato pratico della questione: il fondamento di AJAX è un oggetto javascript che si chiama XMLHttpRequest.
A causa delle differenti implementazioni sui diversi browser, questo oggetto viene creato tramite una funzione cross-browser che si scrive una volta e poi si può dimenticare tranquillamente. :)

function createXMLHttpRequest() {
	try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
	try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
	try { return new XMLHttpRequest(); } catch(e) {}
	alert("XMLHttpRequest not supported");
	return null;
}

Quindi abbiamo capito che questa funzione restituisce il giusto oggetto per le chiamate AJAX, a seconda del browser. Cominciamo mettendola dentro un file di testo e chiamiamolo ajax.js.

Adesso dobbiamo decidere cosa fargli fare. Uhm… facciamo finta di avere una tabella in HTML con tante righe prese dal database sul server… e vogliamo che alla pressione di un pulsantino accanto alla riga, questa venga cancellata dalla pagina e anche dal DB.
Ovviamente la cancellazione “visuale” avverrà subito tramite manipolazione DOM e la cancellazione “reale” avverrà con i suoi tempi tramite una chiamata AJAX.

La parte che ci interessa della pagina HTML, cioè la tabella, potrebbe essere generata da un semplice script PHP, che non riporto. Nell’esempio successivo infatti realizzeremo questo passo in AJAX.

Ma andiamo alla nostra tabella. Nella pagina HTML, in mezzo a tutto il resto, avremo qualcosa del genere:

<html>
<head>
	<title>Test AJAX 1</title>
	<script type="text/javascript" src="ajax.js"></script>
</head>
<body>
<table id="tabella">
	<tr id="riga_1">
		 <!-- QUESTO E' IL DATO PROVENIENTE DAL DB... -->
		<td>Testo 1</td>
		 <!-- ...E QUESTO E' IL PULSANTINO DI ELIMINAZIONE -->
		<td><input type="button" value="Elimina" onclick="elimina_riga(1)" /></td>
	</tr>
	<tr id="riga_2"> <!-- ALTRE RIGHE PER RENDERE LA COSA UN PO' VEROSIMILE -->
		<td>Testo 2</td>
		<td><input type="button" value="Elimina" onclick="elimina_riga(2)" /></td>
	</tr>
	<tr id="riga_3">
		<td>Testo 3</td>
		<td><input type="button" value="Elimina" onclick="elimina_riga(3)" /></td>
	</tr>
</table>
</body>
</html>

… e la funzione Javascript (dentro il file ajax.js) che svolgerà l’azione sarà più o meno così:

function elimina_riga(id) {
	
	// LA RIGA VIENE CANCELLATA DALLA PAGINA WEB
	riga = document.getElementById("riga_"+id);
	riga.parentNode.removeChild(riga); 
	
	// E ADESSO CANCELLIAMOLA _VERAMENTE_ DAL DB
	var xhReq = createXMLHttpRequest();
	xhReq.open("POST", "elimina_riga.php", true);
	xhReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xhReq.onreadystatechange = function() {
		if (xhReq.readyState == 4)  {
			if(xhReq.status == 200) {
				// PER SICUREZZA CONTROLLIAMO CHE L'AZIONE SIA ANDATA A BUON FINE
				if(xhReq.responseText!="1") {
					alert("Hey, qualcosa è andato storto!");
				}
			}
		}
	}
	xhReq.send("id="+id);
}

Sul server ci sarà uno script elimina_riga.php che esegue l’azione asincrona sul database. Per completezza:

<?php
if(is_numeric($_POST['id'])) { // EVITIAMO ATTACCHI DI SQL INJECTION

	mysql_connect('localhost', 'username', 'password'); // CONNESSIONE AL DB
	mysql_select_db('database');

	if(mysql_query("DELETE FROM tabella WHERE id=".$_POST['id']))
		echo "1"; // ET VOILA'... RIGA CANCELLATA!
	else
		echo "0";
}
?>

Ho omesso tutti i controlli su un’eventuale autenticazione (che si potrebbe fare molto facilmente con le variabili di sessione del PHP), perchè è un argomento che non riguarda questo tutorial.

Beh… a questo punto il primo passettino con AJAX è stato fatto! :)
Adesso possiamo vedere qualcosa di più complicato… la richiesta di dati in formato XML!

L’XML è utile per organizzare i dati in una struttura ad albero schematica e allo stesso tempo flessibile dal punto di vista del programmatore.

Supponiamo di voler creare la tabella HTML dell’esempio precedente, utilizzando i dati presi dal database: la tabella sarà creata al carimento della pagina tramite una XMLHttpRequest e la manipolazione DOM del documento.

La pagina HTML dovrà associare all’evento di caricamento della pagina la funzione javascript per la creazione della tabella:

<html>
<head>
	<title>Test AJAX 2</title>
	<script type="text/javascript" src="ajax.js"></script>
</head>
<body onload="popola_tabella()">

<table id="tabella">
</table>

</body>
</html>

leggi_tabella.php è uno script PHP lato server che produce il file XML che ci serve per popolare la nostra tabella:

<?php
header("Content-Type: text/xml");
echo "<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>\n";

mysql_connect('localhost', 'username', 'password'); // CONNESSIONE AL DB
mysql_select_db('database');

?>
<tabella>

<?php
$query = mysql_query("SELECT id, testo FROM tabella");
while($riga = mysql_fetch_assoc($query)) {
?>
	<riga id="<?=$riga['id']?>"><?=$riga['testo']?></riga>
<?
}
?>

</tabella>

Il risultato che avremo sarà come questo:

<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>
<tabella>
	<riga id="1">Testo 1</riga>
	<riga id="2">Testo 2</riga>
	<riga id="3">Testo 3</riga>
</tabella>

e servirà una funzione javascript per richiedere la pagina XML al server ed interpretarla per farla diventare codice HTML.

Dentro ajax.js avremo la funzione principale:

function popola_tabella() {
	var xhReq = createXMLHttpRequest();
	xhReq.open("POST", "leggi_tabella.php", true);
	xhReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xhReq.onreadystatechange = function() {
		if (xhReq.readyState == 4)  {
			if(xhReq.status == 200) {
				xml = xhReq.responseXML;
				if(xml!=null) {
					// INDIVIDUA L'ELEMENTO tabella NELLA PAGINA HTML
					tabella = document.getElementById("tabella"); 
					// ELEMENTO tabella NEL FILE XML
					var xmlTabella = xml.getElementsByTagName("tabella")[0];
					// TUTTE LE RIGHE DELLA TABELLA NEL FILE XML 
					var xmlRighe = xmlTabella.getElementsByTagName("riga");  

					for(i=0;i<xmlRighe.length;i++) { // PER OGNI RIGA....
						xmlRiga = xmlRighe<i>;

						// LEGGE L'ID DELLA RIGA
						id = xmlRiga.getAttribute("id");

						// LEGGE IL TESTO CONTENUTO
						testo = xmlRiga.childNodes[0].nodeValue;

						// CREA UNA NUOVA RIGA
						riga = document.createElement("tr");

						// IMPOSTA L'ID
						riga.setAttribute("id","riga_"+id);

						// CREA LA CELLA CON IL TESTO
						cella1 = document.createElement("td");      
						cella1.innerHTML = testo;

						// CREA LA CELLA CON IL PULSANTE ELIMINA
						cella2 = document.createElement("td");       

						// CREA IL PULSANTE ELIMINA
						elimina = document.createElement("input");  
						elimina.setAttribute("type","button");
						elimina.setAttribute("value","Elimina");
						elimina.onclick = function() { elimina_riga(id); };

						// AGGIUNGE IL PULSANTE ELIMINA ALLA CELLA
						cella2.appendChild(elimina);

						// AGGIUNGE LE CELLE ALLA RIGA
						riga.appendChild(cella1);
						riga.appendChild(cella2);

						// AGGIUNGE LA RIGA ALLA TABELLA
						tabella.appenChild(riga);
					}
						
				}
			}
		}
	}
	xhReq.send("");	
}

E’ da notare che il codice che viene scritto dopo xhReq.onreadystatechange = function() { è da trattare come una funzione separata, che viene invocata quando la virtual machine rileva un cambiamento dello stato della XMLHttpRequest. Ciò implica che non potremo accedere da questo codice alle variabili utilizzate all’interno della funzione chiamante.

… direi che abbiamo finito! :lol:

Bene! :) Adesso chi volesse approfondire potrebbe utilizzare questi piccoli esempi come base per costruire qualcosa di più complesso. Vi assicuro che quanto c’è di più difficile nella programmazione AJAX è stato trattato in questo tutorialino-ino-ino! ;)

Maggiori informazioni sulle funzioni per la manipolazione DOM le potete trovare facilmente su Google.

Sperando di essere stato utile a qualcuno… vi auguro buona programmazione! :D