So, da ich aktuell ein wenig am Weblog meiner Freundin arbeite hatte ich in diesem Zuge auch einmal Gelegenheit deren Seite als meine kleine Sandbox zu missbrauchen, was ihr letztendlich nur zu gute kommt.

Nur vorab, über die Seite an sich werde ich wohl gesondert nochmal berichten wenn wirklich alles “perfekt” steht, die aufmerksamen Leser unter euch kennen die Seite aber wohl eh schon.

Nun will ich den ganzen Keywords im Titel aber auch gerecht werden.

Also, ich wollte eigentlich einfach mal ein bisschen mit der Twitter-API spielen. Ziel sollte es sein das die letzten 10 Updates von Danis Twitter-Account öffentlich auf der Seite dargestellt werden können, obwohl ihr Account aber für die Öffentlichkeit gesperrt ist. Hauptgrund dafür war eigentlich nur die wilde Indexierung durch Google.

Nun unterstützt Twitter von Haus aus das abholen der Updates im JSON-Format und rein zufällig kann auch jQuery von Haus aus mit JSON wunderbar umgehen, selbst wenn die Dateien auf einer fremden Domain liegen.

Nun wäre es natürlich sehr einfach eine kleine Anwendung zu schreiben (bei Ralph wird alles gut beschrieben) in der sich der Browser bei jedem Seitenaufruf direkt die .json-Datei von Twitter bezieht und diese optisch auf der Seite darstellt. Nun gibt es jedoch ein paar Gründe die aus meiner Sicht dagegen sprechen fremde API-Dateien direkt in seinem JavaScript zu benutzen.

Nachteile die da wären:

  1. Der Twitter-Server könnte überlastet sein.
  2. Manchmal will man die Herkunft der Daten verschleiern.
  3. Wir müssen das Ergebnis erstmal unbearbeitbar hinnehmen.
  4. Viele APIs machen bei zuviel Traffic irgendwann dicht.
  5. Der DNS-Resolve auf eine Fremddomain dauert doch meist.
  6. … und die meisten API-Server sind auch nicht die schnellsten.

Aus diesem Grund habe ich mich für etwas entschieden das ich hier mal einen PHP-CURL-CACHE-Proxy nennen möchte. Im Prinzip ist der Sinn hinter diesem Script ein ganz simpler, denn wir haben eigentlich nur Vorteile davon den Server die meiste Arbeit machen zu lassen.

Vorteile die wir ausnutzen sollten:

  1. Antwortet der API-Server nicht, oder gibt einen Fehler zurück behalten wir das letzte valide Ergebnis erstmal im Cache, wir verhindern also Fehlermeldungen.
  2. Niemand kann direkt sehen wo unsere Quelle für die Daten liegt.
  3. Wir können das Ergebnis vor der Ausgabe beliebig Manipulieren, z.B. URLs löschen oder Namen ausschwärzen etc. pp.
  4. Nur unser Server greift auf die API zu, und das in einem bestimmten Zeitintervall, z.b. alle 180 Sekunden, auch wenn sich in dieser Zeit 600 Benutzer auf der Seite tummeln.
  5. Ajax/jQuery sieht lokale XML, JSON und TXT-Dateien als vertrauenswürdiger an und lässt z.b. auf externe Dateien keine Timeout-Option zu.

Es geht hierbei also nicht um die Struktur des JavaScript, das hat (wie schon gesagt) der Ralph ganz gut beschrieben, sondern nur um die Adresse von der wir unser Resultat beziehen.

Ok, und so wird (laienhaft) gemacht:

Zuerst brauchen wir 2 Dateien zum Cachen der Daten. In die erste Datei wird der Timestamp der letzten aktualisierung geschrieben, in die andere Datei packen wir das Resultat was wir vom API-Server bekommen haben. Warum wir das nicht in eine Datei packen? Gute Frage, prinzipiell wäre das wohl auch irgendwie möglich, ich fand es aufgrund der unterschiedlichen Encodings jedoch als leichter beide Werte getrennt zu behandeln. Um vernünftig mit der API arbeiten zu können sollte auf eurem Server die cURL-Extension vorhanden sein, welche es uns auf einfachste Art ermöglicht, fremde Seiten und Dateien abzugreifen.

Hier nun auf die schnelle mein Kleines PHP-Script:

//Erstmal kontrollieren wir ob der Referer
//auch unserer Domain entspricht und ob die
//Anfrage ein XMLHttpRequest ist.
if($HTTP_SERVER_VARS['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' && strpos($HTTP_SERVER_VARS['HTTP_REFERER'], $_SERVER['SERVER_NAME']) == false){
	exit();
}
//Pfad zur Timestamp-Datei
$cache['keys'] = 'cache/keys.txt';
//Pfad zum Cache-Content
$cache['twitter'] = 'cache/twitter.txt';
//Zeit die das Resultat im Cache gehalten werden soll (180 Sekunden)
$cache['time'] = time()-180;
//Wir schauen wann der Cache das letzte mal aktualisiert wurde...
$twit = file($cache['keys']);
//Und setzen gleich mal den richtigen Header
header('application/x-javascript');
//Sollte der Cache älter als 180 Sekunden sein, wird er erneuert...
if($twit[0] <= $cachetime){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, 'http://twitter.com/statuses/user_timeline.json?count=10');
	//Wir müssen uns am Server autorisieren
	curl_setopt($ch, CURLOPT_USERPWD, 'twittername:twitterpasswort');
	//Antwortet der Server nach 4 Sekunden nicht wird abgebrochen
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
	$buffer = curl_exec($ch);
	//Ist das Ergebnis über 1000 Byte lang und
	//beinhalteten den typischen Abschnitt "profile_image_url"
	//schreiben wir es in den Cache, wenn nicht lassen wir
	//die alten Daten im Cache.
	if(strlen($buffer) > 1000 && strpos($buffer,'profile_image_url')){
		$fp = fopen ($cache['keys'], "w");
		fwrite ($fp , time());
		fclose ($fp);
		$fp = fopen ($cache['twitter'], "w");
		fwrite ($fp , $buffer);
		fclose ($fp);
		} else {
			$buffer = file_get_contents($cache['twitter']);
		}
	} else {
		$buffer = file_get_contents($cache['twitter']);
	}
echo $buffer;

Nun brauchen wir nur noch die Cache-Dateien erstellen, diese für unser Script schreibbar machen und unser JavaScript auf die lokale Datei umlenken. Ihr habt zudem natürlich den Vorteil alle Daten, z.B. mit preg_replace frei zu modifizieren.


Kommentare zum Thema JSON, jQuery, cURL ,Twitter und der Cache:

1 | Patrick schrieb am 17.01.2008 um 18:09
Gravatar dieses Kommentators

Danke fuer den Tipp, werd ich bei Gelegenheit mal ausprobieren.

Greetings

2 | buki schrieb am 18.01.2008 um 13:59
Gravatar dieses Kommentators

klingt gut, merci

3 | buki schrieb am 19.01.2008 um 17:27
Gravatar dieses Kommentators

mh ich muss was falsches gemacht haben es klappt bei mir nicht

4 | stephan schrieb am 20.01.2008 um 19:07
Gravatar dieses Kommentators

hallo, finde ich sehr interessant, ich werde dein blog verlinken. ciao

5 | kartoffelbrei schrieb am 27.02.2008 um 19:05
Gravatar dieses Kommentators

mh ich muss was falsches gemacht haben es klappt bei mir nicht

Du darfst das ja auch nicht einfach so kopieren ;) Der Christian hat da auch ja (aus Versehen?) einen kleinen Fehler in den Code gebastelt

//Sollte der Cache älter als 180 Sekunden sein, wird er erneuert…
if($twit\[0\] <= $cachetime){

müsste richtig heißen:

//Sollte der Cache älter als 180 Sekunden sein, wird er erneuert…
if($twit\[0\] <= $cache[‘time’]){

müsste Zeile 18 sein. Die “\” in “$twit\[0\]” müssen natürlich raus, sollen die Textile-Formatierung umgehen. Die Idee finde ich aber ziemlich elegant, muss ich sagen!

6 | dennis schrieb am 18.03.2008 um 11:27
Gravatar dieses Kommentators

wie ist den die url zum blog der freundin?

7 | Christian schrieb am 18.03.2008 um 15:20
Gravatar dieses Kommentators

@dennis Da ist der Blog von Daniela

Kommentar-Feed für diesen Artikel




Dein Kommentar:


HTML-Tags werden entfernt.
Formatierung bitte mit Textile.
Gravatare werden unterstützt.

Werbeabwehr: (bitte lass dieses Feld auf jeden Fall leer)

Name: (erforderlich)

E-Mail: (wird NICHT angezeigt)

Homepage: (wird bei Spamverdacht manuell gelöscht)



Blogsuche

RSS-Feeds

Plaste & Plastik

plasteundplastik.de - Das Geocaching-Weblog

Die Kategorien


Netz-Fundstücke


Meta / Propaganda