Martin Lantzsch
Software Entwickler
7. Juli 2010

Twitter via PHP auslesen

7. Juli 2010 - Geschrieben von Martin - 2 Kommentare

Ein Leser dieses Blogs hat vor kurzem den Wunsch nach einem Artikel geäußert, wie er eine Ähnliche „letzte Tweets Anzeige“ wie auf www.Resigame.de bauen kann. Nun so schnell kann es gehen ;)

Da Twitter eine API bzw. von jedem Nutzer eine XML Datei mit Tweets und anderen Account Infos bereitstellt, haben wir leichtes Spiel an die Daten zu kommen.

So können wir die Datei auslesen:

$tweets = simplexml_load_file('http://www.twitter.com/status/user_timeline/[NUTZERNAME].xml');

[NUTZERNAME] muss natürlich mit dem Name des Twitteraccounts ersetzt werden, z.B. „Resigame“.

Aus dem Objekt $tweets können wir nun die letzte Nachricht auslesen:

echo $tweets->status->text;

Alle anderen verfügbaren Objekte kannst du herausfinden, indem du die XML Datei direkt im Browser aufrufst (Dort wird es sogar als Tree dargestellt).

Um auf ältere Nachrichten zuzugreifen kann hinter Status die Zahl angegeben werden, von der aus die Nachrichten „herab“ gezählt werden (allerdings wird bei 0 begonnen!):

echo $tweets->status{2}->text;

Dies würde uns Beispielsweise die 3. letzte Statusnachricht anzeigen.

Um nun die letzten 3 Nachrichten anzuzeigen verwenden wir einfach eine Schleife:

$i = 0;
while($i <= 2)
{
  echo $tweets->status{$i}->text.'<br>';
  $i++;
}

(mit for Schleifen hab ich es nicht so ;))

Da nun aber bei jedem Aufruf der Seite die Twitter XML Datei neu heruntergeladen werden muss, was nicht gerade Traffic und Ressourcenschonend ist – Kleinvieh macht schließlich auch Mist – Cachen wir nun die Datei:

if(filectime('twitter.xml') < time() - (60*10)) {
  // download file
  $file = file_get_contents('http://www.twitter.com/status/user_timeline/[NUTZERNAME].xml');
  file_put_contents('twitter.xml', $file);
}
$tweets = simplexml_load_file('twitter.xml');

Nun wird erst überprüft ob die Datei twitter.xml, welche im gleichen Ordner wie das Script liegt in den letzten 10 Minuten geändert wurde. Ist das der Fall wird das erneute Herunterladen übersprungen, wenn nicht (also wenn der Änderungszeitpunkt länger als 10 Minuten her ist), wird die XML von Twitter heruntergeladen und in unsere twitter.xml geschrieben.

Anschließend wird die twitter.xml geparst.

Das wäre es auch schon, in den nächsten Tagen zeige ich euch dann noch wie ihr die Twitter Nachrichten mittels jQuery schön als Newsticker laufen lassen könnt.

Browsergames – Welche Last verursachen diese?

23. Juni 2010 - Geschrieben von Martin - 4 Kommentare

Browsergames – jeder kennt eines, viele Spielen eines und so mancher hat selbst schon einmal eines Entwickelt. Doch welcher Aufwand ist es ein solches zu Entwickeln und wie Betreibe ich eines?

Welche Technik und Infrastruktur steckt hinter Browsergames?
Ein Browsergame ist im Grunde eine normale Webseite welche in PHP, Phyton, Perl oder sonst irgendeiner Programmiersprache Entwickelt sein könnte. Oft kommt dazu noch ein wenig JavaScript um es für den Nutzer ansprechender zu Gestalten.

Auf Serverseite sieht es auch meist gleich aus, es werkelt mindestens ein Linux Server mit der Verwenden Script Sprache und einer Datenbank, sowie einem Mailserver. Wird das Browsergame jedoch größer findet hier meist eine Trennung zwischen Web-, File-, Database- und Mail Server statt, da diese dann entsprechend optimiert und die Last somit besser verteilt werden kann.

Im Grunde ist das ganze bisher kein Hexenwerk, geht man aber ins Detail trifft einen der Schlag. Eine normale Webseite wird pro Besuch vielleicht 5 bis 10 mal aufgerufen, hierbei wird die Seite mit Menü und Konsorten aus einer Datenbank gelesen und falls das System schlau ist in einen Cache geschrieben. Bei einem Browsergame hingegen kann nichts gecached werden, da alles Dynamisch für den Spieler aufbereitet wird.

In Zahlen, eine Webseite hat pro Besuch 5 bis 10 Requests. Ein Browsergame kann auch mit diesen 5 bis 10 Requests auskommen, doch dazu kommen noch die AJAX Abfragen, welche nahezu sekündlich ausgeführt werden. Nehmen wir einmal an es wird alle 5 Sekunden eine AJAX Abfrage ausgeführt, dann sind wir schon bei ganzen 12 Weiteren Abfragen pro Minute (Man beachte im Normalfall sind es noch einige mehr!) das würde bei einer Durchschnitts Onlinezeit von 15 Minuten ganze 180 Requests ausmachen!

Wie optimiere ich meinen Server?
Gehen wir mal davon aus, das das Spiel perfekt auf die vielen Requests ausgelegt ist. Was kann man dann auf der Server Seite machen?

Einen kleinen schnellen Webserver verwenden, ich empfehle an dieser Stelle Lighttpd, welcher aus meiner Sicht sich für ein solche Unterfangen wesentlich besser eignet als Apache(2). In der Konfigurationsdatei können unter anderem auch diverse Module wie „webdav“, „rewrite“ und falls es nicht benötigt wird das Modul „accesslog“ deaktiviert werden. Je nach Bedürfnis können natürlich Module ein- bzw. abgeschaltet werden, allerdings sollte die Liste der aktiven immer so kurz wie möglich gehalten werden.

Seitens der Scriptsprache. Da hier keine explizit festgelegt wurde, an dieser Stelle nur einige allgemeine Hinweise. In den jeweiligen Konfigurationsdateien gibt es oft eine Reihe an Parametern, mit denen man Funktionen abschalten kann, welche nicht unbedingt benötigt werden, beispielsweise, das im Header gesendet wird, das diese Seite mit PHP Version 5.3.x erstellt wurde. Tipps gibt es in einschlägigen Webseiten, Foren und Blogs.

So wenig Dienste als möglich! Das sagt eigentlich schon alles, im Hintergrund sollte keine Sinnlosen Dienste wir FTP laufen, wenn diese gar nicht benötigt werden. Sollte es der Fall sein, das man einen dieser Dienste benötigt, einfach schnell via SSH einloggen und nach nicht einmal 10 Sekunden läuft der Dienst.

Gute Hardware ist die halbe Miete. Nicht nur Zuhause beim Entwickeln, auch Online erspart gute Hardware viele Schlaflose Nächte, in denen der Server überlastet ist oder sich aufgehängt hat. Ich empfehle so viel RAM wie möglich und einen Schnellen CPU.

Fazit
Browsergames sind wahre Ressourcenfresser, doch mit der richtigen Hardware, den Perfekten Einstellungen und natürlich Sauber und Performant geschriebenen Quellcode steht dem Spaß nichts mehr im Wege.

3. Juni 2010

Performante Alternative zu PHP Template Engines

3. Juni 2010 - Geschrieben von Martin - 4 Kommentare

Template Engines wie Smarty werden bei vielerlei Projekten eingesetzt, oft auch ohne über die Folgen einer solchen Klasse nachzudenken.

Neben der Teils umständlichen Syntax, welche für Designer oft schwer zu erlernen ist, da sie aus vielerlei komplizierten Konstrukten besteht, sticht der Performanceverlust hervor. Bei jedem Aufruf der Seite, müssen nämlich alle Templates neu geparst werden. In diesem Schritt werden alle zuvor genannten komplizierten Syntaxkonstrukte in PHP Code übersetzt, hier stellt sich die Frage, warum nicht direkt PHP Code verfassen?

Wer jetzt mit dem Argument kommt, PHP Code sei lang und kompliziert, der hat sich getäuscht, denn PHP bietet eine Kurzform aller wichtigen Funktionen und Schleifen, hier ein kurzer Auszug der wichtigsten:

Die Ausgabe einer Variable (ähnlich zu echo), allerdings nur wenn „short tags“ in der php.ini aktiviert sind:

<?=$var?>

Ein einfaches if():

<?php if($var = 'test'): ?>
  Wenn $var test entspricht, dann gib diesen Text aus.
<?php else: ?>
  Ansonsten gib das hier aus.
<?php endif; ?>

Eine foreach() Schleife:

<?php foreach($var as $item): ?>
  Punkt Nummero: <?=$item?>
<?php endforeach; ?>

Wo ist denn nun an dieser Syntax im Vergleich zu Templates Engines wie Smarty ein Problem, Funktionen wie abwechselnde Hervorhebung von Tabellen oder Div’s, kann man ganz leicht selbst schreiben. So könnte die entsprechende Methode in einer Template Klasse aussehen:

class template {
  private static $color;
  public static function highlight($color1, $color2) {
    if(self::$color == $color1) {
      echo $color1; self::$color = $color2;
    } else {
      echo $color2; self::$color = $color1;
    }
  }
}

Und noch Zweifel? Ich glaube weniger! Dies ist eine Ressourcensparende Alternative zu den Allgegenwärtigen Template Engines, vorallem bei einem Einsatz in Hochperformanten und Hochbelasteten Webseiten. Andernfalls, wenn Performance keine Rolle Spielt, kann man getrost auf Smarty und Co. zurückgreifen.

30. Mai 2010

SimpleLD auf Github

30. Mai 2010 - Geschrieben von Martin - Keine Kommentare

Kurze Fortschrittsmeldung, den SimpleLD Source Code habe ich vor ein paar Tagen ins Git Repository auf Github.com gepusht.

Open Source Software

Derzeit sind die Core Komponenten noch in Entwicklung, aber das Framework, ist bereits funktionsfähig, die Paket Schnitstelle funktioniert einwandfrei und diverse Hooks im Code, erlauben neuen Paketen das Framework zu erweitern. In den nächsten Tagen folgen einige Artikel, welche sich mit der Paketentwicklung für das SimpleLD Framework beschäftigen. Ein paar kleine Beispielspakete wie das „home“ Paket sind bereits Online.

>> SimpleLD auf Github

15. Mai 2010

jQuery – Mehrere Elemente verbergen

15. Mai 2010 - Geschrieben von Martin - 3 Kommentare

Jeder der mehrere Elemente auf ein mal mittels jQuery verstecken will, die gleich benannt wurden, wird früher oder später feststellen müssen, das der Selektor immer das erste gefundene Element verwendet.

<div id='test'>Test</div>
<div id='test'>Test 2</div>
<div id='test'>Test 3</div>

Um dies zu umgehen habe ich mir folgende 2 Funktionen geschrieben, welche alle Elemente die auf den 1. Parameter zutreffen nacheinander abarbeiten. Hierzu hole ich mir alle zutreffende Elemente via „$(name).get()“, anschließend kann ich diesen Array mittels „$.each()“ durchlaufen (das jQuery Pendant zu foreach() unter PHP). Da ich nun den Index des Elementes habe kann ich nun das entsprechende Element verbergen.

function hideAll(name, speed) {
  elm = $(name).get();
  $.each(elm, function(index, value) {
    $(name, [index]).hide(speed);
  });
}

Und hier noch eine zum Wieder ein faden (sanftes einblenden) der Elemente:

function fadeInAll(name, speed) {
  elm = $(name).get();
  $.each(elm, function(index, value) {
    $(name, [index]).fadeIn(speed);
  });
}

Als 2. Parameter wird immer der Speed übergeben in der die Animation ablaufen soll, diese sind die jQuery typischen wie „slow“ und „fast“.

Noch mal zu unserem obigen Beispiel, sollen nun alle 3 div’s ausgeblendet werden so benötigen wir lediglich folgenden Code:

hideAll('#test', 'slow');

und zum wieder einblenden selbstverständlich:

fadeInAll('#test', 'slow');
15. Mai 2010

Multi Accounts aufdecken

15. Mai 2010 - Geschrieben von Martin - 2 Kommentare

Heute geht für einen Leser ein Wunsch in Erfüllung. Viel Spaß beim lesen. Falls du dir auch einen Beitrag wünschen willst, schreib mir eine eMail.

Betreiber von Onlinespielen sowie Chats sind immer auf der suche nach sogenannten Doppel- oder Multi-Accounts, das sind Benutzer, die sich öfter auf einer Plattform wie einem Browsergame anmelden um dadurch Vorteile zu erhalten.

Das man sich dabei nicht nur auf sein Gespür verlassen sollte sollte natürlich auch klar sein, darum was kann man machen, damit solche User von vornherein keine Chance haben? Mit ist das sofort eine IP Sperre in den Sinn gekommen, gesagt getan, ich habe meine bestehenden IP Felder – welche die IP Adresse des letzten Logins beinhält – beim Login des Spielers nach seiner IP Adresse abgesucht und wenn sich ein User binnen weniger Stunden öfter als ein mal eingeloggt hat, hab ich ihm den Login untersagt.

Folgendermaßen sieht mein Script aus:

// IP Adresse vom User holen
$ip = $_SERVER['REMOTE_ADDR'];
// die Zeit ab der nach gleichen IPs gesucht wird
$time = time() - 24*60*60;
// nun kann die IP Adresse im users Table gespeichert werden
mysql_query("UPDATE users SET ip = '".$ip."' WHERE userid = '".$userid."'");
// nun können wir prüfen ob andere Benutzer mit dieser IP vorhanden sind
$count = mysql_num_rows("SELECT userid FROM users WHERE ip = '".$ip."' AND last_login > '".$time."'");
if($count > 1)
{
   die('TO MUCH USERS PER IP!');
}

(Geschrieben in PHP)
Dies wäre nun die Brutale Lösung (Kann allerdings durch zusätzliche Filter wie z.B. Punkte entschärft werden), welche alle Multi Account Spieler Aussperrt. Das kann allerdings auch negative Nebeneffekte haben, und zwar können so Familien, Wohngemeinschaften und Büros diese Seite nicht mehr nutzen, da dort alle über einen Internet Anschluss ins Internet gehen und somit eine IP Adresse haben.

Deswegen empfehle ich solange sich der dadurch entstandene Schaden der durch solche Doppelaccounts entsteht in Grenzen hält erst ein mal ein Script zu schreiben, welches alle Doppelaccountspieler auflistet, um diese explizit zu befragen oder ihre Accounts zu überprüfen.

Folgendermaßen hab ich das einmal für ein Mafia Browsergame gemacht:

$query = mysql_query("SELECT ip, userid, username FROM users");
while($users = mysql_fetch_array($query))
{
  // nun gehen wir alle user nach und nach durch
  // falls auch hier ein Zeitlimit benötigt wird, kann das von oben übernommen werden
  $count = mysql_num_rows("SELECT userid FROM users WHERE ip = '".$users['ip']."'");
  if($count > 1)
  {
    // nun da es ja offensichtlich ein Multiaccount Spieler ist, wird er ausgegeben
    // wenn gewünscht könnte man auch in diesem Schritt Informationen zu den
    // gespielten Accounts holen, allerdings würde das dieses Beispiel sprengen
    echo $users['username'] - $users['ip'];
  }
}

(Geschrieben in PHP)

Nun haben wir 2 Möglichkeiten in Betracht gezogen wie man mit Doppelaccounts fertig wird. Ich hoffe sie finden Anklang, und Helfen den Admins bei ihrer Täglichen Arbeit.

5. Mai 2010

JavaScript und str_replace()

5. Mai 2010 - Geschrieben von Martin - Keine Kommentare

Unter JavaScript gibt es leider keine so tolle str_replace() Funktion wie unter PHP. Hier das JavaScript Pendant dazu:

// hier unser Text
string = 'Test and Test';
// nun ersetzen wir es
new = string.split('and').join('und');
// und geben das ersetzte aus
document.write(new);

Wer gar nicht mehr von der PHP Funktion str_replace los kommt, kann sich auch seine eigene Funktion schreiben:

function str_replace(search, replace, string) {
  return string.split(search).join(replace);
}
23. April 2010

PHP – Mail Domains ausschließen

23. April 2010 - Geschrieben von Martin - 10 Kommentare

Gestern war es wiedermal so weit, einige User hatten sich bei Resigame mit feigen Müll Mail Adressen angemeldet. Aber damit ist jetzt Schluss, ich hab die Registrierung gegen diese Mail Adressen abgesichert. Mit folgendem RegEx bin ich vorgegangen:

  // hier die Mail Adresse, welche idR via Formular übergeben wird
  $mail = 'haha@mülldomain.tld';
  // hier können beliebig viele Mail Domains eingetragen werden
  $trash = array('müllmaildomain.tld', 'nochsoeine.tld');
  // nun durchlaufen wir alle Domains
  foreach($trash as $var)
  {
    // wenn die Adresse in die Vorlage passt
    // stirbt das Script und es wird ein Fehler ausgegeben
    if(preg_match('/([a-zA-Z0-9._-])*@'.$var.'/', $mail))
    {
      die('BLOCKED MAIL DOMAIN!');
    }
  }

Das wäre es dann auch schon. Der Array könnte auch aus einer Datenbank befüllt werden, aber das sollte jeder selbst hinbekommen.