RSS Feed
Mär 9

Assoziatives Array als HTML Tabelle ausgeben

Veröffentlich am Dienstag, 9. Mär 2010 in Webentwicklung

Sehr häufig wird gefordert ein assoziatives Array als HTML Tabelle auszugeben. Ich nutze hier sehr oft die implode() Funktion, um dabei mit möglichst wenig Quellcode zu dem Gewünschten Ergebnis zu kommen. Da ich meine Lösung wirklich sehr schön und genial einfach finde, wollte ich euch kurz die Funktion präsentieren. Als auszugebendes Array nehmen wir das MySQL-Debugging Array aus meinem vorherigen Artikel MySQL unter PHP debuggen mit einer eigenen MySQL Klasse.

function array_to_table($a){
	$t='<table>';
	$t.='<tr><th>'.implode('</th><th>', array_keys($a[0])).'</th></tr>';
	foreach($a as $row){
		$t.= '<tr><td>'.implode('</td><td>', $row).'</td></tr>';
	}
	return $t.='</table>';
}

// Ausgabe der Tabelle
echo array_to_table($mysqli->queries);

In Zeile 3 werden die Schlüssel des assoziativen Array für die Überschriften der Spalten genutzt. Wir öffnen hier eine Zeile und eine Spalte und fügen dann mit Hilfe der implode() Funktion alle Schlüssel in diese Zeile ein. Die “Glue” für die implode() Funktion ist hierbei ein schließendes Tag für die Spalte und ein weiteres öffnendes. Am Ende der Zeile schließen wir noch die letzte Spalte und die Zeile. Die gleiche elegante Anwendung der implode() Funktion verwenden wir auch bei den einzelnen Spalten mit den Werten. Hier in einer foreach Schleife.

Mit dieser Funktion kann jedes assoziative Array sehr elegant ausgegeben werden. Dabei lässt sich die Funktion trefflich erweitern. So könnte z.B. in einem Parameter ein Array mit Schlüsselnamen übergeben werden, wenn die Schlüssel des Assoziativen Arrays nicht passend für die Tabelle sind. Oder es könnte jeder Zeile eine alternierende “gerade” und “ungerade” Klasse mitgegeben werden. Oder aber man vergibt Klassen um eine der vielen JavaScript Sortierungen auf die Tabelle anwenden zu können.

Wir ihr also sehen könnt ihr eure Fantasie bei der Erweiterbarkeit freien Lauf lassen. Ich vergebe meistens die Klassen für Sortierung einer Tabelle mit der Tablekit Sortierung.

Ich hoffe, dass euch die Funktion bei eurer täglichen Arbeit helfen kann. Ich liebe die implode() Funktion, da man mit ihr sehr elegant PHP Arrays in Strings umwandeln kann. Ich verwende sie auch häufig beim Erstellen von SQL Statements in Verbindung mit dem IN() Operator.

Mär 4

MySQL unter PHP debuggen mit einer eigenen MySQL Klasse

Veröffentlich am Donnerstag, 4. Mär 2010 in Webentwicklung

Bei einem meiner Projekte kam es zu ungewöhnlich langen Ladezeiten eines Formulars. Da hier allerdings auch sehr viele Datenbankabfragen ausgeführt werden müssen und dabei auch noch die Werte per COUNT() gezählt werden wunderten mich die Zeiten nicht wirklich.

Nun wollte ich natürlich wissen, welche Abfrage dabei besonders viel Zeit in Anspruch nimmt um dann gezielt optimieren zu können. Ich setze in dem Projekt auf die MySQLi Klasse von PHP. Da ich hierbei die Klasse objektorientiert nutze, war es sehr einfach möglich diese zu erweiterten. Eine Möglichkeit wäre es natürlich gewesen eine eigene Funktion zu schreiben, aber in diesem Fall hätte ich auch alle Skript anpassen müssen, in denen ich eine Query ausführe. Daher habe ich mich dazu entschlossen einfach die query() Funktion von MySQLi zu überschreiben. Hier ein stark vereinfachtes Beispiel, wie so etwas aussehen könnte:

<?php

class mysqliDebugger extends mysqli {

	public $queries = array();
	public $queries_time = 0;

	function __construct($host, $user, $pass, $name, $port, $sock){
		parent::__construct($host, $user, $pass, $name, $port, $sock);
	}

	function __destruct(){
		parent::__destruct();
	}

	function query($query){
		$start = microtime(true);

		if(!$result = parent::query($query)){
				$error_message = $this->error;
		}

		$end = microtime(true);

		$this->queries[] = array(
			'number' => count($this->queries),
			'query' => $query,
			'error' => $error_message,
			'time' => $end - $start
		);

		$this->queries_time += $end - $start;

		return $result;
	}
}

$mysqli = new mysqliDebugger('host', 'user', 'pass', 'name');
if($result = $mysqli->query('SELECT * FROM tablename')){
	while($row = $result->fetch_assoc()){
		// Verarbeiten der Ergebniszeilen
	}
}

if($result = $mysqli->query('SELECT * FROM tablename2')){
	while($row = $result->fetch_assoc()){
		// Verarbeiten der Ergebniszeilen
	}
}

?>

Sehen wir uns die wichtigsten Zeilen des Quellcodes an. Die Zeilen 8-10 zeigen den Konstruktor unserer neuen Klasse, die den Konstruktor der geerbten Klasse MySQLi aufruft. In den Zeilen 16-36 überschreiben wir die query() Funktion der MySQLi Klasse mit unserer Debugging-Klasse. Dort wird zuerst einmal zur Protokollierung der Ausführungszeit der Startzeitpunkt mit Hilfe der microtime() Funktion ermittelt. Anschließend wird der Query mit dem Aufruf parent::query($query) an die query() Funktion der MySQLi Klasse übergeben. Einen eventuell auftretenden Fehler speichern wir dabei in einer Variablen ab.

In Zeile 23 speichern wir die Endzeit des Query. Anschließend speichern wir alle Werte, die wir zur späteren Auswertung benötigen in einem Array gespeichert. Zusätzlich summieren wir noch alle Zeiten auf, um später die Gesamtdauer aller Statements bestimmen zu können. Die ab Zeile 38 wird eine einfache Instanziierung und Nutzung der Klasse aufgezeigt, wie man sie auch von MySQLi kennt. Wer also in seinen Skripten schon MySQLi verwendet kann einfach beim Instanziieren der Klasse die neue Debugging-Klasse verwenden und muss keine weiteren Zeilen im Quellcode ändern. Ich empfehle eine kleine Bedingung zu verwenden, die feststellt, ob der Debugging-Modus aktiv ist und nur dann die Debugging-Klasse zu verwenden, wenn sie auch benötigt wird. Das spart im produktiven Einsatz etwas Rechenzeit. Eine mögliche Bedingung könnte wie folgt aussehen:

if($debug){
	$mysqli = new mysqliDebugger('host', 'user', 'pass', 'name');
} else {
	$mysqli = new mysqli('host', 'user', 'pass', 'name');
}

Anstelle der $debug Variablen könntet ihr auch einen GET Parameter oder einen Session Parameter verwenden. Ich rate aber dringend davon ab einen einfach zu erratenden GET Parameter zu verwenden, da in solchen Fällen eure SQL-Statements für Unbefugte sichtbar werden könnten, was unter Umständen die Sicherheit eueres Systems gefährden könnte.

Nachdem wir die Daten gesammelt haben möchten wir sie natürlich auch ausgeben. Das solltet ihr auch wieder die vorherige Bedingung verwenden. Dazu erstellen wir einfach eine Tabelle, die die gesammelten Daten enthält:

<table style="border: 1px solid #000;" rules="all">
	<caption>Gesamtdauer: <?= $mysqli->queries_time ?></caption>
	<tr>
		<th>Anzahl</th>
		<th>Query</th>
		<th>Fehler</th>
		<th>Zeit</th>
	</tr>
<? foreach($mysqli->queries as $query) : ?>
	<tr>
		<td><?= $query['number'] ?></td>
		<td><?= $query['query'] ?></td>
		<td><?= $query['error'] ?></td>
		<td><?= $query['time'] ?></td>
	</tr>
<? endforeach ?>
</table>

Nehmen wir an, wir die Tabelle aus dem ersten Statement ist in der Datenbank nicht vorhanden. In diesem Fall würden wir einen SQL-Fehler erhalten. In der Tabelle können wir dann direkt den Fehler ermitteln und entsprechend das Statement korrigieren. Auch hier wird das Statement gespeichert und die Zeit gemessen.

Gesamtdauer: 0.0025820732116699
Anzahl Query Fehler Zeit
0 SELECT * FROM tablename Table ‘name.tablename’ doesn’t exist 0.00076198577880859
1 SELECT * FROM tablename2 0.0018200874328613

Ihr habt mit dieser kleinen Beispiel-Klasse einen sehr einfachen Debugger zur Hand, mit dem ihr sehr schnell die langsamen Statements in eurem System finden könnt. Ihr könnt die Klasse natürlich auch noch nach euren Wünschen erweitern und auch andere Funktionen von MySQLi überschreiben. Wenn ihr, so wie ich, zentral an einer Stelle die Datenbankverbindung erzeugt könnt ihr durch die Bedingung aus dem zweiten Quellcode eure gesamte Applikation debuggen.

Ich habe damit in meinem Projekt schon zwei überflüssige Statements finden können und einige andere Statements noch weiter optimieren können. Ich hoffe, dass euch der Debugger auch bei eurer täglichen Arbeit unterstützen kann. Über Anregungen und Kommentare Wrede ich mich wie immer freuen.

Mär 3

Das Bermudadreieck des Internet Explorer – Oder: Wo zum Teufel ist mein Ordner hin?

Veröffentlich am Mittwoch, 3. Mär 2010 in Webentwicklung

Heute bin ich mal wieder auf ein sehr faszinierendes Problem mit dem Internet Explorer gestoßen. Meine erste Vermutung war mal wieder ein Programmierfehler im vielgeliebten IE6, aber der Fehler trat auch im Internet Explorer 7 auf.

Ich nutze in einem Projekt absolute Pfade in allen Dateinamen, Links und Formularen. Nun hatte ich aber im einem Formular dummerweise das Gleichheitszeichen nach dem Short Open Tag in PHP vergessen. Mein Formular sah also in verkürzter Form wie folgt aus:

<form action="<? ABSOLUTER_PFAD ?>form.php">
...
</form>

(weiterlesen…)

Mär 2

Tutorial: Drag-and-Drop mit Scriptaculous – Teil 1: Draggable

Veröffentlich am Dienstag, 2. Mär 2010 in Webentwicklung

Heute möchte ich mein angekündigtes Tutorial über Drag-and-Drop starten. Das Ziel dieses Tutorials ist der Nachbau einer dynamischen Newsseite, wie ich sie in meinen Artikel Öffentlich-rechtlich und vorbildhaft – So muss eine Web 2.0 zu Olympia aussehen vorgestellt habe. Da eine solche Seite mit vielen verschiedenen Techniken zusammengesetzt ist, werden wir immer kleine Teile auf dem Schritt zur fertigen Seite nachvollziehen.

Im ersten Teil geht es um die Grundlage einer Seite mit Drag-and-Drop. Wir verwenden für dieses Tutorial die Drag-and-Drop Funktionalität von Scriptaculous, welches eine Erweiterung des Prototype Frameworks ist. Um die hier gezeigten Funktionen selbst nachprogrammieren zu können benötigt ihr also zuerst einmal die beiden Frameworks.

(weiterlesen…)

Mär 1

Weitere Sicherheitslücken beim Internet Explorer 6 aufgetreten

Veröffentlich am Montag, 1. Mär 2010 in Webentwicklung

Es vergeht fast keine Woche, in dem nicht neue Sicherheitslücken im Internet Explorer 6 bekannt werden. Dieses Mal sind die Versionen 6 und 7 für Windows XP betroffen. User von Windows 7 sowie von Windows Server 2008 und Vista sind laut dem Blogartikel von Microsoft nicht betroffen.

Wie so oft wird den Nutzern geraten die Scripting Funktionen ihres Browsers zu deaktivieren. Dies ist aber nicht immer für den Benutzer möglich bzw. findet er oft die nötigen Einstellungen dazu nicht. Meiner Meinung nach wird durch diese Sicherheitslücken zunehmend die Angst vor JavaScript und Co. gestärkt. Das macht es für uns Webentwickler natürlich teilweise sehr schwer den effektiven und wohl dosierten Einsatz von clientseitigen Skriptsprachen zu rechtfertigen.

Nun kann man zwar nicht dem Internet Explorer die Schuld daran geben, denn schließlich tauchen bei jedem Browser mehrmals pro Jahr Sicherheitslücken auf. Aber beim Internet Explorer 6 häufen sich solche Fehler in letzter Zeit. Wenn das natürlich dazu führt, dass er IE6 schneller von Unternehmensrechnern verschwindet und damit seine Hauptzielgruppe verliert umso besser. Doch leider findet er sich noch immer auf jeder Standardinstallation eines Windows XP System und auch die Service Packs zwingen den Benutzer nicht zum Update. Microsoft hat zwar angekündigt den Support für Windows XP ohne SP3 zum Juli einzustellen, aber auf ein Support Ende des IE6 warten wir bisher vergeblich.

Wenn ich mir zu meinem Geburtstag diesen Monat etwas von Microsoft wünschen dürfte, dann wäre es nicht das neue Office 2010, was ja im Juni erscheinen soll, sondern das Ende einer Ära im Browsermarkt.

Feb 25

Der Internet Explorer ist tot! Lang lebe der Internet Explorer!

Veröffentlich am Donnerstag, 25. Feb 2010 in Webentwicklung

Schon vor längerer Zeit hat Google angekündigt den Support für den Internet Explorer 6.0 für die meisten seiner Dienste nicht mehr fortzusetzen. Zu dieser Aussage gibt es jetzt auch ein genaues Datum, ab wann der Support eingestellt werden soll. Der Stichtag ist demnach der 13. März 2010. Was anschließend beim Aufruf der entsprechenden Dienste mit dem Internet Explorer 6.0 zu sehen sein wird konnte ich noch nicht erfahren.

Da ich aber, wie in meinem Artikel Internet Explorer 6 unter Windows 7 nutzen mit dem Windows XP Mode beschrieben habe, selbst noch eine Installation des IE6 auf meinem Laptop laufen habe, werde ich euch dann berichten, ob die Dienste noch nutzbar sind. Auf der Homepage von YouTube ist für Nutzer des Internet Explorers schon länger ein Hinweis zu sehen, der zum Update des Browsers auffordert:

(weiterlesen…)

Feb 24

Öffentlich-rechtlich und vorbildhaft – So muss eine Web 2.0 zu Olympia aussehen

Veröffentlich am Mittwoch, 24. Feb 2010 in Webentwicklung

An dieser Stelle muss ich mal ein Lob loswerden. Zurzeit laufen ja die Olympischen Winterspiele in Vancouver und Whistler. Und natürlich ist die Präsenz im Web auch extrem hoch. Im Fernsehen sind die Spiele vor allem in ARD und im ZDF im Free-TV und bei den digitalen Kanälen der beiden Öffentlich-rechtlichen zu sehen. Das erwartet man auch, denn dafür zahlen wir ja auch brav unsere Gebühren.

Was man nicht unbedingt erwartet und was mich sehr überrascht hat ist der sehr gute Web 2.0 auftritt. Es ist immer sehr gut zu sehen, auf welchen Kanälen gerade etwas live zu sehen ist und was gerade für neue Entscheidungen gefallen sind. Außergewöhnlich ist allerdings, wie dynamisch sich die Seite an die eigenen Interessen anpassen lässt:

(weiterlesen…)

Feb 17

Zeilen-Duplizierer mit AutoComplete Felder nutzen

Veröffentlich am Mittwoch, 17. Feb 2010 in Webentwicklung

ich bekam heute in einem Kommentar die Frage gestellt, ob mein Zeilen-Duplizierer aus dem Beitrag: Einfacher Zeilen-Duplizierer mit Prototype auch auf Feldern funktioniert, die die Scriptaculous Ajax.AutoCompleter Funktion verwenden.

Ich nutze den Duplizierer selbst in einem Formular, das solche Felder enthält. Meine erste Fassung entsprach dabei dem Einzeiler aus dem vorherigen Beitrag. Das Problem dabei ist allerdings, dass die AutoCompleter Funktion beim Erzeugen mit dem Felder verknüpft wird, auf das sie angewendet werden soll. Wenn man nun dieses Feld kopiert wird nicht eine neue Instanz des Ajax.AutoCompleter erzeugt, sondern die Referenz auf das alte Feld mit kopiert. Ein Eintrag im neu erzeugten Feld aktiviert also die AutoCompleter Funktion des vorherigen Feldes.

(weiterlesen…)

Feb 1

Internet Explorer 6 unter Windows 7 nutzen mit dem Windows XP Mode

Veröffentlich am Montag, 1. Feb 2010 in Software, Webentwicklung

Wer sich von euch jetzt fragen sollte “Wieso sollte ich den IE6 unter Windows 7 nutzen?” dem würde ich gerne “Willst du nicht!” antworten. Aber diejenigen unter uns, die Webseiten entwickeln und auch mit dem IE6 eine Website testen müssen, wird dieser Artikel wohl helfen.

Unter Windows kann ja bekanntermaßen immer nur eine Version des Internet Explorers installiert sein. Da der IE8 auch einen Kompatibilitätsmodus für den IE7 besitzt hat man so schon mal zwei Fliegen mit einer Klappe geschlagen. Aber wie soll man unter Windows 7 einen IE6 installieren. Zum Glück gibt es hier eine sehr einfache und sehr benutzerfreundliche Methode. Zum Testen des Chrome Frame für meinem letzen Artikel habe ich noch eine virtuelle Maschine mit Windows XP unter Suns VirtualBox verwendet. Es geht aber sehr viel einfacher und erfordert keine Zeitaufwändige Installation eines XP-Systems, für das man auch noch eine Lizenz benötigt. Wer also keine mehr rumliegen hat und nicht unbedingt eine XP-VM benötigt, kann sich trotzdem den IE6 für Win7 holen.

(weiterlesen…)

Jan 30

Blog oder Website fit machen für den IE6

Veröffentlich am Samstag, 30. Jan 2010 in Webentwicklung

Wie auf vielen News-Seiten zu lesen ist stellt Google ab Mitte des Jahres offiziell den Support für den Internet Explorer in der Version 6.0 ein. Unter den Besuchern meines Blog befindet sich zwar nur ein verschwindend geringer Prozentsatz an IE6 Nutzern, aber auch diese sollten meine Website einigermaßen ansehnlich präsentiert bekommen.

Das größte Problem ist oft, dass die schönen Themes nicht auf den IE6 angepasst wurden und daher zu sehr unschönen Darstellungen führen. Ich habe in einer virtuellen Maschine noch eine Installation vom Internet Explorer 6 laufen und damit mal selbst meinen Blog getestet. Das Ergebnis sah leider wie folgt aus:

Blog vor der Installation des Plugins

(weiterlesen…)