Too Cool for Internet Explorer

Stellenangebot: PHP Entwickler in München


Zur Verstärkung unseres kleinen Teams in München suchen wir ab sofort einen erfahrenen PHP Entwickler (m/w) für unsere Webseiten clipdealer.de und pixelio.de. Bei clipdealer.de handelt es sich um einen neuen online Marktplatz für lizenzfreie Footage Clips und pixelio.de ist die größte kostenlose Bilddatenbank für lizenzfreie Fotos im deutschsprachigen Raum.

Ihre Aufgaben:

  • eigenverantwortliche Optimierung und Weiterentwicklung unserer Webseiten
  • die Konzeption und Erstellung neuer Module

Sie sind zuverlässig, teamfähig, haben Spaß am Programmieren und verfügen über folgende fachlichen Kenntnisse:

  • PHP5 sowie Kenntnisse mit einem objektorientierten Framework
  • MySQL 5 (u. a. Trigger, Stored Procedures)
  • Objektorientiertes JavaScript
  • Sicherer Umgang mit der Shell sowie mit den gängigen Tools
  • Linux und evtl. OSX Kenntnisse
  • Kenntnisse einer Versionsverwaltung z.b. Subversion oder CVS

Von Vorteil sind darüber hinaus folgende Kenntnisse:

  • Konfiguration eines Webservers (Apache, Lighttpd)
  • Performanceoptimierung (z.B. Lastverteilung bei Webservern und Datenbanken, Caching etc.)
  • Mehrjährige Erfahrung in der Entwicklung von PHP basierten, stark frequentierten Internetseiten

Wir bieten ein angenehmes Arbeitsumfeld in einem jungen, motivierten Team mit viel Eigenverantwortung und Raum für neue Ideen. Schicken Sie uns Ihre aussagekräftige Bewerbung bevorzugt per E-Mail oder Post mit einer detaillierten Beschreibung der bisherigen Tätigkeiten und Erfahrungen sowie allen erworbenen Zeugnissen und Ihren Gehaltsvorstellungen an folgende Adresse:

Per E-Mail:

m.hein@clipdealer.de

Per Post:

Clipdealer GmbH
Herr Markus Hein
Lipowskystr. 25
81373 München



lighttpd + virtual host + verschiedene php.ini Dateien


Im Moment beherberge ich auf meinem Rechner eine Entwicklungs- sowie eine Testumgebung, die verschiedene PHP Konfigurationen benötigen. Um verschiedene PHP Konfigurationen zu laden, kann die fastCGI Konfiguration einfach unterhalb des jeweiligen virtuellen Hosts verlagert werden und die 'bin-path' Einstellung entsprechend um den Parameter zum Laden einer speziellen Konfigurationsdatei ergänzt werden:

fastcgi.server = ( ".php" => ((
"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/opt/php5/bin/php-cgi -c /opt/php5/lib/php-devel.ini",
"bin-environment" => (
...
),
...
)))


libreadline unter OSX 10.5.x / mit gcc 4.0.1


Merkhilfe für mich:

Problem

...
gcc -dynamic -arch_only `/usr/bin/arch` -install_name /usr/local/lib/libreadline.5.2.dylib -current_version 5.2 -compatibility_version 5 -v -o libreadline.5.2.dylib readline.so vi_mode.so funmap.so keymaps.so parens.so search.so rltty.so complete.so bind.so isearch.so display.so signals.so util.so kill.so undo.so macro.so input.so callback.so terminal.so text.so nls.so misc.so xmalloc.so history.so histexpand.so histfile.so histsearch.so shell.so mbutil.so tilde.so compat.so -lncurses
Using built-in specs.
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5465~16/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=i686-apple-darwin9 --with-arch=apple --with-tune=generic --host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5465)
i686-apple-darwin9-gcc-4.0.1: -compatibility_version only allowed with -dynamiclib
make[1]: *** [libreadline.5.2.dylib] Error 1
make: [shared] Error 2 (ignored)
$

Lösung

Nach dem "./configure" das Makefile unter ./shlib/Makefile editieren und folgende Änderung durchführen (ca. Zeile 82):

- SHOBJ_LDFLAGS = -dynamic
+ SHOBJ_LDFLAGS = -dynamiclib


PHP, ssh2 und OSX


Als Merkhilfe für mich:

Problem:

pecl ssh2 0.10 lässt sich nicht compilieren.

Wie im PHP Bug Tracker beschrieben, muss ssh2.c editiert und folgendermassen geändert werden:

- #if LIBSSH2_APINO < 200412301450
+ #if LIBSSH2_VERSION_NUM < 0x001000

Der Patch wurde bereits Anfang August letzten Jahres im Bug Tracker veröffentlicht - ich frage mich, warum er es noch immer nicht in ein neues Release der ssh2 extension geschafft hat ...



PHP, syck und SuSE 64bit


Als Merkhilfe für mich:

Problem:

~/syck-0.9.2 # make
[...]
gcc -shared .libs/phpext.o -L/usr/local/lib -lsyck -Wl,-rpath -Wl,/usr/local/lib -Wl,-soname -Wl,syck.so -o .libs/syck.so /usr/lib64/gcc/x86_64-suse-linux/4.2.1/../../../../x86_64-suse-linux/bin/ld: /usr/local/lib/libsyck.a(emitter.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libsyck.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [syck.la] Error 1

Wie in der Fehlermeldung ersichtlich sollte syck mit -fPIC neu compiliert werden:

~/syck-0.55 # export CFLAGS=-fPIC; ./configure; make

Danach sollte sich das syck modul ohne weitere Probleme installieren lassen.



PHP5 mit IMAP unter Mac OS X


Als kleine Merkhilfe für mich zum o.g. Thema. Kürzlich wollte ich meiner lokalen PHP Installation unter Mac OS X 10.4.11 IMAP support hinzufügen. Meine Konfiguration dafür sah folgendermassen aus:

'./configure' '--prefix=/opt/php5' '--enable-force-cgi-redirect' '--disable-debug' '--enable-pic' '--disable-rpath' '--enable-inline-optimization' '--with-bz2' '--with-curl' '--without-gdbm' '--with-gettext=/opt' '--with-iconv' '--with-openssl' '--with-regex=system' '--with-xml' '--with-zlib' '--enable-exif' '--enable-sockets' '--enable-track-vars' '--enable-trans-sid' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--enable-memory-limit' '--enable-fastcgi' '--enable-memcache' '--enable-zip' '--enable-http' '--without-pdo-sqlite' '--without-sqlite' '--enable-mbstring' '--with-imap'

... und resultierte in folgender Fehlermeldung:

...
checking for IMAP support... yes
checking for IMAP Kerberos support... no
checking for IMAP SSL support... no
checking for utf8_mime2text signature... new
checking for U8T_CANONICAL... no
configure: error: utf8_mime2text() has new signature, but U8T_CANONICAL is missing. This should not happen. Check config.log for additional information.

Ein Blick in die config.log zeigt, dass das Include-File c-client.h nicht gefunden wird, und in der tat scheint c-client unter OSX nicht vorhanden zu sein:

conftest.c:240:22: error: c-client.h: No such file or directory

C-client ist Bestandteil des IMAP Paketes der University of Washington. Das komplette IMAP Paket kann über deren FTP Server gezogen werden: ftp://ftp.cac.washington.edu/imap/. Dort habe ich mir das Paket imap-2006k.tar.Z heruntergeladen. Nach dem Entpacken des Paketes wird dieses zunächst per:

$ make oxp

für Mac OS X gebaut. Das IMAP Paket enthält eine komplette IMAP Umgebung und die Installation dafür wäre deshalb auch dementsprechend umfangreich. Für PHP wird jedoch lediglich c-client benötigt, deshalb wird auch nur dieses "installiert", z.b.:

$ mkdir -p /usr/local/imap-2006k/include /usr/local/imap-2006k/lib
$ cp c-client/*.h /usr/local/imap-2006k/include
$ cp c-client/*.c /usr/local/imap-2006k/lib
$ cp c-client/c-client.a /usr/local/imap-2006k/lib/libc-client.a

Anschliessend kann man PHP mit folgenden Parametern neu configurieren und bauen:

'./configure' '--prefix=/opt/php5' '--enable-force-cgi-redirect' '--disable-debug' '--enable-pic' '--disable-rpath' '--enable-inline-optimization' '--with-bz2' '--with-curl' '--without-gdbm' '--with-gettext=/opt' '--with-iconv' '--with-openssl' '--with-regex=system' '--with-xml' '--with-zlib' '--enable-exif' '--enable-sockets' '--enable-track-vars' '--enable-trans-sid' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--enable-memory-limit' '--enable-fastcgi' '--enable-memcache' '--enable-zip' '--enable-http' '--without-pdo-sqlite' '--without-sqlite' '--enable-mbstring' '--with-imap=/usr/local/imap-2006k' '--with-kerberos'


PHP serialize - PHP::Serialization


Ich muss ein PHP object über 'serialize' serialisieren, an Perl weiterreichen und dort über das Modul PHP::Serialization auspacken. Ich habe Stunden damit zugebracht herauszufinden, warum ich auf meine Objektvariablen nicht zugreifen kann.

class test {
  public $public_key = 'public_val';
  private $private_key = 'private_val';
}

"Eigentlich" ist es logisch, dass PHP "auf irgendeine Art und Weise"" im serialisierten String kenntlich machen muss, welche Bestandteile des Objekts private und welche public sind, da ansonsten PHP selbst das Objekt nicht mehr korrekt deserialisieren könnte. Solchen Fragen muss man sich aber erst stellen, wenn man ein seralisiertes Objekt mit etwas anderem als PHP weiterverarbeiten möchte ... . Der Data::Dumper von Perl jedenfalls gibt für das deserialisierte Objekt folgendes zurück:

$VAR1 = bless( {
  'public_key' => 'public_val',
  'testprivate_key' => 'private_val'
}, 'PHP::Serialization::Object::test' );

Die Ausgabe von ...

print Dumper($obj->{'testprivate_key'});

... liefert jedoch ein "undef" - was ist da los? Ganz einfach: PHP fügt nicht nur den Namen der Klasse in den Namen der Objektvariablen beim Serialisieren des Objektes ein, sondern zusätlich vor und hinter dem Namen der Klasse je ein null-Byte:

0000000: 4f3a 343a 2274 6573 7422 3a32 3a7b 733a O:4:"test":2:{s:
0000010: 3130 3a22 7075 626c 6963 5f6b 6579 223b 10:"public_key";
0000020: 733a 3130 3a22 7075 626c 6963 5f76 616c s:10:"public_val
0000030: 223b 733a 3137 3a22 0074 6573 7400 7072 ";s:17:".test.pr
0000040: 6976 6174 655f 6b65 7922 3b73 3a31 313a ivate_key";s:11:
0000050: 2270 7269 7661 7465 5f76 616c 223b 7d   "private_val";}

Ein Dank an dieser Stelle geht an Plu, der mir beim Debuggen geholfen hat und nicht müde wird all meine Perl-Fragen zu beantworten.



Namespaces in PHP6?


Es geschehen anscheinend doch noch wunder! Für mich positiv überraschend haben sich die PHP Entwickler offenbar dazu durchringen können Namespaces in der kommenden neuen PHP Version zu unterstützen. D.h. Prefixe für Klassennamen sollten damit zukünftig der Vergangenheit angehören.

Alt:

class test_foo {
  function bar() {
  }
}

test_foo::bar();

Neu:

namespace test;

class foo {
  function bar() {
  }
}

test::foo::bar();

Offenbar ist es so, dass keine verschachtelten Namespaces für ein Paket definiert werden können, was ich nur begrüssen kann. Sehr gut finde ich auch die Entscheidung den bereits bekannten "Gültigkeitsbereichsoperator" zur Abtrennung der Namespaces zu verwenden.



Ermitteln der Version der JVM im Internet Explorer - The Microsoft Way


WTF!?

<HTML xmlns:IE>
<HEAD>
<STYLE>
@media all {
IE\:clientCaps {behavior:url(&default;clientcaps)}
}
</STYLE>
</HEAD>

<BODY>
<IE:clientCaps ID="oClientCaps" />

<SCRIPT>
sMSvmVersion = oClientCaps.getComponentVersion("{08B0E5C0-4FCB-11CF-AAA5-00401C608500}", "ComponentID");
</SCRIPT>
</BODY>

Gefunden im MSDN

...und der schliessende HTML tag fehlt im Beispiel auch noch...



LightTPD mit mod_cml und mod_magnet


Kleine Gedankenstütze für mich:

Sowohl 'mod_cml' als auch 'mod_magnet' in LightTPD >= 1.4.13 benötigen Lua 5.1. Falls Lua 5.1 nicht in der Linux Distribution enthalten ist oder z.b. auch unter Mac OSX, bekommt man Lighty folgendermassen compiliert (vorausgesetzt lua wurde compiliert und unter /usr/local/ installiert):

$ export LUA_CFLAGS="-I/usr/local/include"
$ export LUA_LIBS="-L/usr/local/lib -llua"
$ ./configure --prefix=/usr --with-pcre --with-lua
$ make


(PHP) Entwicklungsumgebung unter Windows


Mein eigenes PHP Framework, das ich für all meine (privaten) Web Anwendungen verwende, benötigt für einige lokale Tools sowie für Build und Deploy Prozesse unter Unix übliche Tools, wie die Bash, GNU Make, awk, sed und wie sie denn alle heissen. Ausserdem mache ich Gebrauch von einigen Eigenheiten des Dateisystems, wie symbolische Links, wie sie so nicht im Windows Dateisystem implementiert sind, bzw. nur umständlich erreicht werden können. Ausserdem setzt mein Framework LightTPD als Web Server voraus, da ich einige spezielle Module dieses hervorragenden Web Servers gerne verwende.

Nun haben aber nicht alle, die dieses Framework verwenden müssen Linux, Mac OS X oder ein anderes Betriebssystem, bei dem von Haus aus all diese schönen Dinge vorhanden sind. Nein, es gibt in der Tat noch Leute, die ein Windows bevorzugen und für die muss eine vernünftige Lösung her.

Nach einigem Überlegen bin ich auf die Idee gekommen, mein Setup unter Cygwin auszuprobieren. Cygwin ist eine Emulation der Linux API für Windows, die es - kurz gesagt - ermöglicht z.b. Linux Anwendungen auf Windows zu portieren. Mehr dazu bei Wikipedia. Cygwin bringt auch eine portierte Bash mit.

Nach Herunterladen der Distribution von der Cygwin Web Seite und der Installation von Cygwin inkl. der Entwicklungstools, war also das Fundament vorhanden. Wer mit einer Debian basierte Linux Distribution vertraut ist, wird das praktische 'apt-get' Tool kennen, mit dem man nachträglich Software installieren kann. Auch für Cygwin gibt es ein derartiges Tool - cyg-apt. Ich kann nur empfehlen, dieses Tool einzusetzen, erleichtert es doch die nachträgliche Installation von z.b. von PHP benötigten Libraries erheblich. cyg-apt ist in Python geschrieben, weshalb bei der Installation von Cygwin auch die Installation von Python berücksichtigt werden sollte.

Als nächstes habe ich mir die Quellen des aktuellen PHP (5.2) besorgt. Wenn man MySQL Support wünscht, wird ausserdem noch der Quellcode von MySQL benötigt.

Zunächst muss man also MySQL kompilieren - da wir unter Cygwin nur die Client Bibliotheken benötigen, werden auch nur diese compiliert:

./configure --prefix=/usr --without-server
make
make install

Als nächstes kann man dann PHP mit fastCGI Unterstützung compilieren. Man beachte hierbei, dass 'fastCGI' unter Windows zu Problemen führen kann. Falls es später tatsächlich zu Problemen kommt, kann man dann aber PHP immernoch als CGI Anwendung unter LightTPD verwenden. Eine PHP Configuration könnte z.b. folgendermassen aussehen:

'./configure' '--prefix=/usr' '--with-config-file-path=/etc' '--with-config-file-scan-dir=/etc/php.d' '--enable-force-cgi-redirect' '--disable-debug' '--enable-pic' '--disable-rpath' '--enable-inline-optimization' '--with-bz2' '--with-curl' '--with-freetype-dir=/usr' '--with-png-dir=/usr' '--with-gd' '--enable-gd-native-ttf' '--without-gdbm' '--with-gettext' '--with-ncurses' '--with-gmp' '--with-iconv' '--with-jpeg-dir=/usr' '--with-openssl' '--with-png' '--with-regex=system' '--with-xml' '--with-expat-dir=/usr' '--with-dom=shared,/usr' '--with-dom-xslt=/usr' '--with-dom-exslt=/usr' '--with-xmlrpc=shared' '--with-zlib' '--with-layout=GNU' '--enable-bcmath' '--enable-exif' '--enable-ftp' '--enable-sockets' '--enable-track-vars' '--enable-trans-sid' '--enable-wddx' '--with-pear=/opt/pear' '--with-mysql' '--with-mysqli=/usr/bin/mysql_config' '--enable-memory-limit' '--enable-bcmath' '--enable-calendar' '--enable-dio' '--enable-mcal' '--enable-mbstring=shared' '--enable-dbx' '--enable-mbstr-enc-trans' '--enable-mbregex' '--enable-fastcgi' '--enable-force-cgi-redirect'

Alle Bibliotheken, die PHP zusätzlich noch benötigt, kann man i.d.R. per 'cyg-apt' nachinstallieren.

Nachdem auch PHP compiliert und installiert wurde kann man sich nun die Quellen von LightTPD besorgen. Ein einfaches './configure --prefix=/usr' und 'make; make install' reicht hier in der Regel aus, um LightTPD mit den wichtigsten Modulen zu Compilieren und zu Installieren. Die Konfiguration für LightTPD findet man anschliessend unter '/etc/lighttpd/lighttpd.conf' und könnte wie folgt aussehen:

# default document-root
server.document-root = "/data/www/htdocs"

accesslog.filename = "/var/log/lighttpd/access.www.log"

server.port = 81

$SERVER["socket"] == "127.0.0.1:80" {
server.username = "nobody"
server.groupname = "nogroup"
server.errorlog = "/var/log/lighttpd/error.www.log"

fastcgi.server = ( ".php" =>
(( "host" => "127.0.0.1",
"port" => 1026,
#"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/bin/php",
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "4",
"PHP_FCGI_MAX_REQUESTS" => "100"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable"
))
)
# configure server
$HTTP["host"] == "localhost" {
simple-vhost.server-root = "/data/www/"
simple-vhost.default-host = "localhost"
simple-vhost.document-root = "/htdocs/host/"
}

server.document-root = "/data/www/htdocs/host/"
}

# index filenames index-file.names = ( "index.php", "index.html", "index.htm", "default.htm" )

# selecting modules
server.modules = ( "mod_rewrite", "mod_auth", "mod_access", "mod_accesslog", "mod_fastcgi", "mod_redirect", "mod_simple_vhost" )

# disable directory listings
server.dir-listing = "disable"

# mime types
mimetype.assign = (
".pdf" => "application/cation/pdf",
".ps" => "application/postscript",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".ogg" => "application/ogg",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".bz2" => "application/x-bzip",
".tbz" => "application/x-bzip-compressed-tar",
".tar.bz2" => "application/x-bzip-compressed-tar"
)

Da unter Windows fastCGI nicht über Sockets funktioniert, muss es über TCP durch Angabe der Parameter Host und Port konfiguriert werden. Testweise kann man nun LightTPD folgendermassen starten:

/usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf

Abschliessend soll man LightTPD noch als Windows NT Service installieren können. Hierfür benötigt man das Dienstprogramm 'cygrunsrv', das man ggf. per 'cyg-apt' nachinstallieren muss. Der Befehl zum einrichten von LightTPD als Service sollte nach meinen Recherchen dann wie folgt aussehen:

cygrunsrv --install lighty --path /usr/sbin/lighttpd --args "-D -f /etc/lighttpd/lighttpd.conf" --disp "cygwin - lightTPD"

Leider hat die Installation als Service bei mir noch nicht geklappt.

Nachdem nun also PHP und LightTPD installiert sind, fehlt nur noch die Datenbank - MySQL. Da für PHP schon mit den Client Bibliotheken compiliert wurde, reicht es aus, wenn über die MySQL Web Seite der MySQL Installer für Windows heruntergeladen wird. Darüber kann man dann MySQL komfortabel über den Setup Wizard installieren und mit dem Testen und Entwickeln loslegen.

Das hier vorgestellte Setup funktioniert übrigens nicht nur wunderbar für PHP, sondern z.b. auch für Ruby (on Rails), Python oder Perl.



Interaktive PHP Shell


Ich habe mich schon mal letztes Jahr mit der interaktiven Shell von PHP beschäftigt und war damals zu dem Schluss gekommen, dass sie nicht wirklich brauchbar ist, weil sich z.b. keine 'Fatal Error' abfangen lassen und so jeder Schreibfehler zum Abbruch der Shell führt.

Jan Kneschke, der Entwickler meines bevorzugten WebServers lighttpd, hat sich nun dieser Problematik angenommen und hat eine PHP Shell entwickelt, die den eingegebenen PHP Code vor dem Ausführen prüft. Dies geschieht über die Tokenizer Erweiterung. So lässt sich vor dem Ausführen beispielsweise überprüfen ob bei einem Funktionsaufruf die jeweilige Funktion überhaupt existiert oder dass keine doppelten Funktionsnamen angelegt werden.

Das Hauptaugenmerkt bei der Entwicklung der PHP-Shell liegt also bei der Vermeidung des 'Fatal Error' - welcher sonst zum sofortigen Abbruch des PHP Interpreters führt.

Ich habe bisher nur kurz mit der PHP Shell gespielt, kann aber jetzt schon sagen, dass sie sehr viel brauchbarer ist, als die in PHP eingebaute Shell - eben Dank der Vermeidung des 'Fatal Error'. Wer mit der Shell experimentieren möchte, kann Sier hier herunterladen:

PHP Shell von Jan Kneschke



Handbücher mit Latex


Ich habe im Laufe der vergangenen Jahre ein recht umfangreiches Framework zum Entwickeln webbasierter Anwendungen geschrieben. Die ganze Sache hat mittlerweile eine Komplexität erreicht, bei der mir die API Dokumentation alleine nicht mehr aussreicht. Aber womit schreibt man gute Handbücher, welche Tools werden dafür eingesetzt? Eine Textverarbeitung? Ein Texteditor?

Ich bin mit dem Schreiben von komplexen Dokumenten in einer Textverarbeitung wie Word oder OpenOffice nicht wirklich glücklich. Immer wenn ich also vor dieser Problematik stand, tauchte früher oder später "Latex" in meinen Gedanken auf. Bisher hatte ich jedoch immer den Lernaufwand gescheut :o).

Kürzlich war ich jedoch gezwungen längere Zeit auf meinen Internet-Anschluss daheim zu verzichten, packte die Gelegenheit beim Schopf und bestellte bei Lehmanns die DVD "TeX Collection 2005" - randgefüllt mit TeX Distributionen und Erweiterungen. Dazu besorgte ich mir noch eine gute Einführung in LaTeX, sowie eine mässige Referenz.

Ich muss sagen: der Lernaufwand war nicht wirklich hoch. Auf der DVD fand ich die Distribution MacTeX, die sich - wie man es unter OSX gewohnt ist - nahezu von selbst installiert. Auch für Windows und Linux bzw. Unix befindet sich selbstverständlich Software auf der DVD. Am Anfang ist es sicherlich ein wenig aufwändiger die Formatierungsbefehle von Hand zu setzen. Mit der Zeit geht dies aber immer flüssiger von der Hand und wenn man dann das Ergebnis als PDF vor sich sieht oder als Ausdruck in der Hand hält, dann erkennt man schnell, warum sich die Mühe gelohnt hat. Endlich eine Dokumentation, die professionell aussieht.

Ein Vorteil von LaTeX ist meines Erachtens auch, dass man LaTeX leicht in den Entwicklungs-Workflow integrieren kann, weil man den Text mit Kommandozeilen-Tools verarbeiten kann und es viele Tools gibt, die LaTeX produzieren oder man sich schnell auch eigene Tools entwickeln kann, die eigene Informationen automatisiert in das Dokument mit einbinden können.

So bin ich jetzt von phpdoc zum Generieren der API Dokumentation auf Doxygen umgestiegen. Neben der Ausgabemöglichkeit als LaTeX Dokument hat Doxygen zudem noch den Vorteil, dass man API Dokumentation auch aus Programmen, die in anderen Sprachen entwickelt wurden (wie JavaScript), damit verarbeiten kann. Es gibt sogar eine Erweiterung für das von mir favorisierte Build-System - ANT - für Doxygen.

Zum Schluss benötigte ich nur noch ein Tool, mit dem ich Quellcode von Beispielprogrammen farblich formatiert in die Dokumentation integrieren kann. Hier bin ich mit highlight fündig geworden, das zahlreiche Programmiersprachen unterstützt und LaTeX exportieren kann.

Ein ganz wichtiger Vorteil von LaTeX ist, dass die Texte selbst im reinen ASCII Format vorliegen. TeX Systeme gibt es für die meisten Plattformen. Es ist ein ausgereiftes System, das so schon seit viele Jahren besteht. Die Gefahr von inkompatibler Software, die in ein paar Jahren das Dokument nicht mehr Anzeigen oder verarbeiten kann, besteht deshalb nicht. Ausserdem eignen sich LaTeX Dokumente Aufgrund des ASCII-Formats natürlich hervorragend dazu über ein Versionssystem wie subversion oder cvs verwaltet zu werden.

Es würde mich interessieren, mit welchen Tools andere ihre Handbücher schreiben. Wer selbst noch auf der Suche ist, dem kann ich LaTeX jedenfalls nur ans Herz legen.



SDO mit PHP unter Mac OS X


Eigentlich möchte ich mich mal mit den SDOs (Service Data Objects) unter PHP beschäftigen. Die Erweiterung ist in der PHP Welt noch relativ jung und bisher nur über PECL zu bekommen.

Leider habe ich im Moment ein Problem die Erweiterung unter Mac OS X zum Laufen zu bringen. Ich habe bereits eine laufende PHP 5.1.2 Installation mit allen nötigen Erweiterungen. Sobald ich SDO jedoch aktiviere, verweigert PHP seinen Dienst. Über die Console erhalte ich folgende Fehlermeldung, mit der ich wenig anfangen kann:

dyld: NSLinkModule() error
dyld: Symbol not found: __ZTI19SDORuntimeException
Referenced from: /usr/lib/20050922/sdo_das_xml.so
Expected in: flat namespace

Trace/BPT trap

Ich habe bereits das Usenet bemüht und hoffe, dass mir dort jemand helfen kann... mal gespannt.

[Update #1 - 19.02.2006 20:45]

Ich habe eben nochmal die Version von libxml2 bei mir überprüft. In der PHP Dokumentation wird libxml2 ab Version 2.6.19 empfohlen, ich hatte jedoch Version 2.6.16 installiert. Also schnell die aktuelle Version (2.6.23) runtergeladen und alles nochmal compiliert - geht trotzdem nicht :-(.

Wenn ich die Erweiterung für den Data Access Service (DAS) XML deaktiviere, startet immerhin PHP mit der SDO Erweiterung ohne irgendeinen DAS - ich bekomme jedoch ein Warning:

PHP Warning: Interface SDO_PropertyAccess cannot contain non abstract method /abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=[]._#() in Unknown on line 0


Erweiterte Console für Firefox


Ich bin letzte Woche über ein neues Firefox Plugin gestolpert, welches die in die Jahre gekommene Javascript Console ablösen soll.

Firebug ist eine Kombination aus Javascript Console, DOM Inspektor und einem Javascript Interpreter. Daneben kann man ausserdem noch den Datenverkehr bei einem XMLHttpRequest beobachten was ihn zu einem sehr nützlich Hilfsmittel für Entwickler Browser-basierter Applikationen (AJAX / XUL) macht. Ich entwickle beruflich u.a. Anwendungen auf Basis der Mozilla Plattform (Javascript / XUL) und möchte diesen kleinen Helfer nicht mehr missen.

Sehr praktisch finde ich, daß Firebug sich am unteren Rand des Browsers einnistet. Im Weggeklappten Zustand sieht man lediglich in der Statusleiste einen Hinweis auf die in der Seite aufgetretenen Fehler. Klickt man auf diesen Hinweis, wird Firebug aufgeklappt und man kann die Fehler inspizieren. Firebug arbeitet im Gegensatz zur alten Javascript Console Kontextbezogen. D.h. es werden nur die Fehler und Informationen der aktuellen Seite bzw. des aktuellen Tabs dargestellt, was die ganze Sache sehr viel übersichtlicher macht. Im gegensatz zur herkömmlichen Javascript Console verdeckt kein Fenster mehr die Anwendung bzw. hat man die Ausgaben auf der Console beim Testen immer im Blick.

Der DOM Inspektor kann zwar bei Weitem nicht den Funktionsumfang seines grossen Bruders abdecken, dennoch ist er meist die schnellere Alternative. Es genügt ein Seitenelement anzuklicken und schon kann man die Informationen XML, CSS, Javascript und das Boxlayout einsehen.

Ich habe vor einem Jahr schon einmal einige Plugins beschrieben, die meiner Ansicht nach jeder Enwickler browser-basierter Anwendungen installiert haben sollte. Firebug gehört definitiv mit auf diese Liste - nach der Installation bleibt die angestaube Javascript Console garantiert geschlossen.