Es gibt ja eine ganze Fülle an PHP Frameworks und jedes wartet mit seinen ganz eigenen Vor- und Nachteilen auf. Für rsslounge habe ich das Zend Framework gewählt und bereue diese Entscheidung nicht, denn es bietet eine Vielzahl an sehr nützlichen Funktionen und sorgt für eine saubere und aufgeräumte Struktur. Ein gravierender Nachteil ist allerdings die Größe und die hohe Anzahl an Dateien, die das Framework mit sich bringt. Für ein Webprogramm, das anderen zur Verfügung gestellt werden soll und die dies dann auf einen eigenen Server hochladen sollen, ist das ziemlich lästig. Hinzu kommt doch eine gewisse Komplexität, wie man beispielsweise am Cachingverhalten sieht.

Für mein neuestes Projekt wollte ich etwas einfaches, das eine saubere Struktur ermöglicht, aber nicht mit tausenden Dateien und riesigem Funktionsumfang daher kommt. Da ich schon vor einiger Zeit auf das PHP Fat-Free Framework gestoßen bin, und es einen sehr guten ersten Eindruck hinterlassen hat, habe ich mich entschlossen mir das Framework etwas genauer anzusehen. Sehr schnell war klar, dass es perfekt geeignet ist.

Features

Das PHP Fat-Free Framework verfügt über alle wichtigen Features, die mittlerweile so Standard sind:

  • Routing Mechanismus (sehr einfach auch im MVC Style realisierbar)
  • Datenbankzugriff (sogar mit einem mini ORM und einem MongoDB mapper)
  • Template Engine
  • Schnick Schnack wie: On-the-fly JavaScript/CSS compressor, CAPTCHA generator, OpenID, usw.

Die Template Engine konnte mich nicht ganz überzeugen, hier habe ich selbst Hand angelegt, eine kleine Hilfsklasse geschrieben und auf den in PHP integrierten Syntax zurückgegriffen. Ansonsten konnte das Framework in voller Linie überzeugen. Selbst eine Migration um eine Major Version funktionierte mit sehr geringem Aufwand, was mich doch sehr überrascht hat.

Anforderungen

Das Framework selbst ist sehr klein und wird mit einer einzigen 55KB großen PHP Datei beworben. Ganz richtig ist das aber nicht: Der Datenbankzugriff und weitere Funktionen wurden in Plugins ausgelagert. Nimmt man den gesamten Funktionsumfang, so hat man 27 Dateien mit einer gesamten Größe von 223 KB, was natürlich immernoch sehr schlank ist.

Ein bestimmter Server ist nicht erforderlich und das Manual bietet Anleitungen für das Umschreiben der URLs für den Apache Webserver, lighttpd und nginx. Einziger Wermutstropfen: Es benötigt mindestens PHP 5.3, was für einen simplen RSS Reader, der möglichst überall laufen soll eine doch recht hohe Anforderung ist. Gleichzeitig liefert diese Anforderung auch zahlreiche Vorteile, wie beispielsweise schlankeren Code durch Lambda-Funktionen oder der Einsatz von Namespaces.

F3 in der Praxis

Warum mir das Framework so zusagt, sieht man schnell, wenn man ein paar Zeilen Code sieht. Ein Beispiel ist das Routing:

require __DIR__.'/libs/f3/base.php';
F3::set('AUTOLOAD','libs/f3/|libs/|libs/WideImage/|models/|libs/twitteroauth|libs/FeedWriter');
F3::route('GET /', 'controllers\Index->home');
F3::route('GET /mark/@item', 'controllers\Items->mark');
F3::route('POST /source', 'controllers\Sources->add');
F3::route('PUT /source/@id', 'controllers\Sources->write');

Mit der ersten Zeile wird das Framework eingebunden. Mit der zweiten wird ein Autoloader registriert und die entsprechenden Inlcude-Pfade gesetzt (das Pipe Symbol | dient hier als Trennzeichen. Dann werden die Routen definiert. Das Fat-Free Framework unterstützt hierbei auch den REST Ansatz und einzelne URLs können mehrfach, je nach Art des HTTP Requests belegt werden. In diesem Beispiel wird bei einem GET Aufruf der URL / die Klasse \controllers\Index instaziiert und dort die Methode home aufgerufen.

Ähnlich einfach ist der Datenbankzugriff:

F3::set('DB',
	new DB(
		'mysql:host=localhost;port=3306;dbname=mysqldb',
		'admin',
		'p455w0rD'
	)
);
DB::sql('SELECT brandName FROM wherever');
foreach (F3::get('DB->result') as $row) {
	// whatever you want to do with $row
}

Um SQL Injection vorzubeugen, werden natürlich auch parametrisierte Queries unterstützt.

Ähnlich simpel ist das gesamte Framework gestrickt und meist bietet es verschiedene Wege etwas umzusetzen. Besonders elegant finde ich das Routing mit Lambda Funktionen:

F3::route('GET /about',
	function() {
		echo 'No subliminal messages here...';
	}
);

Lizenz und Downloads

Das Framework steht unter der GPLv3 Lizenz zur Verfügung, es wird aber auch eine kostenpflichtige, kommerzielle Lizenz angeboten. Das finde ich das einzige Manko, hier bietet beispielsweise das Zend Framework unter der MIT Lizenz sehr viel mehr Möglichkeiten.

Zur Projektseite des PHP Fat-Free Frameworks: http://fatfree.sourceforge.net/


		

Nach langer Zeit ist es nun mal wieder so weit: eine neue Version von rsslounge ist verfügbar. Es gibt einige Änderungen und Optimierungen. Neue Features und größere Umbauten sind immer eine Frage der Zeit. Ich habe ja einiges auf der Wunschliste und auch im Forum haben einige Wünsche geäußert. Besonders interessant ist eine Funktion, so dass aus den gesammelten Feedbeiträgen wieder ein RSS Feed erzeugt wird. Das kann dann an beliebiger Stelle (z.B. in einer Android RSS App) eingebunden werden.

An dieser Stelle vielen Dank an alle, die mich mit Sprachdateien versorgt haben und mir Feedback geben. Sofern ich die Zeit finde, versuche ich sinnvolle Neuerungen einzubauen. Die Performance zu optimieren (besonders das erstmalige Laden von rsslounge zu beschleunigen) war im aktuellen Update mein primäres Anliegen. Die Änderungsliste ist im Changelog zu finden.

Download: rsslounge 1.7

In letzter Zeit habe ich wieder etwas mehr Muse zu bloggen und werde auch die nächsten Wochen hier etwas aktiver sein. Besonders rsslounge, das ich die letzten Monate arg vernachlässigt habe, kommt auf die Agenda. Ein neuen Release mit einigen kleinen Verbesserungen wird es also bald geben. Darüber hinaus möchte ich wieder etwas mehr über interessante Dinge aus dem Bereich Softwareentwicklung und Fotografie schreiben.

In diesem Sinne bis zum nächsten Post. Ich hoffe es gibt noch einige interessierte Leser!

Häufig kommt es vor, dass Sprachdateien nicht vollständig sind. Ich habe den Effekt bei rsslounge, da ich hier von verschiedenen Personen Sprachdateien bekomme. Da ich nicht sicherstellen kann, ob auch wirklich jeder Key der Sprachdatei übersetzt wurde (außer ich prüfe manuell die gesamte Datei), bietet es sich an, einfach als Fallback-Lösung die entsprechende englische Übersetzung zu verwenden.

Zend_Translate bietet hier eine einfache Möglichkeit “Routen” zu erstellen. Das heißt man kann festlegen, welche Sprache alternativ verwendet werden soll. Dabei können sogar Ketten gebildet werden (z.B. wenn Französisch nicht gefunden wurde, dann in der deutschen Übersetzung suchen und wenn dort auch nichts gefunden wird, in der englischen). Wobei sich mir der Sinn von so einer Verkettung nicht ganz erschließt.

Das setzen einer Route ist sehr einfach. Folgendes Beispiel scanned ein übergebenes Verzeichnis nach CSV Dateien und übernimmt deren Inhalt als Übersetzung. Mit dem Key “route” wird definiert, wie die Sprachen verkettet werden sollen. In diesem Beispiel ist Englisch die Fallbacksprache für Deutsch und Französisch.

$language = new Zend_Translate(
            'csv',    // Typ der Quelle: hier csv Dateien
            'locale', // Quell-Verzeichnis
            'en',     // Standard Sprache
            array(    // Optionen
                'scan' => Zend_Translate::LOCALE_DIRECTORY,
                'route'     => array( 'de' => 'en', 'fr' => 'en' )
            ));

Der sauberste Weg ist es natürlich alle Schlüssel auf zu übersetzen. Beim Aufspüren von fehlenden Übersetzungen hilft Zend_Translate ebenfalls.

Ein Projekt, das schon länger auf der ToDo Liste steht, habe ich nun heute etwas genauer in Augenschein genommen:

Bei HeadJS handelt es sich um ein kleines JavaScript Skript, welches in der Lage ist, weitere JavaScript Dateien nachzuladen:

head.js(
 "/path/to/jquery.js",
 "/google/analytics.js",
 "/js/site.js",
 function() {
     // all done
 }
);

Der Vorteil ist die Tatsache, dass die weiteren Skriptdateien kontrolliert parallelisiert heruntergeladen werden. Wird dieser Aufruf am Ende der Website durchgeführt (also vor dem schließenden body Tag), so kann die HTML Seite, sowie die Stylesheets ungehindert geladen und gerendert werden, bevor mit der Verarbeitung von JavaScript Dateien begonnen wird. Das Ergebnis: die Seite wird schneller angezeigt. Mit 2,3 kB ist das Skript auch schön kompakt und klein.

Weitere Features sind eine bessere HTML5 Kompatibilität, automatisch gesetzte CSS Klassen (z.B. für bestimmte Browser) und noch einige weitere Schmankerl. Es lohnt sich also das kleine Skript genauer anzusehen. Im Einsatz habe ich es bei rsslounge (ab Version 1.7, die ich in wenigen Tagen online stellen will).

Zur headJS Webseite: http://headjs.com/

Ich hatte ja bereits in einem früheren Beitrag erwähnt, dass ich mich daran versucht habe den RSS Reader rsslounge lernfähig zu machen. Dazu sollte der Benutzer neue Beiträge als interessant oder uninteressant klassifizieren können. Ausgehend von der Bewertung dieser bestehenden Einträgen durch den Benutzer, sollten dann neue Feed-Beiträge automatisch weiter nach oben (Interessantes) oder nach unten (Uninteressantes) einsortiert werden.

Hierfür habe ich verschiedene Verfahren der Test-Klassifikation aus dem Information Retrieval in Betracht gezogen und hinsichtlich ihrer Eignung bezüglich des Problems untersucht. Anschließend habe ich als Referenz die Lernfähigkeit mittels dem naiven Bayes-Klassifikators implementiert. Als zweite Lösung habe ich das k-nächste-Nachbarn Verfahren, basierend auf dem simulierten Abkühlen implementiert und untersucht, ob eine der beiden Lösungen für dieses Problem in Frage kommt. Das Ergebnis ist ist leider sehr ernüchternd.

Trotzdem möchte ich hierzu das Paper, das ich dazu verfasst habe, veröffentlichen. Zum einen gibt es einen guten Überblick und eine gute Einführung in die gängigen Verfahren der Text-Klassifikation, zum anderen halte ich das optimierte k-nächste-Nachbarn Verfahren für sehr leistungsfähig. Für passende Problemstellungen ist das ein praxistauglicher Lösungsweg.

Nachdem ich die gesamte Entwicklung von rsslounge offen gelegt habe, halte ich es für sinnvoll auch diesen Versuch (und das damit verbundene Paper) zu veröffentlichen. Vielleicht inspiriere ich jemanden, oder liefere für weitere Arbeiten eine Grundlage bzw. Informationen.

Das Paper als PDF zum Download (1.5MB): Automatisiertes Priorisieren von RSS Feed Beiträgen mittels maschinellem Lernen

Nachdem sich Supportanfragen mittlerweile häufen und immer wieder die gleichen Fragen aufkommen, habe ich nun ein Forum eingerichtet. Dort können Fragen gestellt und Probleme diskutiert werden. Vielleicht reagiert ja jemand schneller, zudem ist so ein Forum immer ein ganz gutes Informationsarchiv.

http://rsslounge.aditu.de/forum