DroidCamp Stuttgart 2010

logodroidcampfinal250px

06:59 Uhr, Bahnhof Mainz.

Die Reise nach Stuttgart beginnt ereignislos, wird aber mit steigender Bahnverspätung und fallenden Temperaturen interessanter.
Gemeinsam mit Carsten kämpfe ich mich gefühlte Stunden durch den Regen. Endlich an der Hochschule der Medien angekommen bemerken wir, dass wir auch einfach zwei Stationen früher hätten aussteigen können. Egal, nichts wie rein, regnet ja schließlich immer noch … die Tür ist abgeschlossen. Also laufen wir um das komplette Gebäude herum und finden endlich eine offene Tür. Erste Erkenntnis … die Hochschule der Medien ist Groß. Zweite Erkenntnis … einige Zeit später … das DroidCamp ist in einem kleinen Nebengebäude und die Wegweiser hängen natürlich nur am richtigen Weg.
Leicht nass und viel zu spät erreichen wir dann doch noch die heiligen Hallen und werden von @russenreaktor freundlich begrüßt.

Continue reading

Mit Besten Empfehlungen

Vor kurzem wurde ich von den lieben Kollegen auf einen interessanten Link aufmerksam gemacht. Hinter einer verkürzten URL verbarg sich ein Fachartikel einer großen Zeitung und darüber schwebte ein Layer mit einem Empfehlungstext des verlinkenden. Nach kurzem Erstaunen und ein wenig Investigation war der Trick schnell erkannt. Auf der Seite befand sich ein IFrame mit dem eigentlichen Artikel und darüber lag ein absolut positioniertes Div mit dem Empfehlungstext.

Der Effekt ist ebenso einfach wie beeindruckend und auch wenn die untersuchte Lösung einige Tricks und Kniffe wie eine extrem kurze Url oder eine verschlüsselte Zielseite aufweist, möchte ich euch Heute zeigen, wie man ein solches System mit wenig Aufwand selbst programmieren kann.

Continue reading

Das Einfach Mal Drauf Los Projekt

Kennt Ihr das auch? Ihr habt eine tolle Idee und möchtet am liebsten direkt los programmieren. Alle Schlüsselinformationen sind vorhanden und es könnte eigentlich los gehen. Aber dann fehlt es einfach an den einfachsten Voraussetzungen.

  • Welche Sprache soll man benutzen?
  • Welches Framework soll man benutzen?
  • Wie soll das ganze aussehen?
  • Wie soll man den Code verwalten?
  • Wie kann man ein Demo-System einrichten?

So oder so ähnlich läuft das eigentlich immer, wenn mir eine wirklich gute Idee kommt. Und das schlimmste dabei ist, bis ich die Vorbedingungen geschaffen habe, hab ich meistens keine Lust mehr auf das eigentliche Projekt :-(

Habt Ihr ähnliche Erfahrungen gemacht, oder sogar Lösungen parat? Was ist ein gutes Vorgehen um schnell mal was auf die Straße zu bekommen?

Ich bin auf eure Ideen und Meinungen sehr gespannt!

Foto von BotheredByBees

Installation und Konfiguration einer Android Entwicklungsumgebung

This entry is part 1 of 1 in the series Android Workshop

Heute möchte ich euch die Installation einer Android Entwicklungsumgebung auf Basis des Android SDK und der Eclipse IDE näher bringen. Wenn man bedenkt, dass man für das Konkurrenzsmartphone sogar Hardware anschaffen muss, macht es Google uns erstaunlich einfach.

Als erstes muss natürlich mal der Android SDK heruntergeladen werden. Das geht am besten auf der Android SDK Download Seite ;-) Auf dieser Seite findet ihr die Installationsschritte übrigens auch noch mal in aller Kürze.

Nach dem Download wird das Archiv in ein beliebiges Verzeichnis entpackt und die Datei SDK Setup.exe gestartet.

Android SDK Paketauswahl

Mit ein wenig Glück, wird euch direkt die Installation der Pakete vorgeschlagen. Wenn ihr eine dicke Leitung, oder etwas Zeit habt, würde ich vorschlagen “Accept All” und anschließend “Install Accepted” zu klicken. Damit werden alle verfügbaren Pakete heruntergeladen und installiert.

Solltet ihr eine Fehlermeldung zur Verbindung bekommen, müsst ihr zunächst den Schalter “Force https://… sources to be fetched using http://…” in den Einstellungen aktivieren.

Android SDK Einstellungen

Nachdem alle Pakete installiert sind, ist der SDK selbst auch schon einsatzbereit.

Jetzt können wir unter “Virtual Devices” ein neues Device zum testen erstellen. Klickt dazu einfach auf die “New” Schaltfläche.

Wählt jetzt einen Namen und die gewünschte API-Version und konfiguriert das Device ganz nach eurem Geschmack.

Erstellen eines Android Images

Nach dem Erzeugen, könnt ihr den Emulator mit eurem erstellten Image auch schon starten und ein wenig klicken. Natürlich macht der Emulator erst mit einer selbst erstellten Applikation wirklich Sinn.

Android Emulator

Es ist übrigens nach meinen Erfahrungen nicht möglich, den Emulator sauber herunter zu fahren, daher könnt Ihr auch einfach beherzt auf den Schließen Button klicken ;-)

Zu guter letzt installieren wir noch das Eclipse Plugin. Öffnet dazu die Eclipse-IDE und wählt aus dem Menü “Help –> Install New Software”. Tragt jetzt die URL https://dl-ssl.google.com/android/eclipse/ und die ComboBox ein, klickt auf Add und wählt einen Namen. Jetzt selektiert alle angebotenen Plugins und akzeptiert und bestätigt so lange, bis alles Installiert ist.

Eclipse Installationsdialog Eclipse ADT Installation

Nach der Installation solltet Ihr Eclipse neu starten. Direkt nach dem Neustart werdet ihr auch schon per Fehlermeldung darauf hingewiesen, dass ihr den Ort eurer Android Installation angeben müsst. Öffnet dazu die Einstellungen, wählt den Android Knoten aus und selektiert euren SDK Installationsordner. Bestätigt dann mit Apply oder OK.

Eclipse Fehlermeldung Eclipse Einstellungen

Damit sind wir auch schon am Ende der Installation angelangt. Im nächsten Teil schreiben wir dann unsere erste Android Applikation.

Have Fun & Take Care!

“Junior”-Level für den Coding Standard?

Wir haben bei uns zur Zeit eine Diskussion zur Umstellung der Coding Standards. Ich hatte vor einer Weile angeregt, ob wir sie nicht an bewährten Regeln von größeren Frameworks anlehnen sollten. Mir gefallen dabei die Coding Standards von Zend recht gut, obwohl es auch für mich eine Umstellung wäre.

Die Vorteile liegen dabei wohl auf der Hand:

  • Es gibt schon Sniffs für den PHP_Codesniffer um die Regeln zu überprüfen.
  • Neue Kollegen kennen diese Regeln aus den Frameworks und nutzen sie idealerweise bereits für ihre Entwicklungen.
  • Codeschnipsel von externen Quellen können eher direkt verwendet werden, ohne sie an die eigenen Codeing Guides anzupassen.

Die Überlegung zur Umstellung der Coding Guides hat natürlich auch Widerstand hervorgerufen. Das größte Bedenken ist dabei, dass es nicht einfach wird, den gesamten vorhandenen Quellcode von mehreren Jahren Entwicklung umzustellen. Ein Bedenken, was nicht so einfach von der Hand zu weisen ist.

Wir haben natürlich auch Überschneidungen zwischen unserem aktuellen Coding Standard und den möglicherweise zukünftigen Coding Standards. Diese Schnittmenge sollte somit bereits in den aktuellen Sourcen abgedeckt sein.

Daher ist mir folgende Idee gekommen. Wie wäre es, wenn man unterschiedliche Level einführt. Also zunächst ein “Junior”-Level für die Schnittmengen in den Styleguides und dann mehrere Stufen bis zum “Chief”-Level. Das “Chief”-Level würde denn den perfekten Codingstyle darstellen. Man könnte dann für jedes Projekt bestimmen, welches Level dieses Projekt erfüllen soll. Natürlich immer das Ziel im Hinterkopf in absehbarerer Zeit das “Chief”-Level zu erreichen.

Aus verschiedenen Aspekten stelle ich es mir ganz spannend vor:

  1. Kein Seniorentwickler will auf die Dauer auf “Junior”-Level programmieren. Zumindest mir würde es gegen den Strich gehen. Zumal es ja auch alle anderen in der Firma sehen würden. ;-)
  2. Man hätte Qualitätslevel als Vergleich zwischen den Projekten und Teams, welche man auch relativ leicht bewerten kann. So ist das super-mega-innovative Projekt dann doch nicht mehr so cool, wenn es nur einen “Junior”-Level erreicht, oder?
  3. Auch hat man durch die Nutzung von Level nicht sofort hunderte/tausende Hinweise. Denn mal ehrlich, bei zu vielen Hinweisen hat man auch keine Lust, da man das Ende und den Fortschritt kaum sehen kann. ;-)

Was haltet ihr von meiner Idee? Könnte das so funktionieren?

PHP Tool Integration (PTI) für Eclipse

This entry is part 8 of 4 in the series Zend Framework Grundlagen

Nachdem Sascha jetzt mit seiner Serie schon recht weit bei der Einrichtung unter Eclipse fortgeschritten ist, will ich ihn da mal unterstützen und ein weiteres Plugin vorstellen, ohne das man unter PHP eigentlich gar nicht entwickeln sollte. Ich selber habe es gerade in den letzten Wochen regelrecht lieben gelernt. :-)


Eclipse PHP Tool Integration oder kurz PTI ist das Plugin, was ich euch hier ans Herz legen will. Mit PTI werden vorhandenen PHP Tools in Eclipse integriert. Zur Zeit sind Integrationen von PHP_Codesniffer, PHPUnit und PHPCPD verfügbar. Drei Tools also, die so schon alleine wirklich praktisch sind. Was ich daran genial finde ist, dass man die Fehler/Warnings durch PTI direkt im Editor sieht und so auch direkt bearbeiten und beheben kann. Ich denke durch diesen direkten Feedback schafft man es recht schnell die Qualität des erstellten Sourcecode zu erhöhen.

Continue reading

Installation der Aptana und Subversion Plugins für Eclipse

This entry is part 7 of 4 in the series Zend Framework Grundlagen

Hallo erstmal! Willkommen zum dritten Teil der Zend Framework Grundlagenworkshops bei dem wir uns mit der Erweiterung der Eclipse Entwicklungsumgebung durch ein Subversion Versionierungsplugin und verbesserte HTML und CSS-Editoren von Aptana beschäftigen wollen.

Continue reading

PhpCilux – continuous integration monitoring

Es ist soweit, ich bin stolz, die erste Version von “PhpCilux” präsentieren zu dürfen. :-)

Eigentlich wollte ich es ja “Daisy” nennen, da ich bei gleichnamigen Sturm über Deutschland mit der Entwicklung begonnen hatte. Allerdings gibt es schon viel zu viele Projekte mit dem Namen “Daisy”.
PhpCilux soll als Name vielmehr symbolisieren, dass es php-Anwendung mittels CI beleuchten kann. Der Name war eine wirklich schwere Geburt, aber jetzt wieder weiter im Text.

Ich beschäftige mich schon seit einer Weile mit Continuous Integration. Dabei habe ich natürlich auch phpUnderControl installiert und eingesetzt. Ich denke, dass ist der Platzhirsch, wenn man sich mit dem Thema im Rahmen einer PHP Entwicklungsumgebung beschäftigt. Es ist auch durchaus zu recht in aller Munde, da es groß und mächtig ist. Für mich aber irgendwie zu mächtig, zu groß und zu komplex. Neben phpUnderControl gibt es noch diverse andere Tools. Im PHP-Umfeld ist dabei sicherlich noch Xinc interessant. Allerdings sieht es so aus, als ob das aktuell nicht mehr weiterentwickelt wird.

Dann bin ich eher aus Zufall auf Sismo gestoßen. Ich finde diesen Ansatz cool, einfach und intuitiv zu bedienen! Es gibt genau nur die Informationen wieder, die man hier benötigt:

  • Projekt erfolgreich: ja/nein
  • Build erfolgreich: ja/nein
  • Navigieren durch die Projekte und Builds

Sismo ist leider noch nicht veröffentlicht. Ich wollte aber unbedingt so ein Tool haben, somit habe ich mich entschlossen so was ähnliches zu entwickeln. Das Ergebnis ist nun da: PhpCilux.

Und was kann es?

Es kann eigentlich gar nicht so viel und das ist auch so gewollt!
Eigentlich kann es nur die Logfiles von PHPUnit und PHP_CodeSniffer anzeigen und mit Informationen aus dem SVN-Log anreichern. Ich brauche hier keine generierten Quellcode-Dokumentationen, Code Coverage oder irgendwelche Softwaremetriken. Nicht, dass dies unwichtig wäre, aber das dient eher zu Verbesserung bzw. Dokumentation des Projektes. Was ich im Rahmen einer einfachen Continuous Integration haben will, ist eigentlich ganz einfach und läßt sich in folgender Aussage auf den Punkt bringen: Könnte man das Projekt jetzt deployen? Dafür reichen meiner Meinung nach zunächst Unit-Tests und eine Auswahl an CodeSniffs. Durch die Beschränkung auf diese zwei Tools erreicht man, dass der Buildprozess recht schnell bleibt und somit auch häufig statt finden kann.

Damit PhpCilux die Builds eines Projektes anzeigen kann, bedarf es eigentlich auch nicht viel. Pro generiertem Projekt gibt es einen Ordner. In diesem Ordner gibt es dann einen Unterordner “reports”, welcher wiederum die eigentlich Build-Ordner enthält. In den einzelnen Ordern können dann die Logfiles von PHPUnit, PHP_CodeSniffer oder SVN liegen: phpcs.txt, phpunit.txt und svnlog.xml.
Als Projektname wird der Name des Ordners verwendet. Gleiches gilt auch für die Namen der einzelnen Builds.

Wie diese Daten dort hin gelangen, ist PhpCilux vollkommen egal. Für meine Entwicklungen habe ich mich für ein phing-Buildscript entschieden. Sie könnten aber auch via Cronjob, manuelles Kopieren oder irgend einen anderen Weg dort landen. Also jedem das seine und für mich kein Aufwand einer Entwicklung. ;-)

So kommen wir jetzt zum Schluß. Es ist früh und ich muss morgen ja wieder arbeiten. Aber eins noch: Ich freue mich auf konstruktives Feedback und mal sehen, vielleicht gibt es auch bald den großen Bruder für PhpCilux… ;-)

Was geht eigentlich so an SQL-Abfragen?

Jetzt schreibe ich schon wieder über Wege zu Optimierungen. Man könnte denken, meine Anwendungen wären langsam. ;-)

Aber mal im Ernst, in größeren gewachsenen Projekten weiß man nicht mehr unbedingt, was ein Seitenaufruf für SQL-Abfragen auslöst. Drei Sachen finde ich dabei interessant:

  1. Die Anzahl von gleichen/ähnlichen Abfragen. –> Vielleicht kann man was zusammenfassen.
  2. Die Abfragezeit der längsten Abfragen. –> Vielleicht kann man was verändern oder noch verbessern.
  3. Anzahl der Abfragen im allgemeinen und die Gesamtausführungszeit. –> Vielleicht kann man was vermeiden.

Im Zend_Framework kann man für die Datenbank das Profiling aktivieren, was ganz gut funktioniert und auch die Voraussetzung für meinen kleinen Codeschnipsel ist. Also zunächst in der Bootstrap das Profiling  aktivieren und dann mache ich eigentlich was ganz einfaches: Ich gehe die einzelnen Einträge aus dem Profiling durch und sortiere/gruppiere die Einträge. Im Anschluß wird das ganze noch in eine Datei weggeloggt. Fertig. Recht einfach, oder? Aber es funktioniert gut um kleinere Schwachstellen zu finden. Wichtig ist noch, dass dies am Ende eingebunden wird, so dass auch alle Abfragen enthalten sind.

So jetzt noch der Code-Schipsel:

	// log sql debug
	$dbs = array(
		'db1' => Zend_Registry::get('db1'),
		'db2' => Zend_Registry::get('db2'),
	);

	// order by max unique statements => max
	// order by query length => length
	$orderBy = 'max';

	foreach ($dbs as $dbKey => $db) {
		$data = array();
		$profiler = $db->getProfiler();

		if (!$profiler->getEnabled()) {
			break;
		}

		$file = TOP_DIR.'/logs/db'.$dbKey.md5($_SERVER['REQUEST_URI']).'.log';

		$totalTime    = $profiler->getTotalElapsedSecs();
		$queryCount   = $profiler->getTotalNumQueries();
		$longestTime  = 0;
		$longestQuery = null;

		$queryData = array();
		foreach ($profiler->getQueryProfiles() as $query) {
		    if ($query->getElapsedSecs() > $longestTime) {
		        $longestTime  = $query->getElapsedSecs();
		        $longestQuery = $query->getQuery();
		    }
		    $queryDataKey = serialize($query->getQuery());
		    if (isset($queryData[$queryDataKey]['count'])) {
		    	$queryData[$queryDataKey]['count']++;
		    	$queryData[$queryDataKey]['ElapsedSecs'] += $query->getElapsedSecs();
				$queryData[$queryDataKey]['getQueryParams'] .= "\n".serialize($query->getQueryParams());
		    } else {
		    	$queryData[$queryDataKey]['count'] = 1;
		    	$queryData[$queryDataKey]['ElapsedSecs'] = $query->getElapsedSecs();
		    	$queryData[$queryDataKey]['getQueryParams'] = serialize($query->getQueryParams());
		    }
		    $queryData[$queryDataKey]['query'] = $query->getQuery();

		}

		$queryData2 = array();
		foreach ($queryData as $_query) {
			if ($orderBy == 'max') {
				// order by max unique statements
				$key = str_pad($_query['count'], 5, 0, STR_PAD_LEFT ).'_'.md5($_query['query']);
			} else {
				// order by query length
				$key = str_pad($_query['ElapsedSecs'], 15, 0, STR_PAD_LEFT ).'_'.md5($_query['query']);
			}
			$queryData2[$key] = implode("\n", $_query);
		}

		krsort($queryData2);

		$data[] = 'Request: '.$_SERVER['REQUEST_URI'];
		$data[] = 'Executed ' . $queryCount . ' queries in ' . $totalTime . ' seconds';
		$data[] = 'Diffrent queries ' . count($queryData2);
		$data[] = 'Average query length: ' . $totalTime / $queryCount .' seconds';
		$data[] = 'Queries per second: ' . $queryCount / $totalTime ;
		$data[] = 'Longest query length: ' . $longestTime;
		$data[] = "Longest query: " . $longestQuery;

		$data[] = '';
		$data[] = '';
		$data[] = '';
		$data[] = implode("\n\n", $queryData2);

		file_put_contents($file, implode("\n", $data));
	}