Posts Tagged ‘ coding

Wie lerne ich schnell eine neue Programmiersprache?

Mein neues Aufgabengebiet als Ausbilder umfasst natürlich auch das kreative Entwickeln von Aufgaben, mit denen die Azubis neues Wissen leichter aufnehmen können. Im Prinzip geht es darum, dass man nicht stupide ein Buch oder Tutorial durcharbeitet, sondern bereits ein bestehendes Problem hat und an dessen Lösung arbeitet. So wird einem nicht alles vorgegeben und man muss nach individuellen Lösungen für die einzelnen Teilprobleme suchen. Diese Herangehensweise habe ich mir irgendwann angeeignet und konnte damit bisher schneller Sachen lernen, vornehmlich bei Programmiersprachen.

Mein Lieblingsprojekt für dieses Thema ist ein Wordlist-Generator. Wem der Begriff fremd ist: Wordlisten werden verwendet, um mittels geeigneter Tools Passwörter zu knacken. Darum geht es mir hier aber gar nicht, sondern nur um die Erstellung einer solchen Liste. Warum? Nun, wenn man ein solches Tool entwickeln möchte, so muss man fast alle grundlegenden Möglichkeiten einer Programmiersprache nutzen:

- Aufbau und Syntax (z.B. )
- Parameterübergabe
- Bedingungen (z.B. if…)
- Schleifen (z.B. for, while, …)
- Funktionen (auch rekursiv)
- Arbeit mit Strings und Arrays
- Dateizugriffe
- Sortieralgorythmen (optional)
- Klassen (optional)
- Datenbank (optional)
- Optimierung vom Code im Allgemeinen und vor allem der Schleifen

Um ehrlich zu sein habe ich bereits 2 verschiedene Varianten entwickelt: die einfache und die etwas kompliziertere. Variante 1 erzeugt einfach eine Liste mit allen möglichen Zeichenkombinationen und einer durch den Benutzer definierten Länge. Dazu entwickelt man eine Funktion, die alle möglichen Zeichen wiedergibt, und das nacheinander. Diese Funktion kann sich nun entweder rekursiv x-mal (je nach gewünschter Passwortlänge) aufrufen oder man packt diese Logik in Schleifen. Im Endeffekt erhält man dann eine solche Liste (Länge 3 Zeichen):

aaa
aab
aac

aba
abb
abc

ZZX
ZZY
ZZZ

Je mehr Zeichen man ermöglicht, desto mehr Kombinationen gibt es. Dadurch steigt der Speicherbedarf und natürlich auch die Ausführungszeit. Diese Methode nennt man Bruteforce, da stupide jede mögliche Kombination von Zeichen durchprobiert wird.

Variante 2 baut eine echte Wordlist nur aus Wörtern auf. Das ist wesentlich schneller als Variante 1, jedoch muss man davon ausgehen, dass die zu knackenden Passwörter eben normal vorkommende Wörter sind – was leider sehr oft der Fall ist. Im Prinzip nimmt man sich ein paar Ebooks oder andere Texte und packt diese in txt-Dateien – je mehr desto besser – und wirft sie in einen Unterordner. Das Tool geht diese Dateien nun einzeln durch, wandelt jedes Leerzeichen und Satzzeichen in Zeilenumbrüche um und wirft doppelt vorkommende Einträge wieder heraus. Lässt man das Tool laufen, so baut sich langsam aber sicher eine sehr umfangreiche Wordlist zusammen.

Ihr seht schon, dass bei einer so simpel klingenden Aufgabe doch ein bisschen Arbeit zu erwarten ist. Das tolle an beiden Projekten ist, dass man einen sehr guten Einstieg in neue Programmiersprachen findet, indem man versucht, beide umzusetzen. Die Vorgehensweise ist eigentlich immer die gleiche:

- Syntax anschauen
- Dateizugriffe lernen
- Schleifen, Bedingungen und Stringmanipulation studieren
- um Funktionen erweitern
- testen
- fertig

Probiert es mal aus – mir haben diese Aufgaben bisher immer gut geholfen, sodass ich neben PHP bereits Basic, Python, C, C++, C#, Java und Shellscripting erlernen konnte.

[Quicktip] Eclipse sehr langsam unter Mac OSX

Heut ist ein guter Tag, um meiner Quicktip Reihe ein neues Kind zu bescheren. Dieses mal geht es um das Problem, dass Eclipse bei mir sehr lange braucht, um zwischen den einzelnen Tabs zu wechseln – teilweise 5 bis 10 Sekunden. Und wie ihr euch vorstellen könnt, kann das ziemlich nervig sein. Unter Windows rennt Eclipse eigentlich ganz gut und mein Macbook sollte eigentlich schon genug Leistung für eine einfache IDE aufbringen können.

Ein bisschen Google brachte mir dann folgenden Tip, der bei mir auch funktioniert hat:
Ändert in der eclipse.ini (die befindet sich direkt innerhalb der “eclipse.app”) die Zeile

-Dosgi.requiredJavaVersion=1.5

in

-Dosgi.requiredJavaVersion=1.6

ab, und schon sollte die Tab-Wechsel-Verzögerung weg sein. Bei mir gab es die ursprüngliche Zeile gar nicht, also hab ich die 1.6′er Zeile einfach unten angehangen. Eclipse neu gestartet und schon funktioniert’s.

Event driven Development und das Observer Pattern

Programmierung besteht nicht nur aus dem Aneinanderreihen von Codezeilen – in der Hoffnung dass es funktioniert. Dazu gehört sehr viel Überlegung und Theorie. Aus diesen Überlegungen entstanden (bzw. entstehen immernoch) sog. Design-Patterns. Das sind Mustervorlagen, wie man eine Klasse oder ein ganzes System aufbauen kann, um bestimmte Optimierungen oder effizienteren Code erreichen kann – losgelöst von einer bestimmten Programmiersprache. Die Patterns sind fast immer allgemeingültig.

Bereits vor einiger Zeit hatte ich das Registry Pattern vorgestellt, welches ich aktiv nutze. Während der letzten Projekte setze ich auf ein neues System, welches eher als Mischform zu bezeichnen ist: Im Kern verwende ich Techniken der event-driven-Entwicklung, das Observer- sowie das Singleton-Pattern. Damit ist es mir möglich, große Teile der Programmlogik auszulagern und – das ist der eigentliche Vorteil – das System wird sehr leicht erweiterbar, da sich neue Funktionen einfach einklinken können. Aber wie funktioniert das nun genau?

Nehmen wir uns als Beispiel ein einfaches Blogsystem: Man kann Artikel schreiben (natürlich nur nach einer Passwortabfrage) sowie die Artikel lesen. Ich möchte nun, dass all diese Vorgänge geloggt werden, mein Twitter-Account automatisch auf neue Artikel hinweist, ich über fehlerhafte Logins per Mail informiert werde und ein Visit-Counter über die Artikel läuft (ich also sehen kann, welche Artikel wie oft gelesen wurden). Das stellt natürlich keine große Schwierigkeit dar und kann so direkt in den bestehenden Code implementiert werden. Es geht aber auch anders.

Zuallererst benötigen wir unseren Observer. Dieser bietet Methoden, mit denen man sich für Events registrieren kann (per Listener) und über die man aber auch Events auslösen kann (Fire Event). Da der Observer als Singleton aufgebaut ist, kann man alle Kommandos jeweils mit einer Zeile Code erledigen. Man spart sich die Instanzierung und das Observerobjekt wird nur ein einziges Mal erstellt – was für seine Funktion essenziell ist.

Im ersten Schritt werden also die Listener registriert, was möglichst am Anfang eures Programmes passieren sollte, damit die Listener alle Events hören können. Mein Observer nimmt dazu folgende Daten für einen Listener entgegen: Event, Klasse und Methode. Das Event ist ein einfacher String, wie z.B. “NewArticleCreated”, “Fail_UserLogin” oder “PageVisit” – kann aber auch ein “*” sein. In diesem Falle lauscht der Listener auf jedes Event, was z.B. für das Logging oder Debugging interessant sein könnte. Die “Klasse” ist eine von mir frei wählbare Klasse, die auch die angegebene “Methode” enthält. Der Observer speichert diese Angaben nun in einem Array und behält sie während der gesamten Laufzeit

Im zweiten Schritt benötigen wir nun noch die Events. Der Observer kennt die Methode “fireEvent”, welche zusätzlich die Parameter Eventname sowie Eventdata enthält. Beispiele für die Eventnamen gab’s weiter oben schon, interessant ist hier eher der Parameter eventData. In diesem kann ich nämlich weitere Infos zum Event mitgeben – sei es als String oder als Array. Das Datenformat sollte natürlich vorher definiert werden.

Und was passiert nun, wenn ich ein Event abfeuere? Der Observer nimmt das Event entgegen und vergleicht es mit seinem Listener-Array. Trifft er eine Übereinstimmung, instanziert er die gegebene Klasse und ruft anschließend die Methode auf. Der Methode wird das Event sowie die eventData übergeben. Klingt alles etwas wirr, deswegen versuchen wir uns wieder an unserem Blog-Beispiel.

Im Initbereich meines Blogsystems registriere ich erstmal folgende Events:

Observer.addListener("*", "Logger", "logEvent");
Observer.addListener("Fail_UserLogin", "Informer", "noticeAdmin");
Observer.addListener("PageVisit", "Visitor", "countVisit");
Observer.addListener("NewArticleCreated", "TwitterTools", "sendNewArticleTweet");

Ab sofort sollten wir an allen relevanten Stellen im Code Events feuern. Ganz wichtig an dieser Stelle: Auch Events feuern, auf die ihr noch gar nicht regieren wollt. Das macht es euch, aber auch anderen Programmierern später leicht, neue Programmlogik hinzuzufügen.

Observer.fireEvent("NewArticleCreated", articleID);
Observer.fireEvent("ArticleUpdated", articleID);
Observer.fireEvent("ArticleDeleted", articleID);
Observer.fireEvent("PageVisit", pageID);
Observer.fireEvent("Fail_UserLogin", userID);

Die Events werden natürlich nicht direkt hintereinander abgefeuert sondern an den entsprechenden Codestellen hinterlegt. Der Observer geht bei jedem fireEvent seine Liste durch und aktiviert die Listener:

NewArticleCreated --> Logger.logEvent(eventName, eventData),
TwitterTools.sendNewArticleTweet(eventName, eventData)
ArticleUpdated --> Logger.logEvent(eventName, eventData)
ArticleDeleted --> Logger.logEvent(eventName, eventData)
PageVisit --> Logger.logEvent(eventName, eventData),
Visitor.countVisit(eventName, eventData)
Fail_UserLogin --> Logger.logEvent(eventName, eventData),
Informer.noticeAdmin(eventName, eventData)

Der Vorteil an dem System ist, dass ich beliebig viele Listener auf bestimmte Events lauschen lassen kann, aber auch beliebig viele Events abfeuern kann. Das System ist also extrem dynamisch.

Möchte ich später z.B. Abonnenten darüber infomieren, dass es einen neuen Artikel gibt oder dass ich einen Artikel geändert habe, erweitere ich die Klasse Informer um die nötigen Methoden (oder bau mir eine neue Klasse) und registriere diese als Listener:

Observer.addListener(“NewArticleCreated”, “Informer”, “noticeUser”);
Observer.addListener(“ArticleUpdated”, “Informer”, “noticeUser”);

Da mir das Event gleich mit übertragen wird, kann ich innerhalb der Methode unterscheiden, welchen Mailtext der User erhalten soll – “Neuer Artikel in meinem Blog” oder “Ich habe einen Artikel bearbeitet”.

Ich hoffe, dass das Prinzip nun etwas verständlicher war…

[PHP] Das Registry Pattern

Kommen wir heute mal zu einem sehr spannenden Thema: Wie kann ich auf bestimmte Daten und Objekte global zugreifen, obwohl ich objektorientiert programmieren möchte. Denn durch die Kapselung ist das ja eigentlich nicht möglich.

Um die Problematik relativ unkompliziert lösen zu können, behilft man sich einer kleinen Hilfe: der Registry. Einfach gesagt ist die Registry-Klasse ein Array, welches man befüllen und auslesen kann. Da es ein statisches Objekt ist, kann man von überall darauf zugreifen ohne erst Instanzen abrufen oder gar auf globale Variablen setzen zu müssen. Das Prinzip dahinter ist relativ leicht. Man deklariert eine Klasse mit statischen Methoden zum Schreiben und Lesen der Registry und natürlich eine statische Variable, die die übergebenen Objekte beinhaltet.

Der komplette Code, den ihr für das Registry Pattern benötigt, sieht so aus:

class registry
{
      private static $instances = array();

      public static function getInstance($name)
      {
            return self::$instances[$name];
      }

      public static function setInstance($name, $instance)
      {
            self::$instances[$name] = $instance;
      }

      public static function removeInstance($name)
      {
            self::$instances[$name] = null;
      }
}

An erster Stelle wird natürlich erstmal die Klasse “registry” deklariert. Anschließend wird als Eigenschaft der Klasse die Variable $instances definiert, und das natürlich statisch. Das hat den Effekt, dass die Daten nicht in einer Instanz der Klasse Registry, sondern in der Klasse selbst gespeichert werden.

Als nächstes kommen die Funktionen getInstance, setInstance und removeInstance. Die Funktionen sollten eigentlich selbsterklärend sein, daher zeige ich hier mal direkt ein Beispiel, wie man mit der Klasse arbeitet:

$dbObject = new db("User", "Password", "Host", "Database");
registry::setInstance("dbObject", $dbObject);

Damit wird das Objekt $dbObject unter der Referenz “dbObject” in der Registry hinterlegt

Anders als normale Objekte werden die statische Methoden nicht mit einem ->, sondern mit :: aufgerufen. Vor den beiden Doppelpunkten steht der Name der Klasse (weil wir ja keine Instanz brauchen!), danach kommt die statische Methode.

In der Registry Klasse wird per self::$instances auf die hinterlegten Objekte zugegriffen. Auch hier wird der Doppelpunkt verwendet, da es sich um eine statische Eigenschaft handelt.

Schön und gut, nun hab ich mein Objekt da rein gepackt. Und nun? Eine Kopie des Objekts befindet sich nun in der Registry und kann an jeder beliebigen Stelle im Code abgerufen werden. Und das geht so:

class testclass
{
	public function getWerte()
	{
		$dbOject = registry::getInstance("dbObject");

		echo $dbObject->doQuery("SELECT ...");
	}

}

Um das Ganze noch etwas eleganter zu betreiben, kann man das Beispiel folgendermaßen anpassen:

class testclass
{
	private $dbObject;

	public function __construct()
	{
		$this->dbOject = registry::getInstance("dbObject");
	}

	public function getWerte()
	{
		echo $this->dbObject->doQuery("SELECT * FROM tWerte...");
	}

	public function getNamen()
	{
		echo $this->dbObject->doQuery("SELECT * FROM tNamen...");
	}

}

Der Umweg über den Constructor und die Eigenschaft $this->dbObject ermöglicht es, das Datenbank-Objekt einmal aus der Registry zu laden, dann aber beliebig in den einzelnen Methoden verwenden zu können. Das spart ein paar Zeilen Code ;)

PHP – Das Zend Framework

Beim Wort “Framework” war mir bisher etwas unwohl, stand es für mich neben den Annehmlichkeiten auch für Einengung. Kann sein, dass ich da die falsche Sichtweise auf die Problematik habe. Aber nach meinem Exkurs in die Ruby on Rails Welt und Tests mit diversen anderen PHP Frameworks war das Thema für mich ein rotes Tuch. Die automatisierte Code-Generierung sah für mich eher wie eine Einschränkung an Stelle einer Erleichterung aus.

Bei der Entwicklung von NetzCMS hatte ich anfangs auch mit dem Gedanken gespielt, auf ein Framework zu setzen. Jedoch erschienen mir die getesteten Systeme zu unflexibel und es sah nicht gerade so aus, dass ich damit so programmieren konnte, wie ich es mir vorstellte.

Leider hatte sich diese Ansicht bei mir fest eingenistet und trübte die Sicht auf die restlichen Frameworks. Naja, das führte dann letztlich dazu, dass ich ein quasi-Framework für das CMS selbst schrieb. Man kann davon nun halten was man will, fakt ist aber: ich habe dadurch extrem viel gelernt. Sei es nun die Optimierung von Code, aber auch das Verständnis von Software-Architekturen. So gesehen war diese Entwicklung also für mich persönlich ein großer Vorteil.

Natürlich hatte der Spaß auch eine Kehrseite: Zeit. Wenn ich auf ein fertiges Framework gesetzt hätte, hätte ich einen Großteil der Entwicklungszeit einsparen können. Ich hätte es wahrscheinlich auch so gemacht, wenn ich mir zu dieser Zeit das Zend Framework angesehen hätte. Es ist mir noch immer nicht ganz klar, warum ich mich nie näher damit beschäftigt hatte…

Doch was macht das Zend Framework nun so anders? Es ist kein klassisches Framework, sondern eher eine sehr gute Sammlung von Klassen, die man einzeln, aber auch im Zusammenspiel verwenden kann. Das macht es zum perfekten Partner in bestehenden Projekten, aber auch bei Neuentwicklungen. Man behällt nämlich alle Freiheiten und spart sich trotzdem ordentlich Zeit. Benötigt man z.B. nur einen schnellen und einfachen Zugriff auf eine Datenbank, bindet man die zend_db Klasse ein und arbeitet mit deren Methoden. Man muss keine weiteren Klassen einbinden bzw. verwenden.

Ein Blick in die Zend Dokumentation der Datenbankklasse ließ mich frohlocken, basiert sie doch auf den gleichen Absichten, unter denen ich meine eigene Datenbank-Klasse entwickelt hatte. Die Methoden sind den meinen sehr ähnlich, nur dass es noch ein paar mehr gibt. Das hat für mich persönlich den Vorteil, dass der Umstieg kaum Umgewöhnung bedeutet. Aber auch, dass ich mit meiner Entwicklung gar nicht so falsch lag.

Neben der gut ausgebauten Datenbank-Klasse bietet Zend u.a. Module für die Benutzerauthentifizierung, Logging und auch eine komplette Implementierung des MVC Patterns (Model-View-Controler, sprich, der Code ist vom Design komplett getrennt). Das alles sind Punkte, die ich für zukünftige Projekte wahrscheinlich selbst entwickeln bzw. weiterentwickeln würde. Mit der Verwendung von Zend kann ich mir das sparen.

Die Ordnerstruktur des Frameworks ist zwar in leichten Zügen vorgegeben, stellt aber eher eine Best Practice Methode dar. Sie baut von vornherein auf MVC auf. Man kann die Struktur aber auch komplett nach den eigenen Wünschen bzw. an das eigene Projekt anpassen.

All das sind Punkte, die das Zend Framework für mich interessant machen. Vorerst. Sobald ich damit die ersten Projekte umgesetzt habe, kann ich es wahrscheinlich besser beurteilen.

Hinter dem Zend Framework stecken Andi Gutmans und Zeev Suraski , die selbst auch für die Entwicklung von PHP 5 verantwortlich sind. Man kann sich denken, dass die Leute, die die Sprache entwickeln, wahrscheinlich auch mit den optimalsten Code für diese Sprache liefern. Auch ein Punkt, der für Zend spricht. Ob sich das nun bewahrheitet, wird sich zeigen.

PHP – Sichere Datenübertragung mit GET

Auch in Zeiten von Webservices, soap und Co. ist der einfache GET-Request noch immer ein guter Freund des PHP Programmierers. Im Gegensatz zu den anderen Methoden ist er extrem einfach und sehr schnell erstellbar.

Das ist gleichermaßen Fluch und Segen. Denn die Einfachheit bezahlt man mit fehlender Kontrolle. So ist es schwer, die Daten sicher zu übertragen und auch den Empfang sicher zu stellen. Doch es ist nicht unmöglich. Und darauf möchte ich in diesem Artikel eingehen.

Das Hauptproblem an GET ist, dass es komplett in Klartext übertragen wird. Nun kann man die Parameter verschlüsseln, was aber zu einem erhöhten Aufwand beim Entschlüsseln führt, vor allem, wenn man mehrere Parameter übertragen möchte. Da Parameter, die nicht der Authentifizierung dienen, nicht unbedingt verschlüsselt übertragen werden müssen, kann man sich diesen Overhead sparen. Letztendlich möchte man ja nur sicherstellen, dass die Daten korrekt und vollständig an den Empfänger weiter gegeben werden. Das kann man am besten mit einer Checksumme bewerkstelligen.

Nehmen wir einmal an, dass folgende Parameter übertragen werden sollen:
name=Mustermann
vorname=Max
kundennummer=12345
email=max.mustermann@email.com

Die Url würde also folgendermaßen aussehen:
[www.test.de]/[index.php]?name=Mustermann&vorname=Max &kundennummer=12345&email=max.mustermann@emailcom

Der Aufruf dieses Links führt dazu, dass die Parameter an die index.php übergeben werden. Doch wie kann diese nun erkennen, ob nicht noch Werte fehlen oder unvollständig sind? Gar nicht. Deswegen behilft man sich mit einer zusätzlichen Checksumme, die man z.B. mittels md5 erstellt:

$checksumme = md5($name.$vorname.$kundennummer.$email);

Die Funktion md5 liefert einen 32-Stelligen Code, der nur durch genau diese Parameter zustande kommt. Ändert sich auch nur ein Zeichen in einem der Parameter, sieht die Checksumme schon wieder komplett anders aus. Daher nennt man md5 auch eine Einwegfunktion, weil aus dieser Prüfsumme die ursprünglichen Werte nicht mehr zurück errechnet werden können.

Die Url wird also um den Parameter “checksum” erweitert:

[www.test.de]/[index.php]?name=Mustermann&vorname=Max&kundennummer=12345 &email=max.mustermann@emailcom&checksum=738ACD43857AB32758BB3175837592492

Das Script auf der Empfängerseite kann nun die gleiche md5 Funktion mit genau der gleichen Reihenfolge der Parameter ausführen und das Ergebnis mit der übergebenen Checksumme vergleichen. Wird das gleiche Ergebnis erziehlt, kann man davon ausgehen, dass alle Daten korrekt übertragen wurden.

Schön, jetzt weiß unser Empfänger, dass wir korrekte und vollständige Daten gesendet haben, aber nicht, ob wir berechtigt waren, ihm diese zuzusenden. Also erweitert man die Checksummen-Funktion um ein zusätzliches Passwort, welches nur dem Empfänger zugänglich gemacht wird. Die Sicherheit kann man noch die Reihenfolge der Parameter ändern:

$checksumme = md5($kundennummer.$name.$email.$vorname.$passwort);

Ohne das Passwort ist der Absender nicht in der Lage, eine korrekte Checksumme zu bilden. Somit kann man Daten im Klartext per GET übertragen und trotzdem für deren Authentizität sorgen.