<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="de_CH">
  <title type="text">Philippe Gerber's Blog (bigwhoop.ch)</title>
  <subtitle type="text">Persönlicher Blog von Philippe Gerber. Hier geht es um Software-Entwicklung, Webwork und meinen Alltag.</subtitle>
  <updated>2009-02-11T10:44:29+01:00</updated>
  <generator uri="http://framework.zend.com" version="1.11.9">Zend_Feed_Writer</generator>
  <link rel="alternate" type="text/html" href="http://bigwhoop.ch" />
  
  
  <id>http://bigwhoop.ch</id>
  <author>
    <name>Philippe Gerber</name>
    <email>philippe@bigwhoop.ch</email>
    <uri>http://bigwhoop.ch/philippe</uri>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/phphil" /><feedburner:info uri="phphil" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Eine Einführung in die Programmiersprache Go]]></title>
    <published>2012-04-25T07:30:00+02:00</published>
    <updated>2012-04-25T07:30:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/VIEcd_0bzKU/eine-einfuehrung-in-die-programmiersprache-go" />
    <id>http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:em>Eines vorne weg: Ich bin in erster Linie PHP-Programmierer.
Und ich denke, ein Grossteil meiner Leser auch. Deshalb sind einige
Erklärungen in diesem Artikel mit PHP Vergleichen versehen. Aber
auch nicht PHP-ler sollten einigermassen gut zurecht kommen. Lasst
es mich wissen. :)</xhtml:em></xhtml:p>
<xhtml:p><xhtml:a href="http://golang.org">Go</xhtml:a> hat in den letzten Monaten
einiges an Aufmerksamkeit erhalten. Persönlich habe hab ich das
bisher aber nur aus der Ferne mitverfolgt. <xhtml:a href="http://blog.golang.org/2012/03/go-version-1-is-released.html">Mit
dem Erscheinen der Version 1</xhtml:a> vor ein paar Tagen nahm ich mir
etwas Zeit, um mich in Go reinzufuchsen. Nachfolgend ein paar
zusammengetragene Fakten und Meinungen.</xhtml:p>
<xhtml:div class="article-outline">
<xhtml:h2>Inhalt</xhtml:h2>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#was-ist-go">
Was ist Go?</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#installation-und-workspaces">
Installation und Workspaces</xhtml:a>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#workspaces">
Workspaces</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#ide">
IDE</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#was-unterscheidet-go">
Was unterscheidet Go?</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#sprachliches">
Sprachliches</xhtml:a>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#kompilierung">
Kompilierung</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#packages">
Packages</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#semikolone-und-klammern">
Semikolone und Klammern</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#variablendeklaration">
Variablendeklaration</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#pointers">
Pointers</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#kontrollstrukturen">
Kontrollstrukturen</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#fehlerbehandlung">
Fehlerbehandlung</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#datentypen-objekt-modell">
Datentypen / Objekt-Modell</xhtml:a>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#keine-klassen">
Keine Klassen</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#basic-types">
Basic Types</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#strukturen">
Strukturen</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#methoden">
Methoden</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#funktionen">
Funktionen</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#funktionen-mit-mehreren-rueckgabewerten">
Funktionen mit mehreren Rückgabewerten</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#verzoegerte-funktionsaufrufe">
Verzögerte Funktionsaufrufe</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#interfaces">
Interfaces</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#sichtbarkeiten">
Sichtbarkeiten</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#arrays-und-slices">
Arrays und Slices</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#maps">
Maps</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#unicode-strings-und-byte-slices">
Unicode, Strings und Byte-Slices</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#weitere-goodies">
Weitere Goodies</xhtml:a>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#eigener-code-formatierer">
Eigener Code Formatierer</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#anbindung-an-github-und-google-code">
Anbindung an GitHub und Google Code</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#eingebautes-testing-framework">
Eingebautes Testing Framework</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li><xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go#fazit">
Fazit</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:div>
<xhtml:p>Mehr gibt es nach dem <xhtml:a href="http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go">
Sprung</xhtml:a>! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/125/2012-04-25/eine-einfuehrung-in-die-programmiersprache-go</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Frühling für den Blog]]></title>
    <published>2012-04-07T03:04:00+02:00</published>
    <updated>2012-04-07T03:04:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/3dm3vcdsqDw/fruehling-fuer-den-blog" />
    <id>http://bigwhoop.ch/artikel/126/2012-04-07/fruehling-fuer-den-blog</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Guten Tag liebe Freunde!</xhtml:p>
<xhtml:p>Ihr wart heute bestimmt fleissig. Habt
<xhtml:strike>Jesus</xhtml:strike>Fisch, (Oster-)Hase, oder was man an
Karfreitag auch immer kocht, verschlungen und den Start des
verlängerten Wochenendes genossen. Ich hab darauf ausnahmsweise
verzichtet und stattdessen meinen Blog einem kleinen Facelifting
unterzogen. Diese Schönheitskur war eher spontan und evtl. ändert
sich auch noch ein bisschen was. Mal gucken, ich hoffe es
gefällt!</xhtml:p>
<xhtml:p class="center"><xhtml:img src="http://bigwhoop.ch/img/articles/126/new-blog.png" alt="Neuer Blog" title="" /></xhtml:p>
<xhtml:p>Wie bereits einmal versprochen, kommen bald ein paar Artikel.
Momentan hab ich beruflich viel zu tun und abends deshalb meist
etwas Motivationsprobleme, um mich nochmals mit Fachwissen
rumzuschlagen. Aber auf folgendes könnt ihr euch hoffentlich
freuen:</xhtml:p>
<xhtml:ul>
<xhtml:li>Eine Einführung in <xhtml:strong>die Programmiersprache Go</xhtml:strong>
von Google</xhtml:li>
<xhtml:li>Ein etwas <xhtml:strong>tieferer Blick auf Fliesskommazahlen</xhtml:strong>
und wie die aufgebaut sind</xhtml:li>
<xhtml:li>Wie nützlich <xhtml:strong>Bit Sets</xhtml:strong> sind und wie PHP 5.4 uns
da noch mehr hilft</xhtml:li>
</xhtml:ul>
<xhtml:p>Man liest sich!<xhtml:br />
Phil</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/126/2012-04-07/fruehling-fuer-den-blog</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[*knock, knock* - Wer ist da? - PHP 5.4!!111!!eins!!]]></title>
    <published>2012-03-01T23:49:00+01:00</published>
    <updated>2012-03-01T23:49:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/6G9tNP6Vwb4/knock-knock-wer-ist-da-php-54111eins" />
    <id>http://bigwhoop.ch/artikel/124/2012-03-01/knock-knock-wer-ist-da-php-54111eins</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Heute ist ein guter Tag, heute wurde PHP <xhtml:strike>6</xhtml:strike>5.4
released. Guckt euch die <xhtml:a href="http://www.php.net/manual/en/migration54.php">Migrationsanleitung</xhtml:a>
durch und entdeckt all die tollen Verbesserungen.</xhtml:p>
<xhtml:p>Ich freu mich besonders auf ...</xhtml:p>
<xhtml:ul>
<xhtml:li>Mehr Speed und weniger Speicherverbrauch!</xhtml:li>
<xhtml:li>UTF-8 als Standard-Charset. Also keine explizite Einstellung in
der <xhtml:code>php.ini</xhtml:code> mehr. Und auch keine nervigen
Encoding-Parameter mehr setzen (z.B.
<xhtml:code>htmlentities()</xhtml:code>).</xhtml:li>
<xhtml:li>Den <xhtml:code>callable</xhtml:code> Type-Hint für
Funktionsargumente.</xhtml:li>
<xhtml:li>Closures, die jetzt mehr Closures sind (Bindung an
"Gültigkeisbereich" mit
<xhtml:code>bind()</xhtml:code>/<xhtml:code>bindTo()</xhtml:code>).</xhtml:li>
<xhtml:li>Short Array Syntax (<xhtml:code>['p', 'h', 'i', 'l']</xhtml:code>).</xhtml:li>
</xhtml:ul>
<xhtml:p>Natürlich freu ich mich auch auf die Traits. Mal gucken wie
lange es geht, bis sich in der Community ein Quasi-Standard
entwickelt. Und hoffentlich werden Traits nicht einfach gebraucht,
nur weil es sie gibt. Vordenker vor!</xhtml:p>
<xhtml:p>Ach ja, und <xhtml:code>register_globals</xhtml:code> ist Geschichte. Ich
mach ein Fass auf. \m/</xhtml:p>
<xhtml:p><xhtml:strong>Besten Dank an das PHP-Team! Es war ein weiter Weg und
ich glaube es wurde viel gelernt. Die Zukunft sah schon trüber aus.
Thx!</xhtml:strong></xhtml:p>
<xhtml:p>PS: Ich hoffe ich finde in Zukunft wieder etwas mehr Zeit für
den Blog. Hab ein paar tolle Artikel in der Pipeline. Hoffentlich
kann ich sie bald teilen. :D</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/124/2012-03-01/knock-knock-wer-ist-da-php-54111eins</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Ich "wiege" 5.8129 Slugs]]></title>
    <published>2012-02-19T12:45:00+01:00</published>
    <updated>2012-02-19T12:45:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/HiiLSjVLmmY/ich-wiege-58129-slugs" />
    <id>http://bigwhoop.ch/artikel/123/2012-02-19/ich-wiege-58129-slugs</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Erinnert ihr euch an den Physikunterricht? Da wurde über etwas
namens Masse gesprochen. Als Funfact wurde euch dabei sicher auch
erklärt, dass euer Gewicht eigentlich eure Masse ist.</xhtml:p>
<xhtml:p>Ein Beispiel: Ich "wiege" (technisch falsch) <xhtml:code>85 kg</xhtml:code>.
Das ist meine Masse. Die ist überall genau gleich. Auf der Erde,
auf dem Mond, in Big Whoop (yay, Monkey Island Referenz) und auf
deiner Mutter (yay, "deine Mutter" Referenz - sry).</xhtml:p>
<xhtml:p>Um mein Gewicht auf der Erde zu berechnen, müssen wir die
Erdbeschleunigung beachten. Denn mein Gewicht ist die gravitale
Kraft, die auf mich einwirkt. Die selbe Kraft wirkt übrigens
entgegengesetzt auch auf die Erde ein. Da die Masse der Erde aber
so viel grösser ist als die meine, beschleunige ich schneller als
die Erde und falle deshalb zu Boden. Ausserdem wirkt der Mensch auf
der anderen Seite der Erde natürlich genauso auf diese ein.</xhtml:p>
<xhtml:p>Aber weiter: Die Schwerebeschleunigung der Erde ist etwa
<xhtml:code>9.81 m/s^2</xhtml:code>. Mit der Formel ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
F = m * a
  = 85kg * 9.81 m/s^2
  = 833.85 kg*m/s^2
  = 833.85 N
</xhtml:pre></xhtml:div>
<xhtml:p>... lässt sich mein Gewicht, oder die auf mich einwirkende
Gewichtskraft, von <xhtml:code>~833 N</xhtml:code> (für <xhtml:em>Newton</xhtml:em>)
berechnen. Soweit solltet ihr das schon mal gehört haben.</xhtml:p>
<xhtml:p>Auf der anderen Seite des Teichs gibt es diese Amerikaner, die
sich irgendwie erfolgreich gegen die Einführung des metrischen
Systems gewehrt haben. Als Belohnung dürfen sie deshalb, nebst
ihrem imperialen System, im Physikunterricht auch das metrische
System lernen. Weil das Gewicht geben die Amis lieber in Pfunden an
... damit lässt sich aber so schlecht rechnen.</xhtml:p>
<xhtml:p>Da <xhtml:code>1 kg = 2.2046 lb</xhtml:code> entspricht, wiege ich dort
drüben also nicht <xhtml:em>85 Kilogramme</xhtml:em>, sondern etwa <xhtml:em>187
Pfunde</xhtml:em>. Und hier darf ich nun das Verb <xhtml:em>wiegen</xhtml:em> ganz
ohne Gänsefüsschen verwenden. Denn Pfund ist die Einheit von
Gewicht, nicht Masse. Pfund ist also Kraft und das imperiale
Äquivalent zu Newtons.</xhtml:p>
<xhtml:p>Jetzt fragt ihr euch aber sicherlich, was denn das imperiale
Äquivalent zu unserer Masse ist? Das Ding nennt sich Slug. Um
unsere Masse ins Slugs zu berechnenm, müssen wir zwei Dinge tun:
Die obige Formel von <xhtml:code>F</xhtml:code> nach <xhtml:code>m</xhtml:code> umstellen
und die Erdbeschleunigung in imperialen Einheiten verwenden. Und
die ist <xhtml:code>32.17 ft/s^2</xhtml:code>. <xhtml:code>ft</xhtml:code> steht dabei für
<xhtml:em>Feet</xhtml:em>.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
 F = m * a
 m = F / a
   = 187 lb / 32.17 ft/s^2
   = 5.8129 lbs^2/ft
   = 5.8129 slugs
</xhtml:pre></xhtml:div>
<xhtml:p>Meine Masse ist also <xhtml:code>5.8129 slugs</xhtml:code>. Oder
umgangssprachlich, aber technisch falsch: <xhtml:strong>Ich wiege 5.8129
Slugs.</xhtml:strong></xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/123/2012-02-19/ich-wiege-58129-slugs</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Der gelegentlich nützliche Ratschlag von Demeter]]></title>
    <published>2012-01-19T07:30:00+01:00</published>
    <updated>2012-01-19T07:30:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/08gynChS5FI/der-gelegentlich-nuetzliche-ratschlag-von-demeter" />
    <id>http://bigwhoop.ch/artikel/122/2012-01-19/der-gelegentlich-nuetzliche-ratschlag-von-demeter</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Kennt ihr das <xhtml:a href="http://de.wikipedia.org/wiki/Law_of_Demeter">Gesetz von
Demeter</xhtml:a> (<xhtml:em>law of demeter</xhtml:em>)? Das war natürlich eine
rhetorische Frage, denn ich werde jetzt sowieso erklären, was
dieses "Gesetz" ist. Ha!</xhtml:p>
<xhtml:p>Das Gesetz von Demeter ist eine Richtlinie, die dabei helfen
soll, dass Objekte in der objektorientierten Programmierung
möglichst wenige Abhängigkeiten haben. Sein Ziel will es damit
erreichen, indem es Objekte nur mit seinen unmittelbaren Nachbarn
kommunizieren lässt.</xhtml:p>
<xhtml:p>Eine Methoden (<xhtml:em>M</xhtml:em>) eines Objekt (<xhtml:em>O</xhtml:em>) soll nur
kommunizieren mit ...</xhtml:p>
<xhtml:ul>
<xhtml:li>sich selbst, also anderen Methoden von <xhtml:em>O</xhtml:em></xhtml:li>
<xhtml:li>Objekten, die ein Property von <xhtml:em>O</xhtml:em> sind</xhtml:li>
<xhtml:li>Objekten, die an <xhtml:em>M</xhtml:em> als Argumente übergeben wurden</xhtml:li>
<xhtml:li>Objekten, die innerhalb von <xhtml:em>M</xhtml:em> erstellt wurden</xhtml:li>
</xhtml:ul>
<xhtml:p>Hier das Wikipedia-Beispiel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
class Beine
{
    public function bewegen()
    {
        /* ... */
    }
}

class Hund
{
    private $beine;

    public function __construct(Beine $beine)
    {
        $this-&gt;beine = $beine
    }

    public function gibBeine()
    {
        return $this-&gt;beine;
    }
}

class Herrchen
{
    public function gassiGehen(Hund $hund)
    {
        $hund-&gt;gibBeine()-&gt;bewegen();
    }
}

$hund = new Hund(new Beine);
$herrchen = new Herrchen();
$herrchen-&gt;gassiGehen($hund);
</xhtml:pre></xhtml:div>
<xhtml:p>Die Zeile, die gegen das Gesetz von Demeter verstösst, ist
...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$hund-&gt;gibBeine()-&gt;bewegen();
</xhtml:pre></xhtml:div>
<xhtml:p>Das Objekt der <xhtml:code>Herrchen</xhtml:code> Klasse greift hier auf ein
Objekt der Klasse <xhtml:code>Beine</xhtml:code> zu, obwohl dieses kein
direkter Nachbar ist. Der direkte Nachbar ist das Objekte der
Klasse <xhtml:code>Hund</xhtml:code>. Um den Code "gesetzestreu" zu machen,
müsste man eine Wrapper-Methode in der <xhtml:code>Hund</xhtml:code>-Klasse
einbauen. Schliesslich weiss der Hund ja auch selber, wie er laufen
kann.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
class Beine
{
    // ...
}

class Hund
{
    // ...

    public function gehen()
    {
        $this-&gt;beine-&gt;bewegen();
    }
}

class Herrchen
{
    public function gassiGehen(Hund $hund)
    {
        $hund-&gt;gehen();
    }
}

// ...
</xhtml:pre></xhtml:div>
<xhtml:p>Klingt doch eigentlich nach einer ganz guten Idee, oder? Ja,
aber natürlich entsteht dadurch auch einiges an zusätzlichem Code.
Schlussendlich kann sogar die Übersichtlichkeit leiden. Man muss
sich also stets überlegen, ob das Gesetz von Demeter bei einer
Situation wirklich hilft - oder eher nicht. In den meisten Fällen
könnte man die Kopplung seiner Objekte aber sicherlich verkleinern,
wenn man etwas öfters an die olle <xhtml:a href="http://de.wikipedia.org/wiki/Demeter">Göttin</xhtml:a> denken würde.</xhtml:p>
<xhtml:p>Und was meinst du dazu, <xhtml:a href="http://de.wikipedia.org/wiki/Martin_Fowler">Martin Fowler</xhtml:a>?</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/122/lod.png" alt="Law of Demeter" /></xhtml:p>
<xhtml:p>Genau.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/122/2012-01-19/der-gelegentlich-nuetzliche-ratschlag-von-demeter</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Musik für einen guten Start ins Weltuntergangsjahr]]></title>
    <published>2012-01-01T10:00:00+01:00</published>
    <updated>2012-01-01T10:00:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/5CfQk5XI0uA/musik-fuer-einen-guten-start-ins-weltuntergangsjahr" />
    <id>http://bigwhoop.ch/artikel/121/2012-01-01/musik-fuer-einen-guten-start-ins-weltuntergangsjahr</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:strong>2012, Baby!</xhtml:strong> Verrückte sagen, die Welt gehe bald
unter.<xhtml:br />
Who cares? Wir tanzen weiter, oder?! :-)</xhtml:p>
<xhtml:a id="the-automatic-monster" name="the-automatic-monster" />
<xhtml:h2>The Automatic - Monster</xhtml:h2>
<xhtml:iframe width="420" height="315" src="http://www.youtube.com/embed/dp0Z7otCk7Q" frameborder="0" allowfullscreen="" /> <xhtml:a id="hard-fi-good-for-nothing" name="hard-fi-good-for-nothing" />
<xhtml:h2>Hard-Fi - Good For Nothing</xhtml:h2>
<xhtml:iframe width="560" height="315" src="http://www.youtube.com/embed/ZVe96l_h-SM" frameborder="0" allowfullscreen="" /> <xhtml:a id="the-pigeon-detectives-im-not-sorry" name="the-pigeon-detectives-im-not-sorry" />
<xhtml:h2>The Pigeon Detectives - I'm Not Sorry</xhtml:h2>
<xhtml:iframe width="420" height="315" src="http://www.youtube.com/embed/Z0GaFD9SeA0" frameborder="0" allowfullscreen="" /> <xhtml:a id="orson-no-tomorrow" name="orson-no-tomorrow" />
<xhtml:h2>Orson - No Tomorrow</xhtml:h2>
<xhtml:iframe width="420" height="315" src="http://www.youtube.com/embed/aqN7gntG8qw" frameborder="0" allowfullscreen="" /> <xhtml:a id="battles-atlas" name="battles-atlas" />
<xhtml:h2>Battles - Atlas</xhtml:h2>
<xhtml:iframe width="560" height="315" src="http://www.youtube.com/embed/7tRdUy_Wr4s" frameborder="0" allowfullscreen="" /> <xhtml:a id="retro-stefson-kimba" name="retro-stefson-kimba" />
<xhtml:h2>Retro Stefson - Kimba</xhtml:h2>
<xhtml:iframe width="560" height="315" src="http://www.youtube.com/embed/omZvCIPsd-0" frameborder="0" allowfullscreen="" /></xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/121/2012-01-01/musik-fuer-einen-guten-start-ins-weltuntergangsjahr</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Statische Methoden sind einfach nur Funktionen - also Vorsicht!]]></title>
    <published>2011-12-21T16:29:00+01:00</published>
    <updated>2011-12-21T16:29:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/T79pbaovvDk/statische-methoden-sind-einfach-nur-funktionen-also-vorsicht" />
    <id>http://bigwhoop.ch/artikel/95/2011-12-21/statische-methoden-sind-einfach-nur-funktionen-also-vorsicht</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Da, ich hab's gesagt. So dahin geklatscht wie es wirkt, so
simpel ist es auch. <xhtml:code>String::format()</xhtml:code> und
<xhtml:code>string_format()</xhtml:code> ist genau das Gleiche. Der einzige
Vorteil den die statische Methode mitbringt, ist, dass durch die
Klasse eine Art Namensraum (oder Tag) gegeben ist.</xhtml:p>
<xhtml:p>Aber im Endeffekt behaupte ich: <xhtml:strong>Statische Methoden
leiten uns dazu, uns von OOP abzuwenden und zurück zu unseren
prozeduralen Wurzeln zu gehen. Oder anders gesagt: Faul zu
sein.</xhtml:strong></xhtml:p>
<xhtml:p>Bevor ihr mich jetzt würgt, möchte ich anmerken, dass statische
Methoden (und Variablen) natürlich ihre Daseinsberechtigung haben.
Und man muss sie auch nicht um jeden Preis vermeiden. Doch sollten
eure Klassen nur so vom <xhtml:code>static</xhtml:code>-Schlüsselwort
durchzogen sein, ja dann sollte ihr nochmals die Architektur eurer
Applikation überprüfen.</xhtml:p>
<xhtml:p>Als Daumenregel postuliere ich:</xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:strong>Statische Methoden sind immer nur dann okay, wenn sie
sich auch wirklich wie Funktionen verhalten.</xhtml:strong> Dazu müssen
sie zustandloslos sein (selbe Eingabe = selbe Ausgabe, keine
Nebenwirkung, etc.). Bei jeder anderen Anwendung ist Vorsicht
geboten.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Nachfolgend ein paar wild durchmixte Szenarien, wo wir auf
statische Methoden und Variablen treffen.</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p><xhtml:strong>Ihr wollt Daten global verfügbar machen?</xhtml:strong> Nutzt
Objekte und schiebt diese umher. Sowas wie <xhtml:a href="http://de.wikipedia.org/wiki/Dependency_Injection">Dependency
Injection</xhtml:a> hilft euch dabei. Globale Daten sind mühsam zu testen
und der Code wird unübersichtlich. Ausserdem fällt man mit der
Aussage <xhtml:em>"Aber ich brauche XY nur einmal in meiner App"</xhtml:em>
früher oder später auf die Schnauze. Nutzt keine <xhtml:a href="http://www.brandonsavage.net/the-registry-pattern-reexamined/">Registry</xhtml:a>
für die Konfigurationen.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p><xhtml:strong>Ihr braucht statische Methoden als Helper?</xhtml:strong> Das
ist wohl okay. Aber bedenkt, dass sich konkrete Implementierung
einfacher vererben lassen. Auch könntet ihr anstatt
<xhtml:code>BlogHelper::formatUserName($user)</xhtml:code> das Strategy Pattern
anwenden: <xhtml:code>$user-&gt;formatName(new
BlogUserNameFormatter());</xhtml:code>. Vielleicht gibt's ja dann auch
mal eine <xhtml:code>RssFeedUserNameFormatter</xhtml:code>-Strategie. Oder eine
Strategie die <xhtml:code>BlogUserNameFormatter</xhtml:code> erweitert.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p><xhtml:strong>Ihr braucht eine Factory?</xhtml:strong> Keine Einwände.
<xhtml:a href="http://de.wikipedia.org/wiki/Fabrikmethode">Factory-Methoden</xhtml:a>
liefern von Natur aus die selben Resultate für gleiche Eingaben.
D.h. die Abhängigkeiten müssen meist direkt geliefert werden.
Ansonsten findet keine Produktion statt (<xhtml:em>höhöhö</xhtml:em>).</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p><xhtml:strong>Ihr wollt eine API (für andere) entwickeln?</xhtml:strong>
Bitte verzichtet auf statische Methoden. Konkrete Implementierungen
lassen sich so viel besser erweitern. Ihr könnt anderen viel Frust
ersparen.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>Um noch auf ein paar Probleme einzugehen:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p><xhtml:strong>Vererbung</xhtml:strong>: Das Problem ist nicht die
Implementierung der ableitenden Klasse, sondern deren Einsatz. Da
überall in eurem Code bei den statischen Methodenaufrufen der
Klassenname teil des Aufrufes ist, müsste ihr euren ganzen Code
durchsuchen und Anpassungen vornehmen.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p><xhtml:strong>Mischmasch</xhtml:strong>: Gerade wenn ihr statische Methoden
vor allem für Helper/Util-Klassen nutzt, werdet ihr ziemlich
schnell das <xhtml:a href="http://de.wikipedia.org/wiki/Single_Responsibility_Prinzip">Single
Responsibility Prinzip</xhtml:a> verletzen. Das besagt nämlich, dass jede
Klasse nur eine klare Aufgabe haben sollte und alle Methoden auch
nur der Erfüllung dieser Aufgabe dienen sollten.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>Ergänzungen? Korrekturen? :)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/95/2011-12-21/statische-methoden-sind-einfach-nur-funktionen-also-vorsicht</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[SPAM-Mails nützlich machen]]></title>
    <published>2011-12-20T16:16:00+01:00</published>
    <updated>2011-12-20T16:16:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/WZBhH-pFKUc/spam-mails-nuetzlich-machen" />
    <id>http://bigwhoop.ch/artikel/120/2011-12-20/spam-mails-nuetzlich-machen</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>In <xhtml:a href="http://www.netzwoche.ch/de-CH/News/2011/12/20/IBM-prognostiziert-die-Abschaffung-von-Passwoertern.aspx">
IBMs Five-in-Five-Prognose</xhtml:a> für die nächsten 5 Jahre steht unter
anderem <xhtml:em>"SPAM-Mails bekommen einen Sinn"</xhtml:em>.</xhtml:p>
<xhtml:p>Darüber hab ich mir noch gar nie Gedanken gemacht. Aber mit
einer klugen Idee könnte da jemand wohl viel Geld scheffeln. Nicht
so viel Geld lässt sich bestimmt mit meiner Idee zur sinnvollen
Nutzung von SPAM-Mails erwirtschaften:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Millionen Menschen leiten ihre SPAM-Mails automatisch an eine
bestimmte E-Mail Adresse weiter. Ein Service dahinter berechnet
anhand eines Algorithmus' und der erhaltenen Daten fortlaufend
<xhtml:strong>Zufallszahlen</xhtml:strong>.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Damit die Zahlen auch zufällig sind, müssten natürlich viele,
viele echte Menschen teilnehmen. Irgendwie müsste man auch noch ein
bisschen Manipulationsschutz einbinden. Z.B. könnte man jedes x-te
Mail einfach ignorieren. Ich kenn mich mit dem Thema Zufälligkeit
nicht besonders aus, weiss aber, dass echte Zufälligkeit sehr
schwer zu erreichen ist. Kann deshalb auch nicht abschätzen
inwiefern meine Idee nur pseudo-zufällige Zahlen erzeugen würde.
Aber ich wollte es mal niederschreiben, da mir die grundsätzliche
Idee von <xhtml:em>"SPAM-Mails klug nutzen"</xhtml:em> so offensichtlich
erschien.</xhtml:p>
<xhtml:p>Was ist eure Idee, um SPAM nützlich zu machen?</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/120/2011-12-20/spam-mails-nuetzlich-machen</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Properties: Neue Get-/Set-Syntax für PHP?]]></title>
    <published>2011-12-05T10:40:00+01:00</published>
    <updated>2011-12-05T10:40:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/qJ-DXn5lCX4/properties-neue-get-set-syntax-fuer-php" />
    <id>http://bigwhoop.ch/artikel/119/2011-12-05/properties-neue-get-set-syntax-fuer-php</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:blockquote>
<xhtml:p><xhtml:strong>Update 09.01.2012</xhtml:strong>: Der Link zum aktuellen RFC
(21.12.2011) ist <xhtml:a href="https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented">https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented</xhtml:a></xhtml:p>
</xhtml:blockquote>
<xhtml:p>In PHP nennen wir Instanzvariablen meist Eigenschaften, oder
eben Properties, einer Klasse. In der Folge nennen wir die nun
Attribute, denn sonst versteht niemand mehr was <xhtml:a href="https://wiki.php.net/rfc/propertygetsetsyntax">dieses RFC</xhtml:a>
vorschlägt: <xhtml:strong>Eine neue Syntax um Getter und Setter in PHP zu
schreiben.</xhtml:strong></xhtml:p>
<xhtml:a id="worum-gehts" name="worum-gehts" />
<xhtml:h2>Worum geht's?</xhtml:h2>
<xhtml:p>Schaut euch diesen Code mal an. Achtung: Die <xhtml:code>$value</xhtml:code>
Variable ist automatisch im Gültigkeitsbereich von <xhtml:code>set</xhtml:code>
verfügbar.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Person
{
    const KG_TO_LB = 0.45359237;

    private $weight;

    public property weightInKilograms
    {
        public get { return $this-&gt;weight; }
        public set { $this-&gt;weight = $value; }
    }

    public property weightInPounds
    {
        public get { return $this-&gt;weight / self::KG_TO_LB; }
        public set { $this-&gt;weight = $value * self::KG_TO_LB; }
    }
}

$philippe = new Person();
$philippe-&gt;weightInKilograms = 84;
echo $philippe-&gt;weightInPounds; // 185.188...
</xhtml:pre></xhtml:div>
<xhtml:p>Properties sollen also PHP so erweitern, dass schnell und
einfach Getter und Setter für Klassen-Attribute geschrieben werden
können. Und zwar mit einem Language-Feature und nicht als
Eigenimplementation in Userland.</xhtml:p>
<xhtml:p>Obiges Beispiel ist momentan nur mit dem "Überladen" mittels
<xhtml:code>__get()</xhtml:code> und <xhtml:code>__set()</xhtml:code> möglich. Dieser
Ansatz hat mehrere Probleme:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>__get()</xhtml:code> und <xhtml:code>__set()</xhtml:code> werden für alle
undefinierten Attribute aufgerufen. Es muss also immer darauf
geachtet werden welches Attribute übergeben wurde.</xhtml:li>
<xhtml:li><xhtml:code>__get()</xhtml:code> und <xhtml:code>__set()</xhtml:code> sorgen oft dafür,
dass der Code nicht sauber strukturiert wird.</xhtml:li>
<xhtml:li>Es ist Magie. Und Magie ist nicht nur böse, sondern lässt sich
auch nicht geschickt in eine IDE integrieren. Also sowas wie
Autocompletion wird komplizierter.</xhtml:li>
<xhtml:li>Und am wichtigsten: <xhtml:code>__get()</xhtml:code> und
<xhtml:code>__set()</xhtml:code> + Vererbung sind eine Qual.</xhtml:li>
</xhtml:ul>
<xhtml:a id="noch-mehr-spass" name="noch-mehr-spass" />
<xhtml:h2>Noch mehr Spass</xhtml:h2>
<xhtml:p>Wie ihr am <xhtml:code>public</xhtml:code> vor dem <xhtml:code>property</xhtml:code> und
den <xhtml:code>get</xhtml:code>s und <xhtml:code>set</xhtml:code>s erahnen könnt, sollen
die Properties auch die bekannten Sichtbarkeiten implementieren.
Also <xhtml:code>public</xhtml:code>, <xhtml:code>protected</xhtml:code> und
<xhtml:code>private</xhtml:code>. Properties sollen sich damit reibungslos in
Klassenhierarchien einbauen lassen. Hier ein paar Beispiele:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Number
{
    protected $n;

    public function __construct($n)
    {
        $this-&gt;number = $n;
    }

    public property number
    {
        set { $this-&gt;n = (int)$value; }
        get { return $this-&gt;n; }
    }

    public property double
    {
        get { return $this-&gt;n * 2; }
    }
}

class HalfNumber extends Number
{
    public property number
    {
        set { $this-&gt;n = $value / 2; }
    }

    public property double
    {
        set { return $this-&gt;number / 2; }
    }
}

$n = new Number(42);
echo $n-&gt;double; // 84
$n-&gt;double = 20; // Fehler: Kein Setter vorhanden

$n = new HalfNumber(42);
echo $n-&gt;number; // 21
$n-&gt;double = 20;
echo $n-&gt;number; // 5
</xhtml:pre></xhtml:div>
<xhtml:p>Evtl. soll es auch ein <xhtml:code>readonly</xhtml:code>-Schlüsselwort für
Properties geben. Damit liese sich unterbinden, dass Unterklassen
<xhtml:code>set</xhtml:code>-Properties implementieren können. Also in obigem
Beispiel könnte <xhtml:code>Number</xhtml:code> beim
<xhtml:code>double</xhtml:code>-Property das
<xhtml:code>readonly</xhtml:code>-Schlüsselwort verwenden und
<xhtml:code>HalfNumber</xhtml:code> könnte dann nicht das
<xhtml:code>set</xhtml:code>-Property implementieren.</xhtml:p>
<xhtml:p>Ein Vorschlag sieht auch vor, dass Properties ähnlich wie
<xhtml:strong>Traits</xhtml:strong> ausserhalb von Klassen definiert und dann
in eben solche eingespiesen werden können. Das wäre für
Wiederverwendbarkeit ziemlich kuhl.</xhtml:p>
<xhtml:p>So, was haltet ihr davon? Sinnvolle Ergänzung? Zucker den
niemand braucht?</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/119/2011-12-05/properties-neue-get-set-syntax-fuer-php</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Ach, Ticketcorner.]]></title>
    <published>2011-12-01T09:09:00+01:00</published>
    <updated>2011-12-01T09:09:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/I6k59-senh8/ach-ticketcorner" />
    <id>http://bigwhoop.ch/artikel/118/2011-12-01/ach-ticketcorner</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Auf meiner musikalischen To-See-Liste steht seit Jahren ganz
oben <xhtml:strong>Red Hot Chili Peppers</xhtml:strong>. Deshalb hab ich mich
heute (für meine Verhältnisse) früh aus dem Bett gekämpft, damit
ich um 08 Uhr bei meiner Post stehe würde um am
Ticketcorner-Schalter <xhtml:a href="http://www.ticketcorner.ch/red-hot-chili-peppers-tickets-bern.html?affiliate=TCS&amp;doc=artistPages%2Ftickets&amp;fun=artist&amp;action=tickets&amp;key=612795%241849471&amp;jumpIn=yTix&amp;kuid=401084&amp;from=erdetaila">
Tickets</xhtml:a> zu ergattern.</xhtml:p>
<xhtml:p>Lieber Ticketcorner, leider ist dein System wohl
zusammengebrochen. Jedenfalls die Verbindung der netten Verkäuferin
hat nicht funktioniert. Überlastet sei es. Was macht man also im
Jahr 2011? Man packt das Smartphone aus und bucht während dem
Anstehen online. Denn das funktioniert. Genial!!!11!!eins!1!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/118/2011-12-01/ach-ticketcorner</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PHP zvals und Referenzen erklärt]]></title>
    <published>2011-11-30T19:22:00+01:00</published>
    <updated>2011-11-30T19:22:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/oqsGtEu2SJM/php-zvals-und-referenzen-erklaert" />
    <id>http://bigwhoop.ch/artikel/117/2011-11-30/php-zvals-und-referenzen-erklaert</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Heute schauen wir uns kurz an, wie PHP Variablen speichert und
wie Referenzen funktionieren. Los geht's.</xhtml:p>
<xhtml:a id="symbols-und-zvals" name="symbols-und-zvals" />
<xhtml:h2>Symbols und zvals</xhtml:h2>
<xhtml:p>Jede PHP Variable besteht aus einem <xhtml:em>Symbol</xhtml:em> (dem Name
der Variable) und einer <xhtml:em>zval</xhtml:em> (Zend Value), einem
speziellen Daten-Container. Diese zval speichert nebst dem Datentyp
und dem Wert, auch wie viele Symbols sie hat
(<xhtml:code>refcount</xhtml:code>) und ob diese Symbols als Referenzen
definiert wurden (<xhtml:code>is_ref</xhtml:code>).</xhtml:p>
<xhtml:p>Im PHP Souce Code ist die <xhtml:code>zval</xhtml:code> einfach eine simple
Struktur:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
typedef struct _zval_struct {
    zvalue_value value;
    zend_uint refcount;
    zend_uchar type;
    zend_uchar is_ref;
}
</xhtml:pre></xhtml:div>
<xhtml:a id="refcount" name="refcount" />
<xhtml:h3>refcount</xhtml:h3>
<xhtml:p><xhtml:code>refcount</xhtml:code> ist wichtig, damit PHP für gleiche
Variablen (im Sinne von <xhtml:code>$a = $b = 42</xhtml:code>) dieselben Daten
nicht mehrmals speichern muss.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/117/two-vars.png" alt="Zwei Variabeln" /></xhtml:p>
<xhtml:p>Der <xhtml:code>refcount</xhtml:code>-Zähler wird also inkrementiert, wenn
ein neues Symbol hinzugefügt wird und dekrementiert, falls ein
Symbol gelöscht wird (z.B. mit <xhtml:code>unset()</xhtml:code>). Wenn
<xhtml:code>refcount</xhtml:code> Null (<xhtml:code>0</xhtml:code>) erreicht, kann die zval
aus dem Speicher gekickt werden. <xhtml:strong>Achtung: Die zval weiss
nicht welche Symbols auf sie zeigen.</xhtml:strong></xhtml:p>
<xhtml:a id="is-ref" name="is-ref" />
<xhtml:h3>is_ref</xhtml:h3>
<xhtml:p>Das <xhtml:code>is_ref</xhtml:code>-Flag wird gesetzt, fall eine Variable
einer anderen per Referenz zugewiesen wurde.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/117/two-vars-by-ref.png" alt="Zwei Variabeln per Referenz" /></xhtml:p>
<xhtml:p>Wieso dieses Flag so wichtig ist, sehen wir gleich.</xhtml:p>
<xhtml:a id="copy-on-write" name="copy-on-write" />
<xhtml:h2>Copy-on-Write</xhtml:h2>
<xhtml:p>Wir haben also gesehen, dass PHP versucht Arbeitspeicher zu
sparen und unnötiges Kopieren zu verhindern. Doch wann wird
kopiert? Nun, zvals (oder die "Daten") werden dann kopiert, wenn
nicht mehr sichergestellt werden kann, dass alle Symbols auf die
selben Daten verweisen werden oder können. Also z.B. wenn
<xhtml:code>$a</xhtml:code> und <xhtml:code>$b</xhtml:code> zuerst gleich sind, danach aber
<xhtml:code>$b</xhtml:code> geändert wird.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/117/two-vars-splitted-by-change.png" alt="Zwei Variablen erst gleich, danach eine geändert" /></xhtml:p>
<xhtml:p>Solange <xhtml:code>$a</xhtml:code> und <xhtml:code>$b</xhtml:code> gleich sind, gibt es
keinen Grund die Daten zu kopieren. Wird <xhtml:code>$b</xhtml:code> aber
verändert, muss die zval kopiert werden. Daneben gibt es noch zwei
andere Szenarien, wann zvals aufgeteilt werden müssen. Bei beiden
geht es darum, wenn ein drittes Symbol ins Spiel kommt.</xhtml:p>
<xhtml:a id="referenz-auf-codeis-ref-0code" name="referenz-auf-codeis-ref-0code" />
<xhtml:h3>Referenz auf <xhtml:code>is_ref = 0</xhtml:code></xhtml:h3>
<xhtml:p>Nehmen wir an, dass <xhtml:code>$a</xhtml:code> und <xhtml:code>$b</xhtml:code> "gleich"
sind. Würde <xhtml:code>$c</xhtml:code> nun ebenfalls <xhtml:code>$a</xhtml:code>
zugewiesen, würde einfach ein weiteres Symbol erstellt werden. Wenn
aber <xhtml:code>$c</xhtml:code> per Referenz an <xhtml:code>$a</xhtml:code> (oder
<xhtml:code>$b</xhtml:code>) zugewiesen wird, muss PHP die zval kopieren. Denn
<xhtml:code>$c</xhtml:code> soll ja nur die selben Daten wie <xhtml:code>$a</xhtml:code>
referenzieren, nicht aber wie <xhtml:code>$b</xhtml:code>.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/117/two-vars-splitted-by-ref.png" alt="Zwei Variablen, geteilt durch neue Referenz" /></xhtml:p>
<xhtml:a id="zuweisung-auf-codeis-ref-1code" name="zuweisung-auf-codeis-ref-1code" />
<xhtml:h3>Zuweisung auf <xhtml:code>is_ref = 1</xhtml:code></xhtml:h3>
<xhtml:p>Und dann gibt es noch das Gegenteil davon: Zwei Variablen
<xhtml:code>$a</xhtml:code> und <xhtml:code>$b</xhtml:code> referenzieren sich, und eine
dritte Variable <xhtml:code>$c</xhtml:code> wird normal <xhtml:code>$a</xhtml:code> (oder
<xhtml:code>$b</xhtml:code>) zugewiesen. Da die Referenz zwischen
<xhtml:code>$a</xhtml:code> und <xhtml:code>$b</xhtml:code> nicht zerstört werden darf,
muss <xhtml:code>$c</xhtml:code> einen eigenen Daten-Container nutzen.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/117/two-vars-by-ref-splitted-by-val.png" alt="Zwei referenzierende Variablen, geteilt durch neue Variable" /></xhtml:p>
<xhtml:p>Dieses Verfahren, dass Daten nicht kopiert werden, solange es
nicht nötig ist, nennt sich <xhtml:strong>copy-on-write</xhtml:strong> oder
<xhtml:strong>copy-on-change</xhtml:strong>.</xhtml:p>
<xhtml:a id="wann-wird-kopiert" name="wann-wird-kopiert" />
<xhtml:h3>Wann wird kopiert?</xhtml:h3>
<xhtml:p>Bei PHP gibt es dazu ein paar einfache Grundregeln.</xhtml:p>
<xhtml:p>Wenn <xhtml:strong>Variablen einander</xhtml:strong> zugewiesen werden,
sehen die Regeln so aus:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Wenn <xhtml:code>refcount</xhtml:code> = <xhtml:code>1</xhtml:code>:</xhtml:p>
<xhtml:ul>
<xhtml:li>Erfolgt die Zuweisung normal wird <xhtml:code>refcount</xhtml:code> auf
<xhtml:code>2</xhtml:code> gesetzt und <xhtml:code>is_ref</xhtml:code> bleibt
<xhtml:code>0</xhtml:code></xhtml:li>
<xhtml:li>Erfolgt die Zuweisung per Referenz wird <xhtml:code>refcount</xhtml:code>
auf <xhtml:code>2</xhtml:code> gesetzt und <xhtml:code>is_ref</xhtml:code> auf
<xhtml:code>1</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p>Wenn <xhtml:code>refcount</xhtml:code> grösser <xhtml:code>1</xhtml:code>:</xhtml:p>
<xhtml:ul>
<xhtml:li>Erfolgt die Zuweisung normal und <xhtml:code>is_ref</xhtml:code> ist
<xhtml:code>0</xhtml:code>, kann <xhtml:code>refcount</xhtml:code> um <xhtml:code>1</xhtml:code> erhöht
werden. Ist <xhtml:code>is_ref</xhtml:code> aber <xhtml:code>1</xhtml:code>, dann muss eine
neue zval erstellt werden.</xhtml:li>
<xhtml:li>Erfolgt die Zuweisung per Referenz und <xhtml:code>is_ref</xhtml:code> ist
<xhtml:code>1</xhtml:code>, kann <xhtml:code>refcount</xhtml:code> um <xhtml:code>1</xhtml:code> erhöht
werden. Ist <xhtml:code>is_ref</xhtml:code> aber <xhtml:code>0</xhtml:code>, dann muss die
bestehende zval aufgeteilt werden.</xhtml:li>
</xhtml:ul>
</xhtml:blockquote>
<xhtml:p>Werden <xhtml:strong>Variablen neue Werte</xhtml:strong> zugewiesen, sehen
die Regeln so aus:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Wenn <xhtml:code>refcount</xhtml:code> = <xhtml:code>1</xhtml:code>:</xhtml:p>
<xhtml:ul>
<xhtml:li>Der bestehende Wert und Datentyp kann überschrieben
werden.</xhtml:li>
</xhtml:ul>
<xhtml:p>Wenn <xhtml:code>refcount</xhtml:code> grösser <xhtml:code>1</xhtml:code>:</xhtml:p>
<xhtml:ul>
<xhtml:li>Wenn <xhtml:code>is_ref</xhtml:code> gleich <xhtml:code>0</xhtml:code> ist, dann muss
eine neue zval erstellt werden.</xhtml:li>
<xhtml:li>Wenn <xhtml:code>is_ref</xhtml:code> gleich <xhtml:code>1</xhtml:code> ist, dann kann
der bestehenden Wert und Datentyp überschrieben werden.</xhtml:li>
</xhtml:ul>
</xhtml:blockquote>
<xhtml:p>Eigentlich ganz simpel, und doch können damit so viele
Kombinationen abgedeckt werden. :)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/117/2011-11-30/php-zvals-und-referenzen-erklaert</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Programmieren lernen mit UC Berkeleys "Structure and Interpretation of Computer Programs"]]></title>
    <published>2011-11-18T08:00:00+01:00</published>
    <updated>2011-11-18T08:00:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/GwX3LSlGdG4/programmieren-lernen-mit-uc-berkeleys-structure-and-interpretation-of-computer-programs" />
    <id>http://bigwhoop.ch/artikel/116/2011-11-18/programmieren-lernen-mit-uc-berkeleys-structure-and-interpretation-of-computer-programs</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Die UC Berkeley bietet auf ihrem YouTube-Kanal unter anderem den
kompletten Kurs <xhtml:a href="http://www.youtube.com/watch?v=zmYqShvVDh4&amp;feature=results_main&amp;playnext=1&amp;list=PL6879A8466C44A5D5">
CS61a: Structure and Interpretation of Computer Programs</xhtml:a> an.
Der Kurs besteht aus 44 Lektionen à je etwa 45 Minuten. Ich hab mir
die Zeit vor ein paar Monaten genommen und kann es nur
weiterempfehlen! Besonders wenn ihr, wie ich, keinen akademischen
Hintergrund habt.</xhtml:p>
<xhtml:p>Falls ihr also mehr über die folgenden Themen erfahren wollt,
dann hört Brian Harvey zu. :)</xhtml:p>
<xhtml:ul>
<xhtml:li>Funktionale Programmierung, speziell Scheme</xhtml:li>
<xhtml:li>Listen, car, cdr, caar, cadr, caar, caddr, etc. ;-)</xhtml:li>
<xhtml:li>Evaluation, REPL</xhtml:li>
<xhtml:li>Higher-order functions</xhtml:li>
<xhtml:li>Lambdas</xhtml:li>
<xhtml:li>Applicative Order Reduction vs. Normal Order Reduction</xhtml:li>
<xhtml:li>Rekursion vs. Iteration</xhtml:li>
<xhtml:li>Data Abstractions</xhtml:li>
<xhtml:li>Hierarchical Data, Trees, depth-first vs. breadth-first</xhtml:li>
<xhtml:li>Algorithmen, Landau-Notation (vor allem <xhtml:em>big O
notation</xhtml:em>)</xhtml:li>
<xhtml:li>Allgemeine Datentypen (<xhtml:em>generics</xhtml:em>)</xhtml:li>
<xhtml:li>Zustandsbehaftung und Umgebung (<xhtml:em>environment</xhtml:em>)</xhtml:li>
<xhtml:li>Nebenläufigkeit (<xhtml:em>concurrency</xhtml:em>)</xhtml:li>
</xhtml:ul>
<xhtml:p>Schaut rein!</xhtml:p>
<xhtml:iframe width="420" height="315" src="http://www.youtube.com/embed/zmYqShvVDh4" frameborder="0" allowfullscreen="" /></xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/116/2011-11-18/programmieren-lernen-mit-uc-berkeleys-structure-and-interpretation-of-computer-programs</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Fucked by PHP #1: Integer nach Boolean Cast]]></title>
    <published>2011-11-17T13:20:00+01:00</published>
    <updated>2011-11-17T13:20:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/fwR8MoSsVVQ/fucked-by-php-1-integer-nach-boolean-cast" />
    <id>http://bigwhoop.ch/artikel/115/2011-11-17/fucked-by-php-1-integer-nach-boolean-cast</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Yay, tolle neue Rubrik, denn heute hab ich wieder mal was über
PHP gelernt. Auf die schmerzhafte Art.</xhtml:p>
<xhtml:p>Kennt ihr eine solche Struktur?</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Article
{
    public function getTags() { /* ... */ }
    public function countTags() { /* ... */ }
    public function hasTags() { /* ... */ }
}
</xhtml:pre></xhtml:div>
<xhtml:p>Nun, ich neige dazu, (aus Faulheit) für die
<xhtml:code>hasTags()</xhtml:code>-Methode folgendes zu schreiben...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
public function hasTags()
{
    return (bool)$this-&gt;countTags();
}
</xhtml:pre></xhtml:div>
<xhtml:p>Das hat bisher auch wunderbar geklappt, doch heute bin ich auf
die Fresse geflogen. <xhtml:strong>Denn PHPs <xhtml:code>integer</xhtml:code> nach
<xhtml:code>bool</xhtml:code> Cast behandelt negative Zahlen als
<xhtml:code>true</xhtml:code>.</xhtml:strong> Also nur <xhtml:code>0</xhtml:code> ist
<xhtml:code>false</xhtml:code>, alle anderen Zahlen sind
<xhtml:code>true</xhtml:code><xhtml:sup>1)</xhtml:sup>. Nach meiner Logik waren postive
Zahlen <xhtml:code>true</xhtml:code>, die Null und negative Zahlen
<xhtml:code>false</xhtml:code>. Diese doofen negativen Zahlen...</xhtml:p>
<xhtml:p>Zur Erklärung: Da meine <xhtml:code>countXYZ()</xhtml:code>-Methode nicht
Tags, sondern freie Sitzplätze eines Trips zählte, konnte dort auch
eine negative Zahl rauskommen (wenn der Trip bereits mehr
Passagiere hatte, als das Limit zulies (Admins dürfen überbuchen)).
Danach hat meine <xhtml:code>hasXYZ()</xhtml:code>-Methode versagt. FAIL.</xhtml:p>
<xhtml:p>Folgendes hilft:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
public function hasTags()
{
    return $this-&gt;countTags() &gt; 0;
}
</xhtml:pre></xhtml:div>
<xhtml:p>Kennt ihr Hotfixes?</xhtml:p>
<xhtml:p><xhtml:sup>1)</xhtml:sup> <xhtml:a href="http://www.php.net/manual/en/language.types.boolean.php">PHP
Manual</xhtml:a></xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/115/2011-11-17/fucked-by-php-1-integer-nach-boolean-cast</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Prozedurale vs. Funktionale Programmierung]]></title>
    <published>2011-11-17T07:00:00+01:00</published>
    <updated>2011-11-17T07:00:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/2oEO8Fib6vM/prozedurale-vs-funktionale-programmierung" />
    <id>http://bigwhoop.ch/artikel/93/2011-11-17/prozedurale-vs-funktionale-programmierung</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Für mich war Prozedur (<xhtml:em>procedure</xhtml:em>) immer ein Synonym für
Funktion (<xhtml:em>function</xhtml:em>). Und ich denke, grundsätzlich ist das
auch absolut korrekt. Der Ausdruck <xhtml:em>Funktion</xhtml:em> kommt aus der
Mathematik und dort liefert eine Funktion für eine bestimme Eingabe
immer die gleiche Ausgabe. In der Programmierung ist dies nicht
immer der Fall: Die Funktion kann äussere Einflüsse haben (z.B.
globale Variablen oder Zufallszahlen). Diese Einflüsse nennt man
die Nebenwirkung (<xhtml:em>side effects</xhtml:em>) einer Funktion. Der
Ausdruck <xhtml:em>Prozedur</xhtml:em> beschreibt im Gegensatz dazu einfach
eine Liste von Instruktionen und muss auch keinen Rückgabewert
haben.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
f1(x) = 2(x + 3)
f2(x) = 2x + 6
</xhtml:pre></xhtml:div>
<xhtml:p>Das sind zwei verschiedene Prozeduren, aber die gleiche
Funktion. Die Instruktionen, die zur Anwendung benötigt werden,
sind unterschiedlich, die Funktion ist aber dieselbe; beide
Prozeduren führen mit der selben Eingabe zum selben Ergebnis.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function f1($x) { $x += 3; $x *= 2; return $x; }
function f2($x) { $x *= 2; $x += 6; return $x; }
var_dump(f1(5) === f2(5)); // true
</xhtml:pre></xhtml:div>
<xhtml:p>Aber ihr seht schon, in vielen Programmiersprachen ist diese
Unterscheidung wässrig und kontextabhängig.</xhtml:p>
<xhtml:p>Worauf ich aber eigentlich hinaus wollte, ist, dass mich diese
Similarität stets verwirrte, wenn es um den Unterschied zwischen
funktionaler und prozeduraler Programmierung ging. Dabei geht es um
etwas weitaus Fundamentaleres: Verschiedene Programmierparadigmen.
Also Ansätze, wie man Probleme löst.</xhtml:p>
<xhtml:a id="prozedurale-programmierung" name="prozedurale-programmierung" />
<xhtml:h2>Prozedurale Programmierung</xhtml:h2>
<xhtml:p>Prozedurale Programmierung ist das, was wohl die meisten von uns
mit Programmierung in Verbindungen bringen. C, C++ und Java haben
sie bekannt gemacht - auch PHP nutzt sie.</xhtml:p>
<xhtml:p>Der Quellcode wird von oben nach unten gelesen und abgearbeitet.
Es handelt sich also um Listen von Instruktionen. Auch Klassen und
Funktionen ändern daran nichts: Es wird zwar im Quelltext
"umhergesprungen", die Instruktionen werden aber immer noch
sequenziell definiert und verarbeitet. C und Java sind also nicht
nur Objekt-orientierte, sondern auch prozedurale
Programmiersprachen.</xhtml:p>
<xhtml:p>Prozedurale Programmiersprachen sind auch immer imperative
Programmiersprachen. Sie befehlen Linie für Linie was der
Compiler/Interpreter tun soll. Diese Anweisungen oft auch den
Zustand (<xhtml:em>state</xhtml:em>) des Programmes. Zum Beispiel wird eine
Variable inkrementiert oder es werden Elemente aus einem Array
entfernt. Solche Berechnungen sind zustandsbehaftet
(<xhtml:em>stateful</xhtml:em>). Das Gegenteil dazu ist zustandslos
(<xhtml:em>stateless</xhtml:em>), doch dazu später mehr.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Imperative Programmierung beschreibt <xhtml:strong>wie</xhtml:strong> etwas
berechnet werden soll. "Gib mir alle Zahlen zwischen 1 und 100. Für
jede Zahl: Überprüfe ob sie durch 7 teilbar ist und wenn ja, zeige
sie auf dem Bildschirm an."</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Der Maschinencode, in welchen unsere Programme von
Compilern/Interpretern übersetzt werden, ist übrigens auch
prozedural.</xhtml:p>
<xhtml:a id="funktionale-programmierung" name="funktionale-programmierung" />
<xhtml:h2>Funktionale Programmierung</xhtml:h2>
<xhtml:p>In funktionalen Programmsprachen definiert man Funktionen. Ha!
Und zwar ganz im mathematischen Sinne. Das Wichtige dabei ist, dass
diese Funktionen ihre Eingabeparameter und den Zustand des
Programmes nicht verändern - es gibt also keine Nebenwirkung, das
System ist zustandslos (Um es noch etwas komplizierter zu machen:
Eine Funktion kann ihren <xhtml:em>eigenen</xhtml:em> Zustand verändert - nur
nicht den von anderen Bereichen des Programmes). Wenn <xhtml:code>a =
b</xhtml:code> ist, müssen auch <xhtml:code>f1(a) = f1(b)</xhtml:code> und
<xhtml:code>f2(a) = f2(b)</xhtml:code> sein. Dadurch sind solche
Programmiersprachen ideal wenn Nebenläufigkeit
(<xhtml:em>concurrency</xhtml:em>) erwünscht ist, da mehrere Instanzen des
Programmes unabhängig voneinander ausgeführt werden können.</xhtml:p>
<xhtml:p>Wenn ich hier in der Theorie von funktionaler Programmierung
schwadroniere, meine ich rein (<xhtml:em>pure</xhtml:em>) funktionale
Programmierung. Viele Programmiersprachen sind zwar funktional,
aber nicht nur (<xhtml:em>impure</xhtml:em>). Das liegt daran, dass z.B. das
Ausgeben von Text an <xhtml:code>STDOUT</xhtml:code> bereits <xhtml:em>stateful</xhtml:em>,
bzw. imperativ ist. Oder anders gesagt: Die Funktion
<xhtml:code>print</xhtml:code> hat Nebenwirkung.</xhtml:p>
<xhtml:p>Ach ja, natürlich können Funktionen andere Funktionen aufrufen;
auch sich selbst. Rekursion ist sogar extrem wichtig und präsent in
der funktionalen Programmierung. Denn so wird zum Beispiel
Iteration gelöst. Eine Liste (ein Array in PHP Jargon) wird an eine
Funktion übergeben, die nimmt sich das erste Element und übergibt
den Rest der Liste wieder an sich selber. Wenn sie eine leere Liste
erhält, hört sie auf.</xhtml:p>
<xhtml:p>Als Programmierer schreibt man also Funktionen. Das
Hauptprogramm an sich ist eigentlich auch eine Funktion, die dann
andere Funktionen aufruft.</xhtml:p>
<xhtml:p>Rein funktionale Programmiersprachen sind auch immer deklarative
Programmiersprachen.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Deklarative Programmierung beschreibt <xhtml:strong>was</xhtml:strong>
berechnet werden soll. SQL ist eine deklarative Sprache: Man
beschreibt was man als Resultat erhalten möchte, den Lösungsweg
sucht die Programmiersprache selbstständig. "Ich brauche alle
Zahlen zwischen 1 und 100, die durch 7 teilbar sind."</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Da Funktionen ein Mittel der Mathematik sind, sind funktionale
Programmiersprachen in akademischen Kreisen sehr beliebt und weit
verbreitet. Bekannte Beispiele sind <xhtml:em>Haskell</xhtml:em>, <xhtml:em>LISP</xhtml:em>
(bzw. seine verschiedenen Dialekte wie <xhtml:em>Scheme</xhtml:em> oder
<xhtml:em>CommonLisp</xhtml:em>) oder <xhtml:em>Erlang</xhtml:em>. Zur Zeit kommen auch
einige Programmiersprachen in Mode, die mehrere
Programmierparadigmen vereinen. So ist <xhtml:em>Scala</xhtml:em> z.B. eine
sowohl funktionale, als auch objekt-orientierte Programmiersprache.
Oder dann gibt es <xhtml:em>Clojure</xhtml:em>, was ein LISP-Dialekt ist, der
in der Java Virtual Machine (JVM) läuft.</xhtml:p>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h2>Fazit</xhtml:h2>
<xhtml:p>Ich hoffe ich konnte einen kurzen Überblick über funktionale
Programmierung verschaffen. Zur Zeit versuche ich mich in dieser zu
vertiefen, da ich mir dadurch ganz neue Denkansätze erhoffe, wie
man Probleme lösen kann.</xhtml:p>
<xhtml:p>Ich freue mich über Kommentare! :)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/93/2011-11-17/prozedurale-vs-funktionale-programmierung</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wie das kollektive Wissen trügt]]></title>
    <published>2011-11-14T12:18:00+01:00</published>
    <updated>2011-11-14T12:18:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/pvfT8QnhOPQ/wie-das-kollektive-wissen-truegt" />
    <id>http://bigwhoop.ch/artikel/41/2011-11-14/wie-das-kollektive-wissen-truegt</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Manchmal, wenn ich mich so durch die Tech-Szene (Blogs, <xhtml:a href="http://news.ycombinator.com/">Hacker News</xhtml:a>, <xhtml:a href="http://stackoverflow.com/">StackOverflow</xhtml:a>, etc.) lese, kriege
ich Zweifel an meinen beruflichen Fähigkeiten. Nicht im Sinne von
<xhtml:em>Du kannst ja nix!</xhtml:em>, sondern eher à la <xhtml:em>Das solltest du
doch auch wissen!</xhtml:em>.</xhtml:p>
<xhtml:p>Wie ausgeprägt diese Zweifel sind, hängt von diversen Faktoren
ab:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>Wie offensichtlich erscheint mir das Wissen?</xhtml:strong>
Wie konnte ich das all die Jahre übersehen?</xhtml:li>
<xhtml:li><xhtml:strong>Wie wichtig erscheint mir das Wissen?</xhtml:strong> Das
sollte ja wirklich jeder wissen, der XYZ macht.</xhtml:li>
<xhtml:li><xhtml:strong>Wie nah ist das Wissen an meiner täglichen
Arbeit?</xhtml:strong> Wow, das verändert ja meine Vorgehensweise.</xhtml:li>
<xhtml:li><xhtml:strong>Wer teilt das Wissen?</xhtml:strong> Der ist 16 und weiss
das?</xhtml:li>
<xhtml:li><xhtml:strong>Wie ist mein Gemütszustand allgemein?</xhtml:strong> Heute
hat eh nicht so viel geklappt...</xhtml:li>
</xhtml:ul>
<xhtml:p>Natürlich gibt es solche Unsicherheiten auch in anderen
Bereichen meines Lebens. Dort werden sie aber nicht so sichtbar, da
ich viel weniger Vergleichswerte habe. Kommunikation ist in diesen
Bereichen auf viel kleinere Gruppen, meist sogar auf von Angesicht
zu Angesicht, beschränkt.</xhtml:p>
<xhtml:p>Beim Durchforsten des Internets entsteht viel einfacher ein
1:n-Gefühl (diesen Begriff hab ich jetzt grad für alle Nerds
erfunden), als im "realen Leben". Man sitzt alleine vor dem
Bildschirm und blickt ins Gedächtnis der Menschheit. Und genau dort
liegt der Punkt: <xhtml:strong>Es ist nicht eine Person, die all dieses
Wissen besitzt.</xhtml:strong> Es ist ein kollektives Wissen - von vielen
Individuen.</xhtml:p>
<xhtml:p>Aber: <xhtml:strong>Man sollte sein Wissen nicht mit dem eines
Kollektivs vergleichen</xhtml:strong>, das kann nicht glücklich machen.
Man sollte viel eher versuchen, <xhtml:strong>all dieses Wissen
aufzunehmen und davon zu profitieren</xhtml:strong>. Es wird immer Leute
geben, die mehr wissen, klüger und besser sind als man selbst. Deal
with it. :)</xhtml:p>
<xhtml:p>Übrigens sollte man sich auch nicht schämen sein Wissen zu
teilen. Irgendjemandem wird es immer helfen, auch wenn man noch so
unsicher ist. Im schlimmsten Fall wird man korrigiert - und lernt
wieder dazu!</xhtml:p>
<xhtml:p>PS: Ich hab keine Ahnung ob <xhtml:em>kollektives Wissen</xhtml:em> der
richtige Begriff ist. Vielleicht geht es hier auch um
Schwarmintelligenz oder das kollektives Gedächtnis. Spielt aber
eigentlich keine Rolle. Sorry an alle Wissensforscher da draussen.
;-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/41/2011-11-14/wie-das-kollektive-wissen-truegt</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PHP Missverständnis #1: Objekte werden per Referenz übergeben]]></title>
    <published>2011-11-07T11:39:00+01:00</published>
    <updated>2011-11-07T11:39:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/w-f2pO1jsu8/php-missverstaendnis-1-objekte-werden-per-referenz-uebergeben" />
    <id>http://bigwhoop.ch/artikel/113/2011-11-07/php-missverstaendnis-1-objekte-werden-per-referenz-uebergeben</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Hört man oft, stimmt so aber nicht: <xhtml:strong>In PHP werden
Objekte nicht per Referenz übergeben.</xhtml:strong></xhtml:p>
<xhtml:p>Was ist eine Referenz? Eine Referenz ist, wenn zwei Bezeichner
(oder Variablennamen) auf den selben Daten-Container zeigen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = 'foo';
$b = 'bar';
// +---+-------+
// | a | 'foo' |
// +---+-------+
// | b | 'bar' |
// +---+-------+

$a = 'foo';
$b = &amp;$a;
// +---+-------+
// | a | 'foo' |
// | b |       |
// +---+-------+
</xhtml:pre></xhtml:div>
<xhtml:p>Wenn wir in PHP ein Objekt erstellen, wird <xhtml:strong>in der
Variable nicht das Objekt, sondern ein Verweis auf das
Objekt</xhtml:strong> gespeichert.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = new stdClass;
$b = new stdClass;
// +---+-----------------------------+
// | a | &lt;Verweis auf Objekt #10000&gt; |
// +---+-----------------------------+
// | b | &lt;Verweis auf Objekt #10001&gt; |
// +---+-----------------------------+
</xhtml:pre></xhtml:div>
<xhtml:p>Wenn wir diese Variable danach in unserem Code umherschieben
(z.B. an eine Funktion übergeben), wird folglich auch nicht das
Objekt an sich, sondern der Verweis darauf, übergeben. Und solange
wir die Variable nicht explizit als Referenz übergeben, wird der
Verweis - wie skalare Variablen auch -
<xhtml:strong>kopiert</xhtml:strong>.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = new stdClass;
$b = $a;
// +---+-----------------------------+
// | a | &lt;Verweis auf Objekt #10000&gt; |
// +---+-----------------------------+
// | b | &lt;Verweis auf Objekt #10000&gt; |
// +---+-----------------------------+

$a = new stdClass;
$b = &amp;$a;
// +---+-----------------------------+
// | a | &lt;Verweis auf Objekt #10000&gt; |
// | b |                             |
// +---+-----------------------------+
</xhtml:pre></xhtml:div>
<xhtml:p>Oder als Code-Beispiel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function byValue($b) {
    $b = new stdClass();
    $b-&gt;name = 'Fritz';
}

function byRef(&amp;$b) {
    $b = new stdClass();
    $b-&gt;name = 'Fritz';
}

$a = new stdClass;
$a-&gt;name = 'Phil';

byValue($a);
echo $a-&gt;name; // Phil

byRef($a);
echo $a-&gt;name; // Fritz
</xhtml:pre></xhtml:div>
<xhtml:p>Solange man keine obskuren Dinge programmiert, dürfte dieser
Unterschied aber egal sein. Referenzen von Objekten sind eh böse;
da kommt der Garbage Collector ziemlich ins Schnaufen. ;-)</xhtml:p>
<xhtml:p><xhtml:strong>Anmerkung:</xhtml:strong> Ich habe mich gerade gefragt, was
die korrekte Übersetzung von <xhtml:em>pass BY reference</xhtml:em> ist?!
<xhtml:em>Per Referenz</xhtml:em>? <xhtml:em>Als Referenz</xhtml:em>? <xhtml:em>Durch
Referenz</xhtml:em>? :S</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/113/2011-11-07/php-missverstaendnis-1-objekte-werden-per-referenz-uebergeben</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wieso nutzen wir eigentlich das Hexadezimalsystem?]]></title>
    <published>2011-11-04T09:10:00+01:00</published>
    <updated>2011-11-04T09:10:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/9t8ZSDBMHnU/wieso-nutzen-wir-eigentlich-das-hexadezimalsystem" />
    <id>http://bigwhoop.ch/artikel/111/2011-11-04/wieso-nutzen-wir-eigentlich-das-hexadezimalsystem</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Zugegeben, die Frage scheint relativ offensichtlich. Doch ist
sie das auch? Es gibt gute Gründe wieso wir das
<xhtml:strong>Hexadezimalsystem (Basis 16)</xhtml:strong> nutzen. Zuerst müssen
wir uns aber bewusst sein, dass der Computer und der Mensch nicht
im selben Zahlensystem rechnen.</xhtml:p>
<xhtml:ul>
<xhtml:li>Der <xhtml:strong>Mensch</xhtml:strong> rechnet im <xhtml:strong>Dezimalsystem
(Basis 10)</xhtml:strong></xhtml:li>
<xhtml:li>Der <xhtml:strong>Computer</xhtml:strong> rechnet im <xhtml:strong>Binärsystem
(Basis 2)</xhtml:strong></xhtml:li>
</xhtml:ul>
<xhtml:p>Doch wieso tut er das? Nun, binäre Arithmetik ist viel einfacher
als die von uns gewohnte dezimale. Damit ist sowas wie Addition
oder Multiplikation gemeint. Für uns Menschen trifft diese Aussage
vermutlich nicht zu, da eine Binärzahl so viele Stellen hat und wir
sie uns deshalb kaum merken können und wir viel schreiben müssen.
Für den Computer spielt das aber keine Rolle. Und durch die
Einfachkeit ist er so verdammt schnell.</xhtml:p>
<xhtml:p>Binäre Zahlen bieten auch andere nette Nebeneffekte: Zum
Beispiel kann bei einer Binärzahl direkt an der 1. Stelle abgelesen
werden, ob sie gerade (1. Stelle = <xhtml:code>0</xhtml:code>) oder ungerade
(1. Stelle = <xhtml:code>1</xhtml:code>) ist. Am späteren Beispiel werdet ihr
das gut erkennen können.</xhtml:p>
<xhtml:p>Doch wieso brauchen wir dann noch andere Zahlensysteme? Bevor
wir die Frage beantworten, schauen wir uns diese Zahlensysteme doch
erst mal an.</xhtml:p>
<xhtml:a id="zahlensysteme" name="zahlensysteme" />
<xhtml:h2>Zahlensysteme</xhtml:h2>
<xhtml:p>Wie ist die Dezimalzahl <xhtml:code>14955</xhtml:code> eigentlich aufgebaut?
Und wie schaut sie umgerechnet in anderen Zahlensystemen aus.</xhtml:p>
<xhtml:a id="dezimalsystem" name="dezimalsystem" />
<xhtml:h3>Dezimalsystem</xhtml:h3>
<xhtml:ul>
<xhtml:li>Basis / Anzahl möglicher Zeichen pro Stelle:
<xhtml:code>10</xhtml:code></xhtml:li>
<xhtml:li>Mögliche Zeichen pro Stelle: <xhtml:code>0</xhtml:code>, <xhtml:code>1</xhtml:code>,
<xhtml:code>2</xhtml:code>, <xhtml:code>3</xhtml:code>, <xhtml:code>4</xhtml:code>, <xhtml:code>5</xhtml:code>,
<xhtml:code>6</xhtml:code>, <xhtml:code>7</xhtml:code>, <xhtml:code>8</xhtml:code>, <xhtml:code>9</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/111/dec.png" alt="Dezimalsystem" /></xhtml:p>
<xhtml:a id="binaersystem" name="binaersystem" />
<xhtml:h3>Binärsystem</xhtml:h3>
<xhtml:ul>
<xhtml:li>Basis / Anzahl möglicher Zeichen pro Stelle:
<xhtml:code>2</xhtml:code></xhtml:li>
<xhtml:li>Mögliche Zeichen pro Stelle: <xhtml:code>0</xhtml:code>,
<xhtml:code>1</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/111/bin.png" alt="Binärsystem" /></xhtml:p>
<xhtml:a id="oktalsystem" name="oktalsystem" />
<xhtml:h3>Oktalsystem</xhtml:h3>
<xhtml:ul>
<xhtml:li>Basis / Anzahl möglicher Zeichen pro Stelle:
<xhtml:code>8</xhtml:code></xhtml:li>
<xhtml:li>Mögliche Zeichen pro Stelle: <xhtml:code>0</xhtml:code>, <xhtml:code>1</xhtml:code>,
<xhtml:code>2</xhtml:code>, <xhtml:code>3</xhtml:code>, <xhtml:code>4</xhtml:code>, <xhtml:code>5</xhtml:code>,
<xhtml:code>6</xhtml:code>, <xhtml:code>7</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/111/oct.png" alt="Oktalsystem" /></xhtml:p>
<xhtml:a id="hexadezimalsystem" name="hexadezimalsystem" />
<xhtml:h3>Hexadezimalsystem</xhtml:h3>
<xhtml:ul>
<xhtml:li>Basis / Anzahl möglicher Zeichen pro Stelle:
<xhtml:code>16</xhtml:code></xhtml:li>
<xhtml:li>Mögliche Zeichen pro Stelle: <xhtml:code>0</xhtml:code>, <xhtml:code>1</xhtml:code>,
<xhtml:code>2</xhtml:code>, <xhtml:code>3</xhtml:code>, <xhtml:code>4</xhtml:code>, <xhtml:code>5</xhtml:code>,
<xhtml:code>6</xhtml:code>, <xhtml:code>7</xhtml:code>, <xhtml:code>8</xhtml:code>, <xhtml:code>9</xhtml:code>,
<xhtml:code>A</xhtml:code>, <xhtml:code>B</xhtml:code>, <xhtml:code>C</xhtml:code>, <xhtml:code>D</xhtml:code>,
<xhtml:code>E</xhtml:code>, <xhtml:code>F</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/111/hex.png" alt="Hexadezimalsystem" /></xhtml:p>
<xhtml:a id="soe-maetschik-numbr" name="soe-maetschik-numbr" />
<xhtml:h2>Sö Mätschik Numbr</xhtml:h2>
<xhtml:p>So, nun überlegen wir mal woran uns die binäre Repräsentation
erinnert. Richtig, an den Arbeitsspeicher des Computers. Und womit
arbeiten wir da als Programmierer normalerweise? Mit Bits oder
Bytes? Wieder richtig, mit Bytes. Und wieviele Bits hat ein Byte?
<xhtml:strong>Höre ich 8?</xhtml:strong> Korrekt. Und jetzt schauen wir mal, ob
diese Zahl in unseren Zahlensystemen eine besondere Bedeutung
hat.</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>Binär</xhtml:strong>: Mit 8 Stellen lassen sich 2<xhtml:sup>8</xhtml:sup>
= 256 Zahlen darstellen. 8 Stellen = 8 Bits = 1 Byte.</xhtml:li>
<xhtml:li><xhtml:strong>Dezimal</xhtml:strong>: Es gibt das Zeichen 8, das hat aber
keine besondere Bedeutung.</xhtml:li>
<xhtml:li><xhtml:strong>Oktal</xhtml:strong>: Die Basis 8 ist 2<xhtml:sup>3</xhtml:sup>.</xhtml:li>
<xhtml:li><xhtml:strong>Hexadezimal</xhtml:strong>: Die Basis 16 ist 2<xhtml:sup>4</xhtml:sup>.
Mit 2 Stellen lassen sich auch 16<xhtml:sup>2</xhtml:sup> = 256 Zahlen
darstellen.</xhtml:li>
</xhtml:ul>
<xhtml:p><xhtml:strong>Das Hexadezimalsystem passt also wunderbar um Bytes
abzubilden.</xhtml:strong> Mit einem Hexadezimalzeichen lassen sich genau
vier Binärzeichen - oder eben Bits - abbilden. Und <xhtml:strong>mit zwei
Hexadezimalzeichen deshalb genau ein Byte.</xhtml:strong></xhtml:p>
<xhtml:p>Da das Oktalsystem als Basis die 3. Potenz von 2 ist (der Basis
des Binärsystems), kann mit einem Oktalzeichen drei Binärzeichen
abgebildet werden. Da das kleinste gemeinsame Vielfach von einem
Byte und drei Bits aber bei drei Bytes (24 Bits) liegt, ist das
Oktalsystem längst nicht so komfortabel wie das Hexadezimalsystem.
Es hat aber den Vorteil, dass keine zusätzlichen Zeichen benötigt
werden. Das war besonders auf frühen Computersystem nützlich.
Ausserdem speicherten diese System <xhtml:a href="http://de.wikipedia.org/wiki/Datenwort">Datenworte</xhtml:a> auch in
12-, 24- oder 36-Bits. Heutige Systeme nutzen 16-, 32- oder
64-Bits. Und da passt das Hexadezimalsystem perfekt.</xhtml:p>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h2>Fazit</xhtml:h2>
<xhtml:p>Das alles klingt so super logisch und offensichtlich, aber die
Eleganz blendet auch und man vergisst manchmal das Geniale hinter
dem Hexadezimalsystem. Mit wenigen, übersichtlichen Zeichen lassen
sich grössere Zahlen und Zeichen abbilden. Ausserdem ist es die
perfekte Schnittstelle zwischen Binärsystem und Mensch.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/111/2011-11-04/wieso-nutzen-wir-eigentlich-das-hexadezimalsystem</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PHP wird auf 77% aller Webseiten eingesetzt]]></title>
    <published>2011-11-03T23:30:00+01:00</published>
    <updated>2011-11-03T23:30:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/Mq1TJuSzK4o/php-wird-auf-77-aller-webseiten-eingesetzt" />
    <id>http://bigwhoop.ch/artikel/112/2011-11-03/php-wird-auf-77-aller-webseiten-eingesetzt</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Laut <xhtml:a href="http://w3techs.com/technologies/overview/programming_language/all">
w3techs.com</xhtml:a> wird <xhtml:strong>PHP auf 77% aller ihnen bekannten
Webseiten eingesetzt</xhtml:strong>. An zweiter Stelle der
server-seitigen Programmiersprachen folgt, weit abgeschlagen,
<xhtml:strong>ASP.net mit 21.9%</xhtml:strong>. Am Ende der Skala sind
<xhtml:strong>Ruby (0.6%)</xhtml:strong> und <xhtml:strong>Python
(0.3%)</xhtml:strong>.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/112/stats.png" alt="Übersicht Server-seitige Programmiersprachen - November 2011" /></xhtml:p>
<xhtml:p>Gezählt wurden die Top 1 Million Webseiten, deren server-seitige
Programmiersprache von w3techs bestimmt werden konnte. Benutzt
bedeutet dabei aber nicht, dass die Webseite ausschliesslich mit
dieser Programmiersprache umgesetzt wurde, sondern das sie im
eingesetzten Stack vorkommt. Also Facebook wird z.B. bei PHP
gezählt. Eine Webseite konnte dabei also auch bei mehreren
Programmiersprachen gezählt werden. Redirects wurden, genauso wie
Subdomains, als eine Webseite gezählt. Somit wurden grosse
Webseiten wie z.B. wordpress.com nur als eins gewertet.</xhtml:p>
<xhtml:p>Wie repräsentativ diese Statistik ist, überlasse ich jedem
selber. Ich will hier keinen Glaubenskrieg vom Zaun brechen.</xhtml:p>
<xhtml:p>Für uns PHP-Programmierer ist übrigens eher die <xhtml:a href="http://w3techs.com/technologies/details/pl-php/all/all">Statistik
zu PHP</xhtml:a> interessant. So wird <xhtml:strong>PHP 5 von 93.3%</xhtml:strong>
und <xhtml:strong>PHP 4 von immerhin 6.7%</xhtml:strong> eingesetzt. Spannend
ist auch, dass der PHP Trend immer noch nach oben zeigt. So nutzten
im <xhtml:strong>November 2010 rund 75%</xhtml:strong> der Top 1'000'000
Webseiten PHP (knapp <xhtml:strong>2.7% weniger als im November
2011</xhtml:strong>).</xhtml:p>
<xhtml:p>(via <xhtml:a href="https://plus.google.com/104059770182664001692/posts/SBbcaaes3V9">Pierre
Joye</xhtml:a>)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/112/2011-11-03/php-wird-auf-77-aller-webseiten-eingesetzt</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[1 = 0.9999...]]></title>
    <published>2011-10-28T22:32:00+02:00</published>
    <updated>2011-10-28T22:32:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/LdOn7oO3SsA/1-09999" />
    <id>http://bigwhoop.ch/artikel/109/2011-10-28/1-09999</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Wusset ihr, dass <xhtml:code>1</xhtml:code> und <xhtml:code>0.9999...</xhtml:code> die
selbe Zahl sind? Hier der Beweis:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
  x = 0.9999...        | *10
10x = 9.9999...        | -x
 9x = 9                | /9
  x = 1
</xhtml:pre></xhtml:div>
<xhtml:p>... oder ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
    x = 1              | /3
x / 3 = 0.3333...      | *3
    x = 0.9999...
</xhtml:pre></xhtml:div>
<xhtml:p>Yay, Mathematik! :)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/109/2011-10-28/1-09999</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wenn das Bett zusammenkracht]]></title>
    <published>2011-10-27T12:39:00+02:00</published>
    <updated>2011-10-27T12:39:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/Zf4cOU3F9tA/wenn-das-bett-zusammenkracht" />
    <id>http://bigwhoop.ch/artikel/108/2011-10-27/wenn-das-bett-zusammenkracht</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Als ich vor ein paar Jahren bei den Eltern auszog, kaufte ich
mir eine teure Matratze und teure Lattenroste. Auf den Bettrahmen
verzichtet ich stets. Mittlerweile wohne ich mit meiner Freundin
zusammen und da Frauen gerne ein hübsches Schlafzimmer haben,
machten wir uns auf die Suche nach einem Bett. Die Suche dauerte
lange und war erfolglos. Wir entschieden uns deshalb dazu, bei IKEA
ein relativ billiges Bett zu kaufen und mit dem teuren Modell bis
zum nächsten, grossen Umzug zu warten.</xhtml:p>
<xhtml:p>Überraschung nach dem Zusammenbau: Meine super-duper Lattenroste
waren zu schmal für das Bettgestell. Und scheinbar war ich nicht
der Einzige mit dem Problem; Betten von IKEA sind unbrauchbar
genormt. Jedenfalls das MALM.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/108/malm.png" alt="IKEA Malm Bett" /></xhtml:p>
<xhtml:p>Nachdem ich <xhtml:a href="http://www.guenstig-schnaeppchen.de/allgemein/beim-ikea-malm-bett-kracht-der-lattenrost-runter/">
breitere Metallleisten</xhtml:a> gekauft und montiert hatte, hielt der
Rost. Ein Bett werde ich mir bei IKEA aber nicht mehr kaufen. Zu
mühsam.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/108/2011-10-27/wenn-das-bett-zusammenkracht</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Für PHP gibt's endlich eine moderne Bildberarbeitungsbibliothek]]></title>
    <published>2011-10-22T08:30:00+02:00</published>
    <updated>2011-10-22T08:30:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/HM8mywbRgKQ/fuer-php-gibts-endlich-eine-moderne-bildberarbeitungsbibliothek" />
    <id>http://bigwhoop.ch/artikel/107/2011-10-22/fuer-php-gibts-endlich-eine-moderne-bildberarbeitungsbibliothek</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Endlich möchte man schreien: Mit <xhtml:a href="https://github.com/avalanche123/Imagine/">Imagine</xhtml:a> hat <xhtml:a href="https://github.com/avalanche123">Bulat Shakirzyanov</xhtml:a> ein Vakum
gefüllt und eine saubere, moderne Bildbearbeitungsbibliothek in PHP
5.3 geschrieben. Es gibt eine übersichtliche Dokumentation, Unit
Tests und reichlich Interesse und Partizipation auf <xhtml:a href="https://github.com/avalanche123/Imagine/">GitHub</xhtml:a>.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/107/imagine.png" alt="Imagine Logo" title="Imagine Logo" /></xhtml:p>
<xhtml:p>Sogar das Logo ist wunderschön... ;-)</xhtml:p>
<xhtml:p>Also ich weiss was ich in Zukunft einsetzen werde, falls ich
Bilder bearbeiten muss.<xhtml:br />
Jetzt muss sich nur noch ein Experte finden, der sowas für
PDF-Erstellung baut.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/107/2011-10-22/fuer-php-gibts-endlich-eine-moderne-bildberarbeitungsbibliothek</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Ein Ausflug in die Kryptologie]]></title>
    <published>2011-10-20T22:32:00+02:00</published>
    <updated>2011-10-20T22:32:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/b0rF-M6RxjY/ein-ausflug-in-die-kryptologie" />
    <id>http://bigwhoop.ch/artikel/105/2011-10-20/ein-ausflug-in-die-kryptologie</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Letzte Woche musst ich zum ersten Mal in meinem Programmierertum
Daten ver- und auch wieder entschlüsseln. Bisher kam ich nur mit
Einwegfunktionen zur Berechnung von Prüfsummen oder zum Hashen von
Passwörtern in Berührung. Hier ein Abriss meiner Entdeckungen.</xhtml:p>
<xhtml:a id="klaeren-wir-ein-paar-begriffe" name="klaeren-wir-ein-paar-begriffe" />
<xhtml:h2>Klären wir ein paar Begriffe</xhtml:h2>
<xhtml:p>Die <xhtml:strong>Kryptologie</xhtml:strong> ist die Wissenschaft, die sich
mit der Sicherheit von Informationen beschäftigt. Darunter fallen
aber nicht nur klassiche Themen wie Geheimschriften,
Verschlüsselungsverfahren, sondern auch elektronische Wahlen oder
z.B. BitCoins. Die Kryptologie ist unterteilt in die zwei
Fachgebiete <xhtml:strong>Kryptografie</xhtml:strong> (<xhtml:em>Wie schütze ich
Informationen? Was ist wann sicher?</xhtml:em>) und Kryptanalyse (<xhtml:em>Wie
gewinne ich Informationen aus verschlüsselten Daten? Wie sicher ist
ein Algorithmus?</xhtml:em>).</xhtml:p>
<xhtml:p>Ein <xhtml:strong>Algorithmus</xhtml:strong> (<xhtml:em>algorithm</xhtml:em>) ist ein
klar definierter Ablauf von immer gleichen Handlungen. Meist um ein
Problem zu lösen. Yay, solche Definitionen machen Spass, nicht?!
Ein kryptografischer Algorithmus, auch <xhtml:strong>Chiffre</xhtml:strong>
(<xhtml:em>cipher</xhtml:em>) wird verwendet, um <xhtml:strong>Klartext</xhtml:strong>
(<xhtml:em>plaintext</xhtml:em>) mit Hilfe eines geheimen
<xhtml:strong>Schlüssels</xhtml:strong> (<xhtml:em>key</xhtml:em>) zu verschlüsseln, bzw.
den daraus resultierende <xhtml:strong>Geheimtext/Chiffretext</xhtml:strong>
(<xhtml:em>ciphertext</xhtml:em>) auch wieder zu entschlüsseln. Die
<xhtml:strong>Steganografie</xhtml:strong> (<xhtml:em>steganography</xhtml:em>) versucht im
Gegensatz zur Kryptografie nicht, die Informationen zu verdecken,
sondern die Kommunikation/den Kommunikationskanal zu verbergen. Die
beiden Verfahren lassen sich kombinieren.</xhtml:p>
<xhtml:p>Alle möglichen Schlüssel einer Chiffre werden als
<xhtml:strong>Schlüsselraum</xhtml:strong> bezeichnet; die Anzahl davon als
<xhtml:strong>Schlüsselanzahl</xhtml:strong>. Berechnet man davon den
Logarithmus zur Basis 2 (log2), erhält man die
<xhtml:strong>Schlüssellänge</xhtml:strong> (<xhtml:em>key size</xhtml:em>) in bit. Je
grösser die Schlüssellänge ist, desto sicherer kann ein Algorithmus
theoretisch sein (da es schlicht mehr Möglichkeiten gibt, um den
Geheimtext zu entschlüsseln).</xhtml:p>
<xhtml:p>Ein paar Begriffe kommen noch, da müsst ihr jetzt durch. Los
geht's...</xhtml:p>
<xhtml:a id="symmetrisch-und-asymmetrisch" name="symmetrisch-und-asymmetrisch" />
<xhtml:h2>Symmetrisch und asymmetrisch</xhtml:h2>
<xhtml:p>Chiffren lassen sich in generell unterteilen in
<xhtml:strong>asymmetrische</xhtml:strong> und <xhtml:strong>symmetrische</xhtml:strong>
Verfahren. Bei Ersterem besitzen alle Kommunikationspartner ein
eigenes <xhtml:strong>Schlüsselpaar</xhtml:strong> (<xhtml:em>key pair</xhtml:em>),
bestehend aus einem <xhtml:strong>öffentlichen Schlüssel</xhtml:strong>
(<xhtml:em>public key</xhtml:em>) und einem <xhtml:strong>geheimen Schlüssel</xhtml:strong>
(<xhtml:em>private key</xhtml:em>). Sie haben den grossen Vorteil, dass kein
geheimer Schlüssel zwischen den Partnern ausgetauscht werden muss.
Bei symmetrischen Chiffren sind die Schlüssel der kommunizierenden
Parteien entweder gleich, oder lassen sich voneinander ableiten.
Symmetrische Verfahren werden unterteilt in
<xhtml:strong>Blockchiffre</xhtml:strong> (<xhtml:em>block cipher</xhtml:em>) und
<xhtml:strong>Stromchiffre</xhtml:strong> (<xhtml:em>stream cipher</xhtml:em>). Bei der
Blockverschlüsselung wird der Klartext zuerst in gleich grosse
Blöcke aufgeteilt. Hat der letzte Block nicht die korrekte Grösse,
wird er normalerweise mit z.B. Nullbytes aufgefüllt. Dieser Vorgang
nennt sich <xhtml:strong>Padding</xhtml:strong>. Danach werden alle Blöcke
einzeln verschlüsselt und am Schluss aneinandergereiht. Die
<xhtml:strong>Blocklänge</xhtml:strong> (<xhtml:em>block size</xhtml:em>) wird in bit
angegeben und sagt aus, wie lang jeder einzelne Block ist. Grössere
Blöcke sind sicherer, da sie die statische Analyse von einzelnen
Blöcken erschweren. Stromverschlüsselung hingegen, verschlüsselt
jedes Bit, Byte oder Zeichen (je nach Implementation) einzeln.
Dabei verändert sich der Schlüssel nach jedem solchen Vorgang.
Deshalb erhält man für eine Klartext/Schlüssel-Kombination stets
einen anderen Geheimtext.</xhtml:p>
<xhtml:p>Gleich haben wir es! Nochmals durchatmen. Und los!</xhtml:p>
<xhtml:a id="modes-of-operation" name="modes-of-operation" />
<xhtml:h2>Modes of Operation</xhtml:h2>
<xhtml:p>Bei Blockchiffren wird der Algorithmus mit Hilfe
<xhtml:strong>kryptographischer Modi</xhtml:strong> (<xhtml:em>modes of
operation</xhtml:em>) auf die aufgeteilten Blöcke angewandt. Diese Modi
sind unabhängig von der eingesetzten Chiffre. Damit der
Verschlüsselungsprozess Zufälligkeit enthält, benötigen einige
dieser Modi einen sogenannten
<xhtml:strong>Initialisierungsvektor</xhtml:strong> (<xhtml:em>initialization
vector</xhtml:em>). Man kann sich diesen wie das Salz beim Hashing
vorstellen. Der IV sorgt dafür, dass der Chiffretext bei gleicher
Klartext/Schlüssel-Kombination nie gleich ist. Dadurch wird
statische Analyse vorgebeugt. Wie das Salz muss auch der IV immer
mitgespeichert werden, da Ver- und Entschlüsselung den selben
benötigen. Er muss wie das Salz nicht geschützt werden.</xhtml:p>
<xhtml:p>Werfen wir einen Blick auf drei weitverbreitete Modi.</xhtml:p>
<xhtml:a id="ecb-electronic-code-book" name="ecb-electronic-code-book" />
<xhtml:h3>ECB - Electronic Code Book</xhtml:h3>
<xhtml:p><xhtml:img src="http://upload.wikimedia.org/wikipedia/commons/c/c4/Ecb_encryption.png" alt="ECB" /></xhtml:p>
<xhtml:p>ECB ist ziemlich einfach: Es wird jeder Block einzeln mit dem
Schlüssel verschlüsselt. Das Problem ist, dass man so für jeden
Klartext immer den selben Chiffretext erhält. Da die Blöcke in
keiner Abhängigkeit stehen, lassen sie sich verschieben, ohne das
dies bemerkt werden kann. ECB sollte deshalb nur für kleine,
zufällige Daten verwendet werden. Je grösser die Daten, desto mehr
Blöcke, desto einfacher die statische Analyse, desto unsicherer die
Verschlüsselung mit ECB.</xhtml:p>
<xhtml:a id="cbc-cipher-block-chaining" name="cbc-cipher-block-chaining" />
<xhtml:h3>CBC – Cipher Block Chaining</xhtml:h3>
<xhtml:p><xhtml:img src="http://upload.wikimedia.org/wikipedia/commons/d/d3/Cbc_encryption.png" alt="CBC" /></xhtml:p>
<xhtml:p>Bei CBC wird für die Verschlüsselung eines Blockes immer der
vorangehende, verschlüsselte Block zusätzlich eingebunden. Für den
ersten Block wird ein IV genutzt. Dadurch erhält der Chiffretext
Zufälligkeit und ist bei gleicher Klartext/Schlüssel-Kombination
nie gleich. Da ein Block stets von vorherigen Block abhängt, werden
Bitfehler weitergereicht und alle Folgeblöcke affektiert.
Allerdings ist CBS selbstsyncronisiert. D.h., falls ein kompletter
Block verloren geht, kann die Entschlüsselung trotzdem fortgesetzt
werden. CBC ist wesentlich sicherer als ECB und kann als Standard
für "normale" Verschlüsselung von Dokumenten, Videos, etc.
angesehen werden.</xhtml:p>
<xhtml:a id="ofb-output-feedback" name="ofb-output-feedback" />
<xhtml:h3>OFB - Output Feedback</xhtml:h3>
<xhtml:p><xhtml:img src="http://upload.wikimedia.org/wikipedia/commons/a/a9/Ofb_encryption.png" alt="OFB" /></xhtml:p>
<xhtml:p>Bei OFB ist der Startpunkt ein IV. Dieser wird mit dem Schlüssel
verschlüsselt, wobei dieses Resultat a) als als "IV" für den
nächsten Block gilt und b) XOR mit dem Klartext verknüpft den
Chiffretext ergibt. Da die eingesetzte Chiffre nicht vom Klartext
abhängig ist, lassen sich die ganzen Bithaufen, die anschliessend
blockweise mit den Klartextblöcken XOR verknüpft werden, bereits im
Voraus berechnen. Das kann ein grosser Vorteil bei zeitintensiven
Verschlüsselungen sein. Anzumerken ist noch, dass Ver- und
Entschlüsselung genau gleich funktionieren und OFB auch als
Stromverschlüsselung eingesetzt werden kann.</xhtml:p>
<xhtml:a id="" name="" /><xhtml:a id="gaengige-chiffren" name="gaengige-chiffren" />
<xhtml:h2>Gängige Chiffren</xhtml:h2>
<xhtml:p>Schauen wir uns jetzt ein paar gängige symmetrische Chiffren an.
Auf asymmetrische Verfahren werde ich in diesem Artikel nicht
weiter eingehen. Google ist euer Freund.</xhtml:p>
<xhtml:table>
<xhtml:thead>
<xhtml:tr>
<xhtml:th>Name</xhtml:th>
<xhtml:th>Beschreibung</xhtml:th>
<xhtml:th>Sicher?</xhtml:th>
<xhtml:th>Schlüssellänge</xhtml:th>
<xhtml:th>Blocklänge</xhtml:th>
<xhtml:th>Runden</xhtml:th>
</xhtml:tr>
</xhtml:thead>
<xhtml:tbody>
<xhtml:tr>
<xhtml:td>DES (Data Encryption Standard)</xhtml:td>
<xhtml:td>alt, langsam</xhtml:td>
<xhtml:td>nein</xhtml:td>
<xhtml:td>56 bit</xhtml:td>
<xhtml:td>64 bit</xhtml:td>
<xhtml:td>16</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>3DES (Triple DES)</xhtml:td>
<xhtml:td>drei Instanzen von DES hintereinander, drei Mal so langsam</xhtml:td>
<xhtml:td>ja</xhtml:td>
<xhtml:td>112 bit</xhtml:td>
<xhtml:td>64 bit</xhtml:td>
<xhtml:td>16</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>AES (Advanced Encryption Standard)</xhtml:td>
<xhtml:td>Eigentlich Rijndael, Gewinner beim Wettbewerb für AES, Standard
bei der US Regierung</xhtml:td>
<xhtml:td>ja</xhtml:td>
<xhtml:td>128/192/256 bit</xhtml:td>
<xhtml:td>128 bit</xhtml:td>
<xhtml:td>10/12/14</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Blowfish</xhtml:td>
<xhtml:td>public domain</xhtml:td>
<xhtml:td>ja</xhtml:td>
<xhtml:td>32 - 448 bit</xhtml:td>
<xhtml:td>64 bit</xhtml:td>
<xhtml:td>16</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Twofish</xhtml:td>
<xhtml:td>Nachfolger von Blowfish, nebst Rijndael Finalist bei AES,
public domain</xhtml:td>
<xhtml:td>ja</xhtml:td>
<xhtml:td>128/192/256 bit</xhtml:td>
<xhtml:td>128 bit</xhtml:td>
<xhtml:td>16</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:p>Daneben gibt es noch etliche weitere Chiffren, die den Rahmen
dieses Artikels aber sprengen würden. <xhtml:strong>Meine Empfehlung ist,
entweder AES oder Twofish zu benutzen.</xhtml:strong> Was ihr nicht tun
solltet, ist, unbekannte oder gar eigene Chiffren einzusetzen.
Algorithmen müssen von einer breiten Öffentlichkeit begutachtet und
getestet worden sein. Sie müssen sich bewähren. Und Fehler
geschehen nun mal schnell.</xhtml:p>
<xhtml:a id="ein-praxisbeispiel" name="ein-praxisbeispiel" />
<xhtml:h2>Ein Praxisbeispiel</xhtml:h2>
<xhtml:p>Ein Beispiel in PHP 5.3+ mit AES-256 und OFB. Ich sollte wohl
erwähnen, dass ich keinerlei Verantwortung übernehme, wenn ihr mit
diesem Code-Schnippsel Daten verschlüsselt. Es gibt bestimmt auch
komplette <xhtml:code>mcrypt</xhtml:code>-Klassen für PHP. Einfach mal bei
GitHub suchen... :)</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
namespace BigWhoop\Crypto;

class Cipher
{
    const PADDING_CONTROL_CHAR = "\1";

    /**
     * @var string|null
     */
    private $cipher = null;

    /**
     * @var string|null
     */
    private $mode = null;

    /**
     * @var resource
     */
    private $handle = null;


    /**
     * @param string $cipher
     * @param string $mode
     */
    public function __construct($cipher, $mode)
    {
        $this-&gt;cipher = $cipher;
        $this-&gt;mode   = $mode;
        $this-&gt;handle = mcrypt_module_open($cipher, '', $mode, '');
    }


    public function __destruct()
    {
        mcrypt_module_close($this-&gt;handle);
    }


    /**
     * @param string $passphrase
     * @param string $iv
     * @return Cipher
     */
    public function init($passphrase, $iv)
    {
        mcrypt_generic_init($this-&gt;handle, $passphrase, $iv);
        return $this;
    }


    /**
     * @return Cipher
     */
    public function deinit()
    {
        mcrypt_generic_deinit($this-&gt;handle);
        return $this;
    }


    /**
     * @param string $passphrase
     * @param string $iv
     * @param string $data
     * @return string
     */
    public function encrypt($passphrase, $iv, $data)
    {
        $data .= self::PADDING_CONTROL_CHAR;

        $this-&gt;init($passphrase, $iv);
        $data = mcrypt_generic($this-&gt;handle, $data);
        $this-&gt;deinit();

        return $data;
    }


    /**
     * @param string $passphrase
     * @param string $iv
     * @param string $data
     * @return string
     */
    public function decrypt($passphrase, $iv, $data)
    {
        $this-&gt;init($passphrase, $iv);
        $data = mdecrypt_generic($this-&gt;handle, $data);
        $this-&gt;deinit();

        $data = rtrim($data);
        $data = substr($data, 0, 0 - mb_strlen(self::PADDING_CONTROL_CHAR));

        return $data;
    }


    /**
     * @return string
     */
    public function createInitializationVector()
    {
        $size = mcrypt_get_iv_size($this-&gt;cipher, $this-&gt;mode);
        return mcrypt_create_iv($size, MCRYPT_RAND);
    }
}
</xhtml:pre></xhtml:div>
<xhtml:a id="anwendung" name="anwendung" />
<xhtml:h3>Anwendung</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
use BigWhoop\Crypto\Cipher;

$cipher = new Cipher(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_OFB);

$passphrase = 'gurkensalat';
$initVector = $cipher-&gt;createInitializationVector();
$plaintext  = 'super geheimer text';

// Verschlüsseln
$ciphertext = $cipher-&gt;encrypt($passphrase, $initVector, $plaintext);

// Entschlüsseln
echo $cipher-&gt;decrypt($passphrase, $initVector, $ciphertext);
// -&gt; super geheimer text
</xhtml:pre></xhtml:div>
<xhtml:p>Ich hoffe ihr konnte was lernen. Bis demnächst!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/105/2011-10-20/ein-ausflug-in-die-kryptologie</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Mehrere MySQL Dienste parallel installieren]]></title>
    <published>2011-10-20T09:02:00+02:00</published>
    <updated>2011-10-20T09:02:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/1Ya2byOJACs/mehrere-mysql-dienste-parallel-installieren" />
    <id>http://bigwhoop.ch/artikel/106/2011-10-20/mehrere-mysql-dienste-parallel-installieren</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Master-Slave-Replikation mit MySQL lässt sich auf dem lokalen
Entwicklersystem wunderbar lösen, indem man mehrere MySQL-Dienst
parallel laufen lässt. Ich spreche von Diensten, in diesem Artikel
geht es also um Windows. Um Windows 7, um genau zu sein.</xhtml:p>
<xhtml:p>Weiter gehe ich davon aus, dass ihr MySQL bereits installiert
habt und der eine Dienst läuft.</xhtml:p>
<xhtml:p>1) Terminal als Administrator öffnen: <xhtml:code>Windows Taste</xhtml:code>
drücken, danach <xhtml:code>cmd</xhtml:code> eingeben und <xhtml:code>CTRL</xhtml:code> +
<xhtml:code>SHIFT</xhtml:code> + <xhtml:code>ENTER</xhtml:code> drücken</xhtml:p>
<xhtml:p>2) Zu MySQLs <xhtml:code>bin</xhtml:code> Verzeichnis wechseln</xhtml:p>
<xhtml:blockquote>
<xhtml:p>z.B. <xhtml:code>cd c:\Program Files\MySQL\MySQL Server
5.5\bin</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>3) Neuen Dienst installieren: <xhtml:code>mysqld --install &lt;Name
des Dienstes&gt; --defaults-file="&lt;Pfad zur
my-new.ini&gt;"</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p>z.B. <xhtml:code>mysqld --install MySQL55-Slave
--defaults-file="C:\ProgramData\MySQL\MySQL Server
5.5\my-slave.ini"</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>4) <xhtml:code>my.ini</xhtml:code> kopieren: <xhtml:code>cp "&lt;Pfad zur
my.ini&gt;" "&lt;Pfad zur my-new.ini&gt;"</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p>z.B. <xhtml:code>cp "C:\ProgramData\MySQL\MySQL Server 5.5\my.ini"
"C:\ProgramData\MySQL\MySQL Server 5.5\my-slave.ini"</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>5) <xhtml:code>my-new.ini</xhtml:code> editieren</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
[client]
port=&lt;neuer Port&gt;
...

[mysqld]
port=&lt;neuer Port&gt;
datadir="&lt;neues Verzeichnis&gt;"
...
</xhtml:pre></xhtml:div>
<xhtml:p>Zum Beispiel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
[client]
port=3307
...

[mysqld]
port=3307
datadir="C:\ProgramData\MySQL\MySQL Server 5.5\data-slave\"
...
</xhtml:pre></xhtml:div>
<xhtml:p>6) <xhtml:code>datadir</xhtml:code>-Vorlage kopieren: <xhtml:code>cp -R "&lt;Pfad
zur MySQL Installation&gt;\data&gt;" "&lt;Pfad zum neuen
'datadir'&gt;"</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:code>cp -R "C:\Program Files\MySQL\MySQL Server 5.5\data&gt;"
"C:\ProgramData\MySQL\MySQL Server 5.5\data-slave"</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>7) Neuen Dienst starten: <xhtml:code>net start &lt;Name des
Dienstes&gt;</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:code>net start MySQL55-Slave</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>8) Verbindung herstellen: <xhtml:code>mysql --defaults-file="&lt;Pfad
zur my-new.ini&gt;" -u root</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:code>mysql --defaults-file="C:\ProgramData\MySQL\MySQL Server
5.5\my-slave.ini" -u root</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>9) <xhtml:code>root</xhtml:code>-Passwort ändern: <xhtml:code>SET PASSWORD FOR
'root'@'localhost' = PASSWORD('&lt;Neues Passwort&gt;');</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:code>SET PASSWORD FOR 'root'@'localhost' =
PASSWORD('546DFSmds4slp56mBc0ijfS9');</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>10) Falls ihr eine Master-Slave-Replikation einrichten möchtet,
findet ihr <xhtml:a href="http://www.codarbyte.de/2010/12/mysql-replikation/">im Blog von
Florian Moker</xhtml:a> eine ausführliche Anleitung.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/106/2011-10-20/mehrere-mysql-dienste-parallel-installieren</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wenn der MySQL Dienst verschwindet]]></title>
    <published>2011-10-13T11:27:00+02:00</published>
    <updated>2011-10-13T11:27:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/hPEPyEBz3c4/wenn-der-mysql-dienst-verschwindet" />
    <id>http://bigwhoop.ch/artikel/104/2011-10-13/wenn-der-mysql-dienst-verschwindet</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Nach dem Start meines PCs war heute Morgen der MySQL Dienst weg.
Vermutlich weil ich seit dem letzten Neustart mit CCleaner die
Registry aufgeräumt hatte. Oder aber das Windows Update ist der
Schuldige. Egal, so lässt sich der Dienst jedenfalls wieder
herstellen...</xhtml:p>
<xhtml:p>1) Terminal als Administrator öffnen: <xhtml:code>Windows Taste</xhtml:code>
drücken, danach <xhtml:code>cmd</xhtml:code> eingeben und <xhtml:code>CTRL</xhtml:code> +
<xhtml:code>SHIFT</xhtml:code> + <xhtml:code>ENTER</xhtml:code> drücken</xhtml:p>
<xhtml:p>2) Zu MySQLs <xhtml:code>bin</xhtml:code> Verzeichnis wechseln</xhtml:p>
<xhtml:blockquote>
<xhtml:p>z.B. <xhtml:code>cd c:\Program Files\MySQL\MySQL Server
5.5\bin</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>3) Dienst installieren: <xhtml:code>mysqld --install &lt;Name des
Dienstes&gt; --defaults-file="&lt;Pfad zur my.ini&gt;"</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p>z.B. <xhtml:code>mysqld --install MySQL55
--defaults-file="C:\ProgramData\MySQL\MySQL Server
5.5\my.ini"</xhtml:code></xhtml:p>
</xhtml:blockquote>
<xhtml:p>4) Danach noch den Dienst starten: <xhtml:code>net start &lt;Name des
Dienstes&gt;</xhtml:code></xhtml:p>
<xhtml:blockquote>
<xhtml:p>z.B. <xhtml:code>net start MySQL55</xhtml:code></xhtml:p>
</xhtml:blockquote>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/104/2011-10-13/wenn-der-mysql-dienst-verschwindet</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Labyrinthe lösen mit PHP]]></title>
    <published>2011-10-09T13:20:00+02:00</published>
    <updated>2011-10-09T13:20:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/4S2s1SmUbG0/labyrinthe-loesen-mit-php" />
    <id>http://bigwhoop.ch/artikel/103/2011-10-09/labyrinthe-loesen-mit-php</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Heute werde ich eine Art vorstellen, wie man (mit PHP) einfache
2D-Labyrinthe lösen kann. Dazu werden wir den <xhtml:strong>Maze Routing
Algorithmus von C. Y. Lee</xhtml:strong> verwenden. Dieser Algorithmus
ist relativ simpel, findet garantiert einen Weg (falls es einen
gibt) - und erst noch den schnellsten. Negativ ist, dass der
Algorithmus nicht besonders schnell ist und bei grossen Labyrinthen
auch speicherintensiv werden kann.</xhtml:p>
<xhtml:a id="die-theorie" name="die-theorie" />
<xhtml:h2>Die Theorie</xhtml:h2>
<xhtml:p>Aber schauen wir uns erst mal so ein Beispiellabyrinth an. Blau
markiert den Start, das Ziel ist Gelb.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/103/maze3-big.png" alt="Beispiellabyrinth" /></xhtml:p>
<xhtml:a id="rastern" name="rastern" />
<xhtml:h3>Rastern</xhtml:h3>
<xhtml:p>Der erste Schritt besteht darin, dass Labyrinth zu rastern. Das
geht bei diesem 2D Labyrinth sehr einfach, da alle Felder (egal ob
Wand oder Weg) gleich gross sind. Wir können also ein
Koordinatensystem anwenden, wobei oben links <xhtml:code>x=0, y=0</xhtml:code>
und unten rechts <xhtml:code>x=33, y=24</xhtml:code> entspricht.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/103/maze3-grid.png" alt="Beispiellabyrinth gerastert" /></xhtml:p>
<xhtml:a id="bewerten" name="bewerten" />
<xhtml:h3>Bewerten</xhtml:h3>
<xhtml:p>Als nächstes werden wir nun, vom Startpunkt ausgehend, alle
möglichen Wege wellenförmig bewerten. Dem Startpunkt geben wir die
Wertung 0. Allen Wegfeldern die an den Startpunkt anknüpfen
erhalten die Wertung 1 (1. Welle). Alle Wegfelder die wiederum an
diese Felder anknüpfen, erhalten die Wertung 2 (2. Welle). Das tun
wir solange, bis wir das Ziel erreicht haben oder keine Felder zum
Bewerten mehr übrig sind. Tritt Letzteres ein, können wir davon
ausgehen, dass es keine Möglichkeit gibt das Labyrinth zu
lösen.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring0.png" alt="Bewertung 0" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring1.png" alt="Bewertung 1" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring2.png" alt="Bewertung 2" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring3.png" alt="Bewertung 3" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring4.png" alt="Bewertung 4" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring5.png" alt="Bewertung 5" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring6.png" alt="Bewertung 6" /> <xhtml:img src="http://bigwhoop.ch/img/articles/103/scoring7.png" alt="Bewertung 7" /></xhtml:p>
<xhtml:p>Anzumerken gilt, dass ein bereits bewertetes Feld nicht neu
bewertet werden darf. Sonst würden wir nämlich in eine
Endlosschleife kommen, da benachbarte Felder sich stetig
neubewerten würden.</xhtml:p>
<xhtml:p>Das fertig bewertete Labyrinth sieht dann so aus:</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/103/maze3-scored.png" alt="Beispiellabyrinth bewertet" /></xhtml:p>
<xhtml:p>Hier ist gut zu sehen, dass wir das Ziel erreichten, bevor alle
Felder bewertet wurden. Da der Weg über noch nicht bewertete Felder
langsamer wäre, können wir diese getrost ignorieren.</xhtml:p>
<xhtml:a id="rueckwaertssuche" name="rueckwaertssuche" />
<xhtml:h3>Rückwärtssuche</xhtml:h3>
<xhtml:p>Um den schnellsten Pfad zu finden, gehen wir jetzt - vom
Zielpunkt aus - rückwärts durch das Labyrinth. Wir schauen uns also
die Nachbarn des Zielpunktes (= <xhtml:em>Wertung 52</xhtml:em>) an und suchen
uns den Nachbarn raus, der die tiefste Wertung hat. Der Nachbar
rechts hat keine Wertung, bleibt also nur der Nachbar unten
(<xhtml:em>51</xhtml:em>). Für diesen durchforsten wir wiederum dessen Nachbarn
und finden einen weiteren Nachbarn darunter (<xhtml:em>50</xhtml:em>). Weiter
geht's mit dessen Nachbarn. Wir wählen den Nachbarn rechts davon
(<xhtml:em>49</xhtml:em>). Dies tun wir solange, bis wir den Startpunkt
(<xhtml:em>0</xhtml:em>) gefunden haben. Während unserer Rückwärtsreise merken
wir uns natürlich genau, welche Wegpunkte wir passieren.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/103/maze3-solved.png" alt="Beispiellabyrinth gelöst" /></xhtml:p>
<xhtml:p>Sind wir durch, müssen wir die Route nur noch umkehren (damit
sie vorwärts geht) und schon haben wir unseren Lösungsweg.</xhtml:p>
<xhtml:p>Wie ihr vielleicht bemerkt hat, gibt es für dieses Labyrinth
mehrere Lösungswege, die genau gleich lang sind. So könnten wir
z.B. beim Feld mit der Wertung 28 nach oben, anstatt nach links
ziehen. Für solche Fälle könnte man den Algorithmus erweitern und
einbauen, dass möglichst gerade Strecken bevorzugt werden. Sollte
nicht allzu schwierig sein! :)</xhtml:p>
<xhtml:a id="die-praxis" name="die-praxis" />
<xhtml:h2>Die Praxis</xhtml:h2>
<xhtml:p>Es braucht eigentlich nur zwei Klassen: <xhtml:code>Point</xhtml:code> und
<xhtml:code>Maze</xhtml:code>. Jeder <xhtml:code>Point</xhtml:code> hat eine X- und eine
Y-Position, einen Typ (<xhtml:em>Startpunkt</xhtml:em>, <xhtml:em>Wegpunkt</xhtml:em>,
<xhtml:em>Zielpunkt</xhtml:em> oder <xhtml:em>Wand</xhtml:em>) sowie eine Wertung
(standardmässig <xhtml:code>null</xhtml:code>). Die <xhtml:code>Maze</xhtml:code> Klasse
verwaltet ein Raster bestehend aus <xhtml:code>Point</xhtml:code>-Objekten und
bietet Methoden zum Bewerten und zur Wegfindung.</xhtml:p>
<xhtml:p><xhtml:strong>Den kompletten Source Code für die nachfolgenden Auszüge
hab ich auf <xhtml:a href="https://github.com/bigwhoop/Maze-Routing-Algorithm">GitHub</xhtml:a>
gestellt. Greift zu!</xhtml:strong></xhtml:p>
<xhtml:a id="rastern" name="rastern" />
<xhtml:h3>Rastern</xhtml:h3>
<xhtml:p>Die <xhtml:code>Maze</xhtml:code>-Klasse bietet eine Hilfsfunktion an, um
aus einem .PNG (z.B.
https://github.com/bigwhoop/Maze-Routing-Algorithm/raw/master/maze3.png)
ein Labyrinth zu erstellen. Dabei wird jeder schwarze Pixel als
Wand, jeder weisse Pixel als Weg, der blaue Pixel als Startpunkt
und der gelbe Pixel als Zielpunk angesehen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$maze = Maze::createFromImage(__DIR__ . '/maze3.png');
</xhtml:pre></xhtml:div>
<xhtml:p>Ihr könnt euch also gerne in Paint kurz euer eigenes Labyrinth
malen. :)</xhtml:p>
<xhtml:p>Aber los geht's. Betrachten wir zuerst die
<xhtml:code>findConnectingPaths()</xhtml:code> Methode. Diese findet für jeden
Punkt die benachbarten Punkte oben, links, rechts und unten, die
keine Wand sind.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
/**
 * @param Point $point
 * @return array
 */
private function findConnectingPaths(Point $point)
{
    $possiblePointTypes = array(
        Point::TYPE_START,
        Point::TYPE_PATH,
        Point::TYPE_FINISH
    );

    if (!in_array($point-&gt;getType(), $possiblePointTypes)) {
        return array();
    }

    $offsets = array(
        array('x' =&gt; -1, 'y' =&gt;  0), // left of $point
        array('x' =&gt;  0, 'y' =&gt; -1), // above $point
        array('x' =&gt;  0, 'y' =&gt;  1), // below $point
        array('x' =&gt;  1, 'y' =&gt;  0), // right of $point
    );

    $connectingPaths = array();

    foreach ($offsets as $offset) {
        // Build x/y of connecting point
        $x = $point-&gt;getX() + $offset['x'];
        $y = $point-&gt;getY() + $offset['y'];

        if (!isset($this-&gt;grid[$y])) {
            continue;
        }

        if (!isset($this-&gt;grid[$y][$x])) {
            continue;
        }

        $connectingPoint = $this-&gt;grid[$y][$x];

        if (in_array($connectingPoint-&gt;getType(), $possiblePointTypes)) {
            $connectingPaths[] = $connectingPoint;
        }
    }

    return $connectingPaths;
}
</xhtml:pre></xhtml:div>
<xhtml:p>Wir erhalten also ein Array mit <xhtml:code>Point</xhtml:code>-Objekten
zurück. Oder auch nur ein leeres Array, falls ein Punkt keine
Nachbarn hat.</xhtml:p>
<xhtml:a id="bewerten" name="bewerten" />
<xhtml:h3>Bewerten</xhtml:h3>
<xhtml:p>Die <xhtml:code>scoreGrid()</xhtml:code> Methode schnappt sich den
Startpunkt, steckt ihn in eine "Welle" für die Wertung 0 und
startet damit die Bewertungsroutine
<xhtml:code>scorePathsRecursively()</xhtml:code>. Diese wiederum tut
folgendes:</xhtml:p>
<xhtml:ol>
<xhtml:li>Setzt für alle übergebenen Wegpunkte die aktuelle Wertung.</xhtml:li>
<xhtml:li>Sucht anhand der übergebenen Wegpunkte die nächst möglichen,
noch nicht bewerteten Punkte und steckt sie in eine neue "Welle"
(<xhtml:code>$upcomingPaths</xhtml:code>).</xhtml:li>
<xhtml:li>Ruft sich selbst mit der eigens zusammengebauten nächsten
"Welle" und der nächsten Wertung auf.</xhtml:li>
<xhtml:li>Bricht dann ab, wenn eine "Welle" keine Punkte hat oder der
Zielpunkt gefunden und bewertet wurde.</xhtml:li>
</xhtml:ol>
<xhtml:p>Und hier der Code:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
/**
 * @return Maze
 */
public function scoreGrid()
{
    if (!$this-&gt;isScored) {
        $this-&gt;scorePathsRecursively(array($this-&gt;startPoint), 0);
        $this-&gt;isScored = true;
    }

    return $this;
}


/**
 * @param array $paths
 * @param int $score
 */
private function scorePathsRecursively(array $paths, $score)
{
    if (empty($paths)) {
        return;
    }

    $upcomingPaths = array();

    foreach ($paths as $path) {
        $path-&gt;setScore($score);

        if ($path-&gt;getType() == Point::TYPE_FINISH) {
            return;
        }

        foreach ($this-&gt;findConnectingPaths($path) as $connectingPath) {
            if (!$connectingPath-&gt;isScored()) {
                $upcomingPaths[] = $connectingPath;
            }
        }
    }

    $this-&gt;scorePathsRecursively($upcomingPaths, $score + 1);
}
</xhtml:pre></xhtml:div>
<xhtml:a id="rueckwaertssuche" name="rueckwaertssuche" />
<xhtml:h3>Rückwärtssuche</xhtml:h3>
<xhtml:p>Nachdem wir alle nötigen Felder bewertet haben, können wir die
Wertungen analysieren und die Route zusammensetzen. Dazu nutzen wir
die Methode <xhtml:code>findRoute()</xhtml:code>. Die stellt erst mal sicher,
dass das Labyrinth bewertet wurde und überprüft dann, ob der
Zielpunkt eine Wertung hat. Hat der nämlich keine, bedeutet das,
dass es keine Lösung geben kann. In diesem Fall können wir einfach
abbrechen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
/**
 * @return array
 */
public function findRoute()
{
    if (!$this-&gt;isScored) {
        $this-&gt;scoreGrid();
    }

    // We didn't reach the finish point :/
    if (!$this-&gt;finishPoint-&gt;isScored()) {
        return array();
    }

    return $this-&gt;findRouteRecursively($this-&gt;finishPoint);
}
</xhtml:pre></xhtml:div>
<xhtml:p>Danach wird vom Zielpunkt ausgehend
<xhtml:code>findRouteRecursively()</xhtml:code> aufgerufen. Diese Methode tut
folgendes:</xhtml:p>
<xhtml:ol>
<xhtml:li>Untersucht alle Nachbarn des Punktes nach folgenden Kriterien:
<xhtml:ol>
<xhtml:li>Ist er der Startpunkt, können wir abbrechen.</xhtml:li>
<xhtml:li>Er muss eine Wertung haben.</xhtml:li>
<xhtml:li>Er muss eine kleinere Wertung als der Suchpunkt haben.</xhtml:li>
<xhtml:li>Falls nicht der erste untersuchte Kandidat, muss er eine
kleinere Wertung als der aktuell beste Kandidat haben.</xhtml:li>
</xhtml:ol>
</xhtml:li>
<xhtml:li>Wurde ein Punkt gefunden, wird dieser der Route
hinzugefügt.</xhtml:li>
<xhtml:li>Danach gibt es einen rekursiven Aufruf von
<xhtml:code>findRouteRecursively()</xhtml:code> mit dem gefundenen Punkt und
der bisher zusammengesetzten Route.</xhtml:li>
</xhtml:ol>
<xhtml:p>Zu beachten gilt, dass die Route den Start- und Zielpunkt nicht
beinhaltet. Dies könnte man natürlich ändern. Ist nur eine
Definitionssache, was man als Route bezeichnet. :)</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
/**
 * @param Point $point
 * @param array $route
 * @return array
 */
private function findRouteRecursively(Point $point, array $route = array())
{
    $nextPoint = null;

    foreach ($this-&gt;findConnectingPaths($point) as $nextPointCandidate) {
        // If possbile next point is the start, we found what we're looking for
        if ($nextPointCandidate-&gt;getType() == Point::TYPE_START) {
            return array_reverse($route);
        }

        // Possible next point must be scored
        if (!$nextPointCandidate-&gt;isScored()) {
            continue;
        }

        // Possible next point's score must be below the current point's score
        if (!$nextPointCandidate-&gt;getScore() &gt;= $point-&gt;getScore()) {
            continue;
        }

        // Possible next point's score must be below the current possible next point's score
        if (null === $nextPoint || $nextPointCandidate-&gt;getScore() &lt; $nextPoint-&gt;getScore()) {
            $nextPoint = $nextPointCandidate;
        }
    }

    // Seems like we could not find the start. -&gt; No route.
    if (!$nextPoint) {
        return array();
    }

    // Add next point to the route
    $route[] = $nextPoint;

    return $this-&gt;findRouteRecursively($nextPoint, $route);
}
</xhtml:pre></xhtml:div>
<xhtml:p>So, wir haben nun ein Array mit allen Punkten für den kürzesten
Weg zwischen Start- und Zielpunkt. Oder anders gesagt: Das
Labyrinth ist gelöst! :)</xhtml:p>
<xhtml:p>Vielleicht kommt in Zukunft noch ein Update zu diesem Artikel,
über einen anderen Algorithmus oder eine Verbesserung für
diesen.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/103/2011-10-09/labyrinthe-loesen-mit-php</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Tschüss GitHub!]]></title>
    <published>2011-10-04T00:42:00+02:00</published>
    <updated>2011-10-04T00:42:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/1sPaW_REuI4/tschuess-github" />
    <id>http://bigwhoop.ch/artikel/102/2011-10-04/tschuess-github</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>GitHub ist cool. Es gibt aber Projekte (oder Daten), die man
lieber privat hält. Nutzt man GitHub kommt man nicht darum herum,
sich für mindestens $7 pro Monat ein Bezahlkonto zu gönnen. Und
$7/Monat finde ich, ehrlich gesagt, ziemlich viel. Das sind
immerhin $84 pro Jahr für 5 private Repositories.</xhtml:p>
<xhtml:p>Seit heute gibt es eine tolle Alternative: <xhtml:a href="http://blog.bitbucket.org/2011/10/03/bitbucket-now-rocks-git/">Atlassians
Bitbucket unterstützt nun, nebst Mercurial, auch Git.</xhtml:a>
<xhtml:strong>Und Bitbucket ist gratis. Egal ob die Repositories
öffentlich oder privat sind. Und es gibt auch kein
Limit.</xhtml:strong></xhtml:p>
<xhtml:p>Deshalb hab ich heute kurzer Hand all meine privaten
Repositories von GitHub nach Bitbucket verschoben. Das geht dank
schicker Importfunktion super schnell. Meine öffentlichen
Repositories lasse ich vorerst noch auf GitHub. Denn wie gesagt:
Das Produkt ist ja toll - nur überteuert.</xhtml:p>
<xhtml:p>In diesem Sinne,<xhtml:br />
Danke, Bitbucket!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/102/2011-10-04/tschuess-github</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Das Samurai Prinzip]]></title>
    <published>2011-09-30T07:30:00+02:00</published>
    <updated>2011-09-30T07:30:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/eD0HmiqvcoQ/das-samurai-prinzip" />
    <id>http://bigwhoop.ch/artikel/101/2011-09-30/das-samurai-prinzip</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Ich weiss, ihr wärt lieber Ninjas als Samurai. Kämpfer im
Dunkeln, schnell wie Neutrinos, agil wie das Scrumtier und tödlich
wie der BSOD. Aber heute geht es um die Samurai. Also eigentlich
geht es um Softwareentwicklung. Aber von vorne...</xhtml:p>
<xhtml:p>Die Samurai folgten einem Verhaltenscodex, dem Bushido. Darin
ging es um Ehre, Mut, Treue und weiteres solch klebriges Zeugs. Ein
Verstoss dagegen endete oft im rituellen Suizid. Darauf bezieht
sich der folgende Spruch.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Kehre erfolgreich zurück, oder gar nicht.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Und was hat das jetzt mit Softwareentwicklung zu tun? Nun, damit
ist gemeint, dass <xhtml:strong>ein Funktionsaufruf nur bei erfolgreicher
Verarbeitung etwas zurückgeben sollte, ansonsten aber eine
Exception werfen</xhtml:strong>.</xhtml:p>
<xhtml:p>Ein einfaches Beispiel: Wir brauchen eine Funktion, die einen
<xhtml:code>User</xhtml:code>-Datensatz aus der Datenbank holt. Wird dieser
nicht gefunden, soll nun nicht etwa <xhtml:code>null</xhtml:code>,
<xhtml:code>false</xhtml:code> oder ein leeres <xhtml:code>User</xhtml:code>-Objekt
zurückgegeben, sondern eine <xhtml:code>RecordNotFoundException</xhtml:code>
geworfen werden.</xhtml:p>
<xhtml:p>Was aber, wenn wir einfach nur überprüfen wollen, ob der
Datensatz existiert? Wir würden also erwarten, dass nichts gefunden
wird. Wäre da eine <xhtml:code>RecordNotFoundException</xhtml:code> nicht
falsch?<xhtml:br />
Nein, denn die Funktion die wir aufrufen wird
<xhtml:code>findUserRecord()</xhtml:code> oder ähnlich heissen. Dadurch ist der
Kontext der Funktion klar gegeben: Es soll ein Datensatz
<xhtml:em>gefunden</xhtml:em> werden. Wollen wir schauen ob ein Datensatz
existiert, müssen wir eine andere Funktion schreiben. Zum Beispiel
<xhtml:code>hasUserRecord()</xhtml:code>.</xhtml:p>
<xhtml:p>Durch diese Konvention werden wir automatisch dazu gezwungen
Funktionen so zu schreiben, dass sie nur genau eine Aufgabe haben.
Es entsteht auch automatisch ein Vertrag zwischen Funktion und
Caller. Und der ist immer gleich:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Hey Caller, ich gebe dir nur im Erfolgsfall Daten zurück. Wenn
was schief geht, dann musst du dich um die Ausnahme kümmern.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Man kann diese Verträge noch erweitern, wie beispielsweise bei
<xhtml:a href="http://c2.com/cgi/wiki?ExceptionGuarantee">Exception
Guarantee</xhtml:a>. So darf dort die Funktion im Fehlerfall nichts am
Zustand der Applikation verändern. Sprich: Wird eine Exception
geworfen, muss vorher wieder der Zustand von vor dem
Funktionsaufruf hergestellt werden. Dadurch ist vor dem
Funktionsaufruf klar, dass wir entweder im Ausgangszustand oder im
erwünschten Zielzustand landen. Und nichts dazwischen.</xhtml:p>
<xhtml:p>Wichtig anzumerken ist, dass der Caller die benötigen
Rahmenbedingungen für die Funktion schaffen muss. Wenn die Funktion
merkt, dass diese nicht gegeben sind, dann darf sie in aller Härte
abbrechen. Dies wird dann als Logikfehler des Programmierers
angesehen (und sollte gefixt werden) - und nicht als
Laufzeitfehler.</xhtml:p>
<xhtml:p>Das Ganze hat natürlich auch Schattenseiten. So müssen
Exceptions stets vom Caller gefangen werden. Dies bedeutet
Mehraufwand beim Programmieren und kann auch zu verschachteltem,
unübersichtlichem Code führen.</xhtml:p>
<xhtml:p>Ich muss eingestehen, dass ich dieses Programmierparadigma noch
nie angewandt habe. Es klingt aber äussert spannend und ich werde
es bei Gelegenheit testen. Habt ihr schon Erfahrungen damit oder
könnt ihr euch vorstellen, so zu programmieren?</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/101/2011-09-30/das-samurai-prinzip</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Firefox 7: "http://" in Adressleiste wieder anzeigen]]></title>
    <published>2011-09-28T10:33:00+02:00</published>
    <updated>2011-09-28T10:33:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/6hlRGOqli6o/firefox-7-http-in-adressleiste-wieder-anzeigen" />
    <id>http://bigwhoop.ch/artikel/99/2011-09-28/firefox-7-http-in-adressleiste-wieder-anzeigen</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Soeben hat sich mein Firefox auf Version 7 geupdatet. Eines der
neuen Features ist folgendes:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>The 'http://' URL prefix is now hidden by default</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Wenn ihr das Protokoll wieder anzeigen möchtet, dann geht das
wie folgt:</xhtml:p>
<xhtml:ol>
<xhtml:li>In der Adressleiste <xhtml:code>about:config</xhtml:code> eingeben</xhtml:li>
<xhtml:li>Nach <xhtml:code>browser.urlbar.trimURLs</xhtml:code> suchen</xhtml:li>
<xhtml:li>Doppelklicken, damit der Wert auf <xhtml:code>false</xhtml:code>
wechselt</xhtml:li>
</xhtml:ol>
<xhtml:p>That's it.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/99/2011-09-28/firefox-7-http-in-adressleiste-wieder-anzeigen</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Premature Abstraction]]></title>
    <published>2011-09-28T09:00:00+02:00</published>
    <updated>2011-09-28T09:00:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/DiEVaVgOXeM/premature-abstraction" />
    <id>http://bigwhoop.ch/artikel/98/2011-09-28/premature-abstraction</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Wir hören viel über <xhtml:strong>Premature Optimization</xhtml:strong> und
wie böse es ist, da wir versuchen unseren Code zu optimieren, bevor
wir überhaupt wissen können, ob er optimiert werden muss. Deshalb
sollten wir es nicht tun, da es in den meisten Fällen nicht nötig
sein wird.</xhtml:p>
<xhtml:p>Heute sprechen wir über etwas Ähnliches: <xhtml:strong>Premature
Abstraction</xhtml:strong>, also voreilige Abstraktion.</xhtml:p>
<xhtml:a id="abstraktion-ist-doch-toll" name="abstraktion-ist-doch-toll" />
<xhtml:h2>Abstraktion ist doch toll?!</xhtml:h2>
<xhtml:p>Je länger wir schon programmieren, desto mehr Erfahrung haben
wir. Sollten wir jedenfalls, sonst läuft etwas schief. :) Erfahrung
bringt mit sich, dass wir ein Problem besser analysieren und in
Code lösen können. Zu Beginn unserer Programmierkarriere schrieben
wir Spaghetticode, heute teilen wir den Code in Module, Klassen,
Bereiche, Aufgaben, Funktion, etc. auf. Wir schreiben mehr Code als
bei der anfänglichen Spaghettilösung. Dieser Mehraufwand ist fast
immer Abstraktion. Doch wieso tun wir das eigentlich?</xhtml:p>
<xhtml:p>Nun, einerseits wird unser Code dadurch wiederverwendbar. Er
lässt sich einfacher verändern und warten, denn die Abhängigkeiten
sind klarer und wir müssen nicht bangen, dass bei der kleinsten
Veränderung an Stelle A plötzlich Stelle B abraucht. Abstraktion
kapselt also Lösungen; und ist deshalb auch einfacher zu
erweitern.</xhtml:p>
<xhtml:a id="wo-liegt-nun-also-das-problem-mit-abstraktion" name="wo-liegt-nun-also-das-problem-mit-abstraktion" />
<xhtml:h2>Wo liegt nun also das Problem mit Abstraktion?</xhtml:h2>
<xhtml:p>Das Problem liegt nicht an der Abstraktion, sondern am Zeitpunkt
wo wir sie anwenden. Wir neigen dazu Probleme überkompliziert zu
lösen. Das aus dem Grund, weil wir schon viel weiter denken als wir
müssten.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Unsere Applikation muss Uploads speichern können. Falls wir
gross rauskommen, werden wir die Daten vermutlich bei Rackspace
oder Amazon speichern. Ich sollte das also berücksichtigen.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Guter Gedankengang! Und schon schreiben wir nebst der
<xhtml:code>UploadedFile</xhtml:code>-Klasse auch noch eine
<xhtml:code>Storage</xhtml:code>-Klasse, die das <xhtml:em>Strategy Pattern</xhtml:em>
implementiert und die Klasse <xhtml:code>FileSystemStorageStrategy</xhtml:code>
nach sich zieht. Falls wir jetzt also später mal die Uploads bei
Amazon speichern wollen, reichen wir einfach eine
<xhtml:code>AmazonS3StorageStrategy</xhtml:code>-Klasse nach und ändern ein
paar wenige Code-Stellen.</xhtml:p>
<xhtml:p>Hach, was für eine schöne Lösung. Schade nur, dass jetzt der Tag
schon rum ist und wir unsere anderen Tickets nicht abgearbeitet
haben. Und was ist, wenn wir mit unserer schicken Applikation jetzt
gar nie abheben und die Uploads nie bei Amazon gespeichert werden
müssen? Richtig, wir haben Zeit verschwendet. <xhtml:strong>Abstraktion
wird oft schlicht nicht gebraucht. Solange ein Problem nur einmal
gelöst werden muss, müssen wir es nicht unnötig abstrahieren. Das
ist Zeitverschwendung.</xhtml:strong></xhtml:p>
<xhtml:p>Falls unsere Dateien einestages tatsächlich bei Amazon
gespeichert werden müssen, können wir oben genannte Abstraktion
immer noch einbauen. <xhtml:strong>Wir verlieren durch die Verzögerung
der Implementation keine (oder nur minimale) Zeit.</xhtml:strong> Der
Aufwand ist ja der gleiche. Also mal davon ausgegangen, dass wir
die "Datei auf Dateisystem speichern"-Funktionalität gekapselt
haben. Denn die wird ja vermutlich bereits an mehreren Stellen in
unserer Applikation gebraucht.</xhtml:p>
<xhtml:p>Abstraktionen haben noch ein weiteres Problem: Sie sind
schwierig und wir brauchen - wie anfangs geschrieben - genügend
Erfahrung um sie korrekt umzusetzen. Manchmal sind die
Anforderungen aber so unklar, dass wir gar noch nicht wissen können
wie sich etwas entwicklen wird. Wir können uns deshalb durch
voreilige Abstraktion sogar den Code verbauen, so dass es später
komplizierter wird, ihn zu erweitern. <xhtml:strong>In dem wir Abstaktion
später einführen, haben wir einen Wissensvorsprung. Die Lösung wird
besser.</xhtml:strong></xhtml:p>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h2>Fazit</xhtml:h2>
<xhtml:p>Abstraktion ist gut und wichtig! Wir müssen uns aber zügeln,
damit wir keinen geilen Code-Pr0n schreiben, sondern die einfache
Lösung umsetzen. Wir können oft schlecht abschätzen wie sich eine
Applikation entwickeln wird. Deshalb sollten wir aufpassen, dass
wir nicht überkonzipieren.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/98/2011-09-28/premature-abstraction</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[You're doing it wrong #2: Lösungsfindung]]></title>
    <published>2011-09-23T16:25:00+02:00</published>
    <updated>2011-09-23T16:25:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/FYwo85WZC08/youre-doing-it-wrong-2-loesungsfindung" />
    <id>http://bigwhoop.ch/artikel/97/2011-09-23/youre-doing-it-wrong-2-loesungsfindung</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Wenn man sich nicht sicher ist, wie etwas richtig gemacht wird,
sollte man es einfach weglassen. So muss es jedenfalls einem
Redakteur des <xhtml:a href="http://tagi.ch">Tagesanzeigers</xhtml:a> ergangen
sein.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/97/fail.png" alt="Hat das Model seinen oder ihren Vater getötet? Es hat Vater getötet." /></xhtml:p>
<xhtml:p>Anzumerken gilt, dass Google Reader neuere Einträge oben listet.
Zuerst wurde also der unterste veröffentlicht.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/97/2011-09-23/youre-doing-it-wrong-2-loesungsfindung</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[You're doing it wrong #1: Singletons]]></title>
    <published>2011-09-23T16:03:00+02:00</published>
    <updated>2011-09-23T16:03:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/UUU8bvqc51g/youre-doing-it-wrong-1-singletons" />
    <id>http://bigwhoop.ch/artikel/96/2011-09-23/youre-doing-it-wrong-1-singletons</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Ein kleiner Programmierer-Tipp für's Wochenende. :)</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/96/fail.png" alt="Avoid Globals, Implement Singletons Instead" /></xhtml:p>
<xhtml:blockquote>
<xhtml:p>You should avoid using global variables. Implement singleton
instead, which is far better.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Prost!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/96/2011-09-23/youre-doing-it-wrong-1-singletons</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Neuer Blog]]></title>
    <published>2011-09-22T13:31:00+02:00</published>
    <updated>2011-09-22T13:31:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/gvyuw2odj2I/neuer-blog" />
    <id>http://bigwhoop.ch/artikel/94/2011-09-22/neuer-blog</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Tach!</xhtml:p>
<xhtml:p>Die letzten Tage habe ich meinen neuen Blog aufgeschaltet. Ziel
war ein schlichtes, text-orientiertes Design zu schaffen. Zu
bewerten ob ich das erreicht habe, überlasse ich euch. :)</xhtml:p>
<xhtml:p>Jedenfalls möchte ich in Zukunft mehr bloggen, weshalb ich mir
einen schicken <xhtml:a href="http://daringfireball.net/projects/markdown/">Markdown-Editor</xhtml:a>
gebastelt habe, der beim Schreiben nicht im Weg steht. Dazu kommt
in naher Zukunft ein technisches Follow-up.</xhtml:p>
<xhtml:p>Gestern hab ich noch ein paar URLs normalisiert und die
Kommentare von Disqus migriert, weshalb auch der RSS Feed etwas
rumzickte. Entschuldigt also etwaige Ungereimtheiten und Fehler.
Wird alles noch feingeschliffen...</xhtml:p>
<xhtml:p>Viel Spass!<xhtml:br />
Phil</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/94/2011-09-22/neuer-blog</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Musikalische Entdeckungen (1. Semester 2011)]]></title>
    <published>2011-09-17T14:20:00+02:00</published>
    <updated>2011-09-17T14:20:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/TTZ9Pk1fF7o/musikalische-entdeckungen-1-semester-2011" />
    <id>http://bigwhoop.ch/artikel/91/2011-09-17/musikalische-entdeckungen-1-semester-2011</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Meine Blog hat ein Face-Lifting gekriegt und damit auch endlich
eine eigene Sparte für all die Musik erhalten, die meine Ohren
täglich beglückt.</xhtml:p>
<xhtml:p>Auch im ersten Halbjahr 2010 hab ich einiges an toller Musik
entdeckt. Hier deshalb meine meistgehörten Alben während dieser
Zeit. Einfach so damit ich dann richtig loslegen kann - in
Zukunft.</xhtml:p>
<xhtml:a id="playlist" />
<xhtml:h2>Playlist</xhtml:h2>
<xhtml:p><xhtml:object width="300" height="500"><xhtml:param name="movie" value="http://grooveshark.com/widget.swf" />
<xhtml:param name="wmode" value="window" />
<xhtml:param name="allowScriptAccess" value="always" />
<xhtml:param name="flashvars" value="hostname=cowbell.grooveshark.com&amp;playlistID=60014127&amp;bbg=000000&amp;bth=000000&amp;pfg=000000&amp;lfg=000000&amp;bt=FFFFFF&amp;pbg=FFFFFF&amp;pfgh=FFFFFF&amp;si=FFFFFF&amp;lbg=FFFFFF&amp;lfgh=FFFFFF&amp;sb=FFFFFF&amp;bfg=666666&amp;pbgh=666666&amp;lbgh=666666&amp;sbh=666666&amp;p=0" />
<xhtml:embed src="http://grooveshark.com/widget.swf" type="application/x-shockwave-flash" width="300" height="500" flashvars="hostname=cowbell.grooveshark.com&amp;playlistID=60014127&amp;bbg=000000&amp;bth=000000&amp;pfg=000000&amp;lfg=000000&amp;bt=FFFFFF&amp;pbg=FFFFFF&amp;pfgh=FFFFFF&amp;si=FFFFFF&amp;lbg=FFFFFF&amp;lfgh=FFFFFF&amp;sb=FFFFFF&amp;bfg=666666&amp;pbgh=666666&amp;lbgh=666666&amp;sbh=666666&amp;p=0" allowscriptaccess="always" wmode="window" /></xhtml:object></xhtml:p>
<xhtml:a id="blind-melon-for-my-friends" />
<xhtml:h2>Blind Melon - For My Friends</xhtml:h2>
<xhtml:p>Ich war bereits ein riesen Fan vom Album <xhtml:em>No Soup</xhtml:em>,
welches 1995 erschien. Im selben Jahr verstarb Sänger Shannon Hoon
leider an einer Überdosis Kokain (duh...). Die Band trennte sich
und 13 Jahre später ging es mit neuem Sänger und dem Album <xhtml:em>For
My Friends</xhtml:em> weiter.</xhtml:p>
<xhtml:p>Ich weiss nicht so recht wie man den Sound von Blind Melon
beschreiben kann. Vielleicht Pop-Rock auf sanften Drogen. Die
Melodien sind eingängig, aber trotzdem fernab vom musikalischen
Einheitsbrei. Vielleicht einfach selber reinhören... ;-)</xhtml:p>
<xhtml:a id="kill-cheerleader-all-hail" />
<xhtml:h2>Kill Cheerleader - All Hail</xhtml:h2>
<xhtml:p>Es geht das Gerücht rum, dass Lemmy von Motörhead <xhtml:em>Kill
Cheerleader</xhtml:em> mal als "the greatest rock n' roll band since Guns
N' Roses." beschrieb. Kill Cheerleader spielten einen sehr
dreckigen (oder punkigen) Hard Rock, der es leider nur auf ein
Album schaffte (<xhtml:em>All Hail</xhtml:em> von 2004), da sich die Band im
Jahr 2006 auflöste. Man kann da also gut mal zuschlagen ohne sich
danach gleich nen riesen Backkatalog kaufen zu müssen.</xhtml:p>
<xhtml:p>PS: Bei mir brauchte die CD ein paar Runden. Danach ging's ab!
:-)</xhtml:p>
<xhtml:a id="big-star-1-record" />
<xhtml:h2>Big Star - #1 Record</xhtml:h2>
<xhtml:p>Big Star ist eine der Bands, die in den 70er Jahren eigentlich
ganz gross hätte werden sollen. Interne Streitigkeiten warfen die
Band aber immer wieder zurück und so blieb der grosse Erfolg aus.
Schade, denn was die Jungs auf ihren Erstling von 1972 pressten
gehört zum besten Pop aus dieser Zeit.</xhtml:p>
<xhtml:p>Fans der Sitcom <xhtml:em>That '70s Show</xhtml:em> dürfte die Band übrigens
durch das Intro bekannt sein.</xhtml:p>
<xhtml:a id="the-mountain-goats-tallahassee" />
<xhtml:h2>The Mountain Goats - Tallahassee</xhtml:h2>
<xhtml:p><xhtml:em>The Mountain Goats</xhtml:em> entstand während der Studienzeit von
Frontmann John Darnielle. Die erste Dekade des Bestehens agierte er
alleine, später kam Peter Hughes hinzu. Veröffentlicht wurden
bisher an die 20 Alben. Eines der bekannteren ist Tallahassee.</xhtml:p>
<xhtml:p>Wer auf ruhige, aber nicht balladeske (!),
Singer-/Songwriter-Musik steht, sollte hier ruhig mal
reinschnuppern. Auch lyrisch gibt es einiges zu entdecken.</xhtml:p>
<xhtml:a id="the-offspring-splinter" />
<xhtml:h2>The Offspring - Splinter</xhtml:h2>
<xhtml:p>Es gab mal eine (extrem kurze) Zeit, wo ich ein Internetradio
betrieb. Das erste Album das online rezensiert wurde war
<xhtml:em>Splinter</xhtml:em> von den Punk-Rockern der 2. Generation: <xhtml:em>THE
OFFSPRING</xhtml:em>.</xhtml:p>
<xhtml:p>Ich hab die Scheibe damals nicht oft gehört, doch sie die
letzten Monate wiederentdeckt. Und was soll ich sagen? Ich bin
begeistert! Schnörkelloses Ami-Fun-Punk-Gerocke das einfach Spass
macht. Nichts Spezielles, nichts Ungehörtes, einfach Melodien die
ins Ohren gehen und sich dort genüsslich einnisten.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/91/2011-09-17/musikalische-entdeckungen-1-semester-2011</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Eure Sterne könnt ihr behalten]]></title>
    <published>2011-09-15T12:00:00+02:00</published>
    <updated>2011-09-15T12:00:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/f0CuNYluPrk/eure-sterne-koennt-ihr-behalten" />
    <id>http://bigwhoop.ch/artikel/89/2011-09-15/eure-sterne-koennt-ihr-behalten</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Hey, ich bin jung, da macht man halt Fehler. Guckt mich nicht so
an! Nur weil ich lange Haare habe und ins 5-Sterne-Hotel
eincheckte? Ich wurde halt schwach, als ich online am Buchen war.
Einen Teil der Reservation zahlte ja eh der Arbeitgeber. Mein Kopf
sagte nur "Schnäppchen" und schon klickte die Hand. Zu meiner
Verteidigung nützt wohl auch nicht, dass ich meine Handlung bereits
Sekunden danach bereute; die wollten doch tatsächlich zusätzlich 20
Euro für 24 Stunden Internetzugang. Spinner. Da hat ja jeder
Starbucks mehr Sterne an den Eiern. Vielleicht sollten die eh mal
dieses Sterne-Bewertungssystem anpassen. Jedenfalls wollte ich die
Buchung ja stornieren, doch der Stichtag dafür lag sogar noch vor
meinem Bestelldatum. Und das war immerhin 5 Wochen vor Check-In. So
schnell geht's: Aus der Begeisterung wurde Zwang. Innert
Minuten.</xhtml:p>
<xhtml:p>Wochen später checkte ich also wahllos ein. Den Baggage Porter
umging ich gekonnt - das perfektionierte ich letztens in den USA.
Wieso soll ich für eine Dienstleistung bezahlen, die ich nicht
benötige? Geht weg. Ich betrat mein Zimmer. Das Interieur sah aus
wie in einem alten James Bond Film. Und es roch auch so wie ich mir
Sean Connerys Aftershave vorstelle: Nach Altherrenduft. Vergoldete
Armaturen und Lampen, wohin das Auge blickte. Einen Schreibtisch
wie ich ihn nur aus Dokumentarfilmen über den Kalten Krieg kenne.
Ich fühlte mich mindestens so unwohl wie Nixon, als er aus dem Amt
gebootet wurde. Dabei bin ich weder ein Verbrecher, noch ein
Arschloch. Ich bin halt nur eher der einfache Typ. Zum Beispiel
schnitt ich mir die Fingernägel mit dem mitgebrachten Schweizer
Taschenmesser, anstatt mir für zahlreiche Euronen eine Maniküre zu
gönnen. Ich lasse mich nicht gerne verwöhnen. Jedenfalls nicht
gegen Geld. Dabei fühl ich mich unwohl.</xhtml:p>
<xhtml:p>Unterm Strich war es Geldverschwendung. Aber immerhin hab ich
etwas Wichtiges gelernt: Mein Luxus definiert sich nicht durch
persönlichen Service und Freizeitangebot, sondern durch eine
praktikable, moderne Einrichtung.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/89/2011-09-15/eure-sterne-koennt-ihr-behalten</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Closure != Lambda]]></title>
    <published>2011-08-05T15:40:00+02:00</published>
    <updated>2011-08-05T15:40:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/1xwYVPSxnMA/closure-lambda" />
    <id>http://bigwhoop.ch/artikel/87/2011-08-05/closure-lambda</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Seit PHP 5.3 kommen auch wir PHP-Programmier in den Genuss von
Lambdas und Closures. Obwohl die beiden Features zur selben Zeit
implementiert wurden und sich auch nahe stehen (können), handelt es
sich dabei aber um zwei unterschiedliche Konzepte. Ein Versuch der
Aufklärung.</xhtml:p>
<xhtml:a id="lambdas" name="lambdas" />
<xhtml:h2>Lambdas</xhtml:h2>
<xhtml:p>Lambdas sind anonyme Funktionen. Sie haben also keinen
Bezeichner/Namen, sondern werden in Variablen gespeichert, an
Funktionen übergeben oder von Funktionen zurückgegeben. In einigen
Programmiersprachen gibt es ein spezielles Schlüsselwort (meist
eben dieses <xhtml:code>lambda</xhtml:code>) um anonyme Funktionen zu
definieren. In PHP nutzt man das alt-bekannte
<xhtml:code>function</xhtml:code>.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Anonyme Funktion
$gruss = function() {
    echo 'Hallo';
}

$gruss(); // Hallo

// Benannte Funktion die eine anonyme Funktion
// als erstes Argument entgegennimmt und eine
// anonyme Funktion zurückgibt.
function namedFunction(\Closure $anonFunc) {
    $anonFunc();
    return function() {
        echo 'Welt';
    };
}

$gegruesseter = namedFunction($gruss); // Hallo
$gegruesseter();                       // Welt
</xhtml:pre></xhtml:div>
<xhtml:p>Was beim letzten Beispiel auf die falsche Fährte lockt ist der
<xhtml:code>\Closure</xhtml:code> Typ-Hint. Der kommt daher, dass PHP sowohl
anonyme Funktionen als auch Closures mit einem Compiler-Trick
implementiert und jeweils als Objekt der Klasse
<xhtml:code>\Closure</xhtml:code> abbildet. Was wir oben benutzt haben sind
aber nur anonyme Funktionen, keine Closures. Zu denen kommen wir
jetzt.</xhtml:p>
<xhtml:a id="closures" name="closures" />
<xhtml:h2>Closures</xhtml:h2>
<xhtml:p>Bei Closures geht es um Variablen und den Gültigkeitsbereich
(<xhtml:em>scope</xhtml:em>), in welchem eine Funktion definiert wurde. Und mit
"Funktion" meine ich eben nicht nur anonyme, sondern auch benannte
Funktionen. Das Problem ist, dass die meisten Programmiersprachen
Closures für benannte Funktionen nicht unterstützen. Deshalb werden
Closures oft mit anonymen Funktionen/Lambdas gleichgesetzt.</xhtml:p>
<xhtml:p>Normalerweise sind Variablen innerhalb einer Funktion nach dem
Verlassen derer nicht mehr verfügbar.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function func() {
    $i = 0;
}
isset($i); // &lt;- false
</xhtml:pre></xhtml:div>
<xhtml:p>Mit Hilfe von Closures kann man diese Variablen aber am Leben
erhalten, in dem man sie in einem anderen Gültigkeitsbereich (=
eine andere Funktion) kapselt.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function func() {
    $i = 5;
    return function() use ($i) {
        echo $i;
    };
}

$x = func();
$x(); // 5
</xhtml:pre></xhtml:div>
<xhtml:p>Möchte man <xhtml:code>$i</xhtml:code> innerhalb des Closures editierbar
machen, muss man die Variable referenzieren.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function func() {
    $i = 0;
    return array(
        function() use (&amp;$i) {
            echo $i;
        },
        function($j = 1) use (&amp;$i) {
            $i += $j;
        },
    );
}

list($prnt, $incr) = func();
$prnt(); // 0
$incr();
$incr();
$prnt(); // 2
$incr(4);
$prnt(); // 6
</xhtml:pre></xhtml:div>
<xhtml:p>Closures kommen aus der funktionalen Programmierung und dort ist
es eigentlich nicht üblich, dass Variablen editiert werden können.
Deshalb implementiert jede Sprache diesen Spezialfall auch ein
bisschen anders.</xhtml:p>
<xhtml:p>Zum Abschluss noch ein Beispiel in Python. Dieses kennt nämlich
lokale Funktionen und ab Version 3 auch das Schlüsselwort
<xhtml:code>nonlocal</xhtml:code>, um Variablen des umgebenden
Gültigkeitbereiches zu referenzieren.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
def func():
    x = 0
    def printX():
        nonlocal x
        print x
    def incrementX(j = 1):
        nonlocal x
        x += j
    return printX, incrementX

prnt, incr = func()
prnt() # 0
incr()
incr()
prnt() # 2
incr(4)
prnt() # 6
</xhtml:pre></xhtml:div>
<xhtml:p>Die Funktionen <xhtml:code>printX</xhtml:code> und <xhtml:code>incrementX</xhtml:code>
sind keine anonymen Funktionen, sondern lokal definierte Funktionen
der <xhtml:code>func</xhtml:code> Funktion. In PHP geht das so nicht.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/87/2011-08-05/closure-lambda</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PHP.net kriegt ein neues Design]]></title>
    <published>2011-07-19T21:28:00+02:00</published>
    <updated>2011-07-19T21:28:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/7vZhpmky0yI/phpnet-kriegt-ein-neues-design" />
    <id>http://bigwhoop.ch/artikel/86/2011-07-19/phpnet-kriegt-ein-neues-design</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Momentan geht einiges in der PHP Community. Nebst all den
tollen, neuen Frameworks in Userland geht es auch mit grossen
Schritten Richtung PHP 5.4. Sehr gute Zeichen, wenn man bedenkt,
dass der Vibe die letzten paar Jahre eher negativ war. Und jetzt
erhält auch PHP.net endlich ein neues Design. Und so schaut es
aus:</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/86/php-prototype.png" alt="PHP.net Redesign" title="PHP.net Redesign" /></xhtml:p>
<xhtml:p>Wer selbst einen Blick risikieren möchte, hüpft nach <xhtml:a href="http://prototype.php.net">prototype.php.net</xhtml:a>. Wer bei der
Umsetzung helfen möchte, schaut am besten im <xhtml:a href="https://wiki.php.net/web/redesign/howtohelp">Wiki</xhtml:a> vorbei.</xhtml:p>
<xhtml:p><xhtml:strong>Nachtrag:</xhtml:strong> Ich glaube das Redesign ist schon
seit einiger Zeit in Arbeit. Jedenfalls impliziert dies der Titel
<xhtml:em>The 2009 / 2010 redesign of php.net</xhtml:em> einer Wiki-Seite. In
der offiziellen Mailing List hab ich leider auch nicht viel Neues
gefunden. Vielleicht weiss ja jemand von euch Bescheid, wie es um
das Redesign steht?!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/86/2011-07-19/phpnet-kriegt-ein-neues-design</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wie man die Mehrwertsteuer richtig berechnet]]></title>
    <published>2011-07-04T11:02:12+02:00</published>
    <updated>2011-07-04T11:02:12+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/IjGeroJq7g0/wie-man-die-mehrwertsteuer-richtig-berechnet" />
    <id>http://bigwhoop.ch/artikel/83/2011-07-04/wie-man-die-mehrwertsteuer-richtig-berechnet</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Vor geraumer Zeit musste ich bei einer Anzeige von Preisen
zusätzlich die inbegriffene Mehrwersteuer (oder Umstatzsteuer)
ausweisen. In der Schweiz beträgt diese in der Regel
<xhtml:strike>7.6</xhtml:strike> 8 Prozent. Ohne gross zu überlegen hatte ich
diesen Prozentsatz einfach auf den Preis angewendet.</xhtml:p>
<xhtml:p>Bruttopreis = Preis inkl. Mehrwertsteuer<xhtml:br />
Nettopreis = Preis exkl. Mehrwertsteuer</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
Mehrwertsteuer = Bruttopreis * Mehrwertsteuersatz
               = CHF 50.- * 7.6%
               = CHF 50.- * 7.6 / 100
               = CHF 3.80
</xhtml:pre></xhtml:div>
<xhtml:p>Dies ist offensichtlich ein grober Denkfehler, denn die 7.6%
beziehen sich nicht auf den Bruttopreis, sondern auf den Nettopreis
- also <xhtml:strong>exkl. Mehrwertsteuer</xhtml:strong>. Die Formel dazu ist
ziemlich simpel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
Mehrwersteuer = Bruttopreis - Nettopreis
              = Bruttopreis - Bruttopreis / (Mehrwertsteuersatz + 1)
              = CHF 50.- - CHF 50.- / (7.6% + 1)
              = CHF 50.- - CHF 50.- / (7.6 / 100 + 1)
              = CHF 50.- - CHF 46.47
              = CHF 3.53
</xhtml:pre></xhtml:div>
<xhtml:p>Da ich es jetzt niedergeschrieben habe, werde ich es hoffentlich
nie mehr vergessen. :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/83/2011-07-04/wie-man-die-mehrwertsteuer-richtig-berechnet</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Passwörter sicher(er) speichern]]></title>
    <published>2011-07-03T11:51:00+02:00</published>
    <updated>2011-07-03T11:51:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/-i_2GVNbYLY/passwoerter-sicherer-speichern" />
    <id>http://bigwhoop.ch/artikel/85/2011-07-03/passwoerter-sicherer-speichern</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:a id="update" name="update" />
<xhtml:h2>Update</xhtml:h2>
<xhtml:blockquote>
<xhtml:p>Als ich diesen Artikel schrieb war mir die Existenz von
zeitintensiven Hashing-Verfahren wie <xhtml:code>bcrypt</xhtml:code> noch nicht
bekannt. Obwohl das meiste Geschriebene dadurch seine Richtigkeit
nicht verliert, würde ich doch dazu raten, anstatt auf SHA-256 auf
bcrypt zu setzen. :-)</xhtml:p>
</xhtml:blockquote>
<xhtml:a id="einleitung" name="einleitung" />
<xhtml:h2>Einleitung</xhtml:h2>
<xhtml:p>Seit Ende April wurde in <xhtml:a href="http://attrition.org/security/rants/sony_aka_sownage.html">unzählige
Webseiten eingebrochen</xhtml:a>, die im Namen "Sony" tragen. Unter
anderem das Sony Playstation Network, Sony Online Entertainment,
Sony Music, Sony BMG, Sony Erricson, Sony Pictures und diverse
Webseiten von Landesniederlassungen von Sony.</xhtml:p>
<xhtml:p>In mehreren Fällen wurden Datenbanken entwendet, die Passwörter
in Klartext beinhalten. Für jeden Webentwickler eigentlich ein
absolutes No-Go. Falls ihr irgendwo eine solche Datenbank habt,
<xhtml:strong>setzt alle Passwörter zurück, optimiert die Speicherung
dieser und lasst eure Benutzer ein neues Passwort setzen.</xhtml:strong>
Damit wäre dieses Szenario aus dem Raum und wir können zum
eigentlich Thema fortschreiten.</xhtml:p>
<xhtml:p>Da ihr gute Entwickler seid, habt ihr die Passwörter eurer
Benutzer bestimmt als Hash abgespeichert. Eventuell habt ihr sie
sogar gesalzen.</xhtml:p>
<xhtml:p>Lange Zeit galt <xhtml:a href="http://de.wikipedia.org/wiki/MD5">MD5</xhtml:a> dabei als das
Hashing-Verfahren der Wahl. Obwohl MD5 etwas angeschlagen ist, ist
die Verwendung zum Hashen von Passwörtern weiterhin ungefährlich.
Denn obwohl sich bei MD5 <xhtml:a href="http://de.wikipedia.org/wiki/Kollisionsangriff">Kollisionen
finden</xhtml:a> lassen (= zwei frei wählbare, zufällige Datenblöcke
finden, die den gleichen Hash besitzen) ist für die Generierung von
Prüfsummen egal. Denn dort zählt die Resistenz gegen <xhtml:a href="http://de.wikipedia.org/wiki/Preimage-Angriff">Preimage-Angriffe</xhtml:a>,
da ein Datenblock ja gegeben ist (der Passwort-Hash).</xhtml:p>
<xhtml:p>Aber wir denken weiter, wir wollen möglichst sichere Passwörter.
Deshalb wollen wir diese zukunftsicher mit <xhtml:a href="http://de.wikipedia.org/wiki/SHA-256">SHA-256</xhtml:a> (256 Bits, 64
Zeichen) anstatt MD5 (128 Bits, 32 Zeichen) hashen, dabei salzen
und das ganze Prozedere sogar mehrmals durchführen. Los geht's!</xhtml:p>
<xhtml:a id="ausgangslage" name="ausgangslage" />
<xhtml:h2>Ausgangslage</xhtml:h2>
<xhtml:p>Schauen wir uns folgende, vereinfachte Tabelle
<xhtml:code>users</xhtml:code> an.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
CREATE TABLE `users` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `username` VARCHAR(80) NOT NULL,
  `password` VARCHAR(32) NOT NULL,
  `salt` VARCHAR(32) NOT NULL
) ENGINE = InnoDB;
</xhtml:pre></xhtml:div>
<xhtml:p>Schieben wir hier ein paar Einträge rein.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
INSERT INTO `users`
  (`username`, `password`, `salt`)
VALUES
  (
    'dhoward',
    MD5(CONCAT('superman12', '23f7e74d0d9b54da662d5c555ea4107f')),
    '23f7e74d0d9b54da662d5c555ea4107f'
  ),
  (
    'lebronjames',
    MD5(CONCAT('the_king', '7725eb219d8692ca7bb8f64077014a6b')), 
    '7725eb219d8692ca7bb8f64077014a6b'
  );
</xhtml:pre></xhtml:div>
<xhtml:p>So eine Tabelle existiert vermutlich in vielen oder sogar den
meisten Webanwendungen und soll Ausgangspunkt unserer Optimierungen
sein. Da bereits ein gutes Mass an Sicherheit gegeben ist, müssen
wir auch nicht alle Passwörter zurücksetzen und unsere Benutzer
informieren. Die gezeigt Lösung soll unsere aktiven Benutzer
automatisch in den Genuss von mehr Sicherheit bringen.</xhtml:p>
<xhtml:p>Der Vollständigkeit halber hier noch der aktuelle Inhalt:</xhtml:p>
<xhtml:table class="GridTable">
<xhtml:thead>
<xhtml:tr>
<xhtml:th>id</xhtml:th>
<xhtml:th>username</xhtml:th>
<xhtml:th>password</xhtml:th>
<xhtml:th>salt</xhtml:th>
</xhtml:tr>
</xhtml:thead>
<xhtml:tbody>
<xhtml:tr>
<xhtml:td>1</xhtml:td>
<xhtml:td>dhoward</xhtml:td>
<xhtml:td>9eb9917ac6d651fb5259b1f7f7facc55</xhtml:td>
<xhtml:td>23f7e74d0d9b54da662d5c555ea4107f</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>2</xhtml:td>
<xhtml:td>lebronjames</xhtml:td>
<xhtml:td>735ea0f75bc028cb48558ba2cfb047f4</xhtml:td>
<xhtml:td>7725eb219d8692ca7bb8f64077014a6b</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:a id="datenbank-updaten" name="datenbank-updaten" />
<xhtml:h2>Datenbank updaten</xhtml:h2>
<xhtml:p>Jetzt wollen wir die Tabelle so umbauen, dass die Passwörter
sicherer gespeichert werden. Dazu hashen wir sie zwischen 40'000
und 50'000 Mal mit SHA-256 und fügen nebst dem persönlichen Salz
noch den Secret Key der Webanwendung hinzu.</xhtml:p>
<xhtml:ul>
<xhtml:li>Durch das <xhtml:a href="http://de.wikipedia.org/wiki/Salt_(Kryptologie)">Salzen</xhtml:a> werden
<xhtml:a href="http://de.wikipedia.org/wiki/Rainbow_Table">Rainbow
Tables</xhtml:a> (vorgerechnete Klartext-Passwörter und deren Hash)
ausgehebelt.</xhtml:li>
<xhtml:li>Da jeder Benutzer ein eigenes, persönliches Salz erhält, muss
auch jeder Datenbank-Eintrag beim Knacken einzeln bearbeitet
werden. Wenn das Salz für alle Benutzer gleich wäre, könnte der
Angreifer Hashes mit diesem Salz generieren und alle Einträge auf
einmal überprüfen. Das wollen wir nicht.</xhtml:li>
<xhtml:li>Nebst dem persönlichen Salz werden wir aber zusätzlich noch ein
systemweites Salz hinzufügen (den Secret Key). Dieser ist nur in
der Webapplikation gespeichert, nicht aber in der Datenbank. Der
Angreifer müsste also auch Zugriff auf unseren Code erlangen (Gute
Nacht, dann!).</xhtml:li>
<xhtml:li>Um den Angreifer noch etwas länger zu beschäftigen, werden wir
die Passwörter mehrmals hashen. Für uns ist dieser zusätzliche
Zeitaufwand irrelevant, für den Angreifer aber zeitintensiv.</xhtml:li>
</xhtml:ul>
<xhtml:p>Schlussendlich soll dem Angreifer nur noch eine Möglichkeit
bleiben: <xhtml:a href="http://de.wikipedia.org/wiki/Brute_Force">Brute-Force-Attacke</xhtml:a>,
bzw. <xhtml:a href="http://de.wikipedia.org/wiki/Dictionary_Attack">Dictionary-Attacke</xhtml:a>.
Doch selbst mit geklauter Datenbank würden ihm dazu folgende
Hinweise fehlen: Wie wurde das Passwort gesalzen, in welcher
Reihenfolge, gabe es zusätzliche Salze und wie lauten diese?</xhtml:p>
<xhtml:p>Fangen wir an und bauen die <xhtml:code>users</xhtml:code> Tabelle um.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
ALTER TABLE `users`
  CHANGE `password` `password` VARCHAR(64) NOT NULL,
  ADD `hashing_algo` ENUM('md5', 'sha256') NOT NULL DEFAULT 'md5',
  ADD `hashing_rounds` SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1;
</xhtml:pre></xhtml:div>
<xhtml:p>Wir haben nun die Passwortspalte soweit angepasst, dass ein 64
Zeichen langer SHA-256 Hash gespeichert werden kann. Ausserdem
haben wir neue Spalten für den Hashing Algorithmus und die Anzahl
Durchgänge, die gehasht wurden, hinzugefügt.</xhtml:p>
<xhtml:p>Der Tabelleninhalt sieht nun so aus:</xhtml:p>
<xhtml:table class="GridTable">
<xhtml:thead>
<xhtml:tr>
<xhtml:th>id</xhtml:th>
<xhtml:th>username</xhtml:th>
<xhtml:th>password</xhtml:th>
<xhtml:th>salt</xhtml:th>
<xhtml:th>hashing_algo</xhtml:th>
<xhtml:th>hashing_rounds</xhtml:th>
</xhtml:tr>
</xhtml:thead>
<xhtml:tbody>
<xhtml:tr>
<xhtml:td>1</xhtml:td>
<xhtml:td>dhoward</xhtml:td>
<xhtml:td>9eb9917ac6d651fb5259b1f7f7facc55</xhtml:td>
<xhtml:td>23f7e74d0d9b54da662d5c555ea4107f</xhtml:td>
<xhtml:td>md5</xhtml:td>
<xhtml:td>1</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>2</xhtml:td>
<xhtml:td>lebronjames</xhtml:td>
<xhtml:td>735ea0f75bc028cb48558ba2cfb047f4</xhtml:td>
<xhtml:td>7725eb219d8692ca7bb8f64077014a6b</xhtml:td>
<xhtml:td>md5</xhtml:td>
<xhtml:td>1</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:a id="code-updaten" name="code-updaten" />
<xhtml:h2>Code updaten</xhtml:h2>
<xhtml:p>Die Datenbank steht. Jetzt müssen wir noch die Codebase
anpassen. Ich zeige dies anhand von PHP auf. Gehen wir von einem
existierenden Model <xhtml:code>User</xhtml:code> aus, dass wir mit folgenden
Funktionen erweitern/ausstatten.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
class User
{
    const HASHING_ALGO_MD5    = 'md5';
    const HASHING_ALGO_SHA256 = 'sha256';

    public $username;
    public $password;
    public $salt;
    public $hashingAlgo;
    public $hashingRounds;

    /**
     * Erstellt einen Hash für ein Klartext-Passwort.
     *
     * @param string $password
     * @param string $salt
     * @param string $hashingAlgo
     * @param int $hashingRounds
     * @return string
     */
    static public function hashPassword($password, $salt, $hashingAlgo, $hashingRounds)
    {
        switch ($hashingAlgo)
        {
            case self::HASHING_ALGO_MD5:
                $hash = $password . $salt;
                break;

            case self::HASHING_ALGO_SHA256:
                $secretKey = Config::get('security.secret-key');
                $hash = $secretKey . $password . $salt;
                break;

            default:
                throw new InvalidArgumentException('Hashing Algo wird nicht unterstützt.');
        }

        for ($i = 0; $i &lt; (int)$hashingRounds; $i  ) {
            $hash = hash($hashingAlgo, $hash);
        }

        return $hash;
    }

    // ...

    /**
     * Überprüft, ob ein Klartext-Passwort für diesen Benutzer gültig ist.
     *
     * @param string $password
     * @return bool
     */
    public function checkPassword($password)
    {
        return $this-&gt;password == self::hashPassword($password, $this-&gt;salt, $this-&gt;hashingAlgo, $this-&gt;hashingRounds);
    }

    /**
     * Hasht und speichert ein Klartext-Passwort nach dem
     * dem aktuell sichersten, implementierten Prinzip.
     * 
     * @param string $password
     * @return User
     */
    public function setPassword($password)
    {
        $this-&gt;salt          = md5(uniqid());
        $this-&gt;hashingAlgo   = self::HASHING_ALGO_SHA256;
        $this-&gt;hashingRounds = mt_rand(40000, 50000);
        $this-&gt;password      = self::hashPassword($password, $this-&gt;salt, $this-&gt;hashingAlgo, $this-&gt;hashingRounds);

        return $this;
    }

    // ...
}
</xhtml:pre></xhtml:div>
<xhtml:p>In unserer Anwendungslogik gibt es jetzt noch irgendwo die
Stelle, wo ein Anmeldeversuch überprüft werden muss. Das könnte
etwa so aussehen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
// ...

$user = User::findByUsername($username);

if (!$user) {
    throw new Exception('Ungültiger Benutzername.');
}

if (!$user-&gt;checkPassword($password)) {
    throw new Exception('Ungültiges Passwort.');
}

if ($user-&gt;hashingAlgo != User::HASHING_ALGO_SHA256) {
    $user-&gt;setPassword($password);
    $user-&gt;save();
}

// ...
</xhtml:pre></xhtml:div>
<xhtml:p>Bei einem erfolgreichen Versuch wird überprüft, ob der Benutzer
noch einen MD5-Hash verwendet. Ist dies der Fall, wird der Hash
aufgerüstet. Der Benutzer kriegt davon nichts mit.</xhtml:p>
<xhtml:p>Nehmen wir also an, dass sich User <xhtml:code>dhoward</xhtml:code>
erfolgreich mit <xhtml:code>superman12</xhtml:code> eingeloggt hat. Die Tabelle
könnte danach so aussehen (als Secret Key wurde <xhtml:code>foobar</xhtml:code>
benutzt):</xhtml:p>
<xhtml:table class="GridTable">
<xhtml:thead>
<xhtml:tr>
<xhtml:th>id</xhtml:th>
<xhtml:th>username</xhtml:th>
<xhtml:th>password</xhtml:th>
<xhtml:th>salt</xhtml:th>
<xhtml:th>hashing_algo</xhtml:th>
<xhtml:th>hashing_rounds</xhtml:th>
</xhtml:tr>
</xhtml:thead>
<xhtml:tbody>
<xhtml:tr>
<xhtml:td>1</xhtml:td>
<xhtml:td>dhoward</xhtml:td>
<xhtml:td>4029a6d114c4889c3087ae8f0ef25ce3
59dac54f7631e2f740c6d39f340dd9a0</xhtml:td>
<xhtml:td>b007f1de0b2243a1f149b9f7102155ac</xhtml:td>
<xhtml:td>sha256</xhtml:td>
<xhtml:td>43452</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>2</xhtml:td>
<xhtml:td>lebronjames</xhtml:td>
<xhtml:td>735ea0f75bc028cb48558ba2cfb047f4</xhtml:td>
<xhtml:td>7725eb219d8692ca7bb8f64077014a6b</xhtml:td>
<xhtml:td>md5</xhtml:td>
<xhtml:td>1</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:a id="benchmark" name="benchmark" />
<xhtml:h2>Benchmark</xhtml:h2>
<xhtml:p>Zum Abschluss noch eine kleine Benchmark, die aufzeigt, wie
lange mein PC zur Berechnung der Hashes bräuchte. Ich denke, die
Resultate sprechen für sich. :-)</xhtml:p>
<xhtml:table class="GridTable">
<xhtml:thead>
<xhtml:tr>
<xhtml:th>Methode</xhtml:th>
<xhtml:th>1 Hash</xhtml:th>
<xhtml:th>10 Hashes</xhtml:th>
<xhtml:th>100 Hashes</xhtml:th>
<xhtml:th>500 Hashes</xhtml:th>
<xhtml:th>1000 Hashes</xhtml:th>
<xhtml:th>5000 Hashes</xhtml:th>
</xhtml:tr>
</xhtml:thead>
<xhtml:tbody>
<xhtml:tr>
<xhtml:td>MD5, gesalzen, 1-mal gehasht</xhtml:td>
<xhtml:td>&lt;1 ms</xhtml:td>
<xhtml:td>&lt;1 ms</xhtml:td>
<xhtml:td>&lt;1 ms</xhtml:td>
<xhtml:td>1 ms</xhtml:td>
<xhtml:td>3 ms</xhtml:td>
<xhtml:td>13 ms</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>SHA-256, gesalzen, 43452-mal gehasht</xhtml:td>
<xhtml:td>156 ms</xhtml:td>
<xhtml:td>1 s 619 ms</xhtml:td>
<xhtml:td>15 s</xhtml:td>
<xhtml:td>1 min 17 s</xhtml:td>
<xhtml:td>2 min 34 s</xhtml:td>
<xhtml:td>12 min 48 s</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/85/2011-07-03/passwoerter-sicherer-speichern</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Ein kleines Programmier-Rätsel für zwischendurch]]></title>
    <published>2011-05-25T11:45:00+02:00</published>
    <updated>2011-05-25T11:45:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/7_MSS0xiG8k/ein-kleines-programmier-raetsel-fuer-zwischendurch" />
    <id>http://bigwhoop.ch/artikel/84/2011-05-25/ein-kleines-programmier-raetsel-fuer-zwischendurch</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Lust auf eine kleine Knobelei? Guck dir das folgende Bild an,
verstehe wie es aufgebaut ist und schreibe ein Script, dass ein
solches Bild generiert. Kleiner Tipp: Es ist 16 Pixel, oder 8
"Punkte" breit.</xhtml:p>
<xhtml:div style="text-align: center;"><xhtml:img src="http://bigwhoop.ch/img/articles/84/raetsel.png" alt="Bild des Rätsels" title="Na? :)" /></xhtml:div>
<xhtml:p>Inspiration zum Rätsel und Lösung folgen in den nächsten
Tagen.<xhtml:br />
In der Zwischenzeit freue ich mich über Lösungsideen und
-umsetzungen in den Comments!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/84/2011-05-25/ein-kleines-programmier-raetsel-fuer-zwischendurch</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Nervige Webseiten bei Google sperren]]></title>
    <published>2011-04-21T19:07:35+02:00</published>
    <updated>2011-04-21T19:07:35+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/uLzg46qX53Y/nervige-webseiten-bei-google-sperren" />
    <id>http://bigwhoop.ch/artikel/79/2011-04-21/nervige-webseiten-bei-google-sperren</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Die Programmierer unter euch kennen es: Man sucht per Google
Hilfe zu einem Problem und die ersten Resultate sind von
Experts-Exchange, wo man nur die Frage, aber keine Antwort findet.
Obwohl das geniale <xhtml:a href="http://stackoverflow.com">Stack
Overflow</xhtml:a> mittlerweile dominiert, sowohl den Markt als auch die
Suchergebnisse, schlüpfen doch immer wieder mal Resultate von
unnützen Webseiten durch.</xhtml:p>
<xhtml:p>Doch Google bietet Abhilfe! Auf der Seite <xhtml:a href="http://www.google.com/reviews/t">Manage Blocked Sites</xhtml:a> lassen
sich ungeliebte Domains eintragen und so aus den eigenen
Suchresultaten verdrängen. Ein Account bei Google wird dazu
natürlich vorausgesetzt.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/79/manager.png" alt="Oberfläche zum Sperren von nervigen Webseiten in Google" title="Oberfläche zum Sperren von nervigen Webseiten in Google" /></xhtml:p>
<xhtml:p>Falls anschliessend in den Suchresultaten gesperrte Webseiten
rausgefiltert wurden, wird man darauf hingewiesen und man kann die
Resultate mit einem Klick ein- und ausblenden.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/79/search.png" alt="Google Suche wenn gesperrte Seiten in den Suchresultaten auftreten" title="Google Suche wenn gesperrte Seiten in den Suchresultaten auftreten" /></xhtml:p>
<xhtml:p>Einen Haken hat die Sache: Momentan funktioniert der Filter nur
auf <xhtml:a href="http://www.google.com/#q=javascript">google.com</xhtml:a>,
nicht aber auf <xhtml:a href="http://www.google.ch/#q=javascript">google.ch</xhtml:a> oder <xhtml:a href="http://www.google.de/#q=javascript">google.de</xhtml:a>.</xhtml:p>
<xhtml:p>Zum Abschluss hier noch die aktuelle Liste meiner gesperrten
Domains:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
internet.com
javascript.com
w3schools.com
about.com
selfphp.de
selfhtml.org
experts-exchange.com
</xhtml:pre></xhtml:div>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/79/2011-04-21/nervige-webseiten-bei-google-sperren</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wie die Agentur C "Es ist besser, Gott zu vertrauen, als sich auf Menschen zu verlassen." begründet]]></title>
    <published>2011-04-19T21:35:00+02:00</published>
    <updated>2011-04-19T21:35:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/jhLh8dxtiO0/wie-die-agentur-c-es-ist-besser-gott-zu-vertrauen-als-sich-auf-menschen-zu-verlassen-begruendet" />
    <id>http://bigwhoop.ch/artikel/78/2011-04-19/wie-die-agentur-c-es-ist-besser-gott-zu-vertrauen-als-sich-auf-menschen-zu-verlassen-begruendet</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Die <xhtml:a href="http://www.agentur-c.ch">Agentur C</xhtml:a> macht in der
Schweiz mit Bibelversen Werbung. Abgesehen von der Frechheit, dass
solche religiöse Werbung erlaubt wird, <xhtml:a href="http://www.frei-denken.ch/de/tag/zensur/">den Freidenkern eigene
Werbung aber verwehrt bleibt</xhtml:a>, ist mir religiöse Werbung
eigentlich ziemlich egal. Wenn "Gott mich liebt" und "Jesus für
meine Sünden gestorben ist" ist das zwar Unfug, aber immerhin kein
dämlicher Ratschlag wie ich mein Leben leben soll.</xhtml:p>
<xhtml:p>Die Agentur C wirbt aber mit einem Vers, der mich so richtig
aufregt:</xhtml:p>
<xhtml:p style="text-align: center;"><xhtml:img src="http://bigwhoop.ch/img/articles/78/agentur-c.png" alt="Es ist besser, Gott zu vertrauen, als sich auf Menschen zu verlassen." title="Es ist besser, Gott zu vertrauen, als sich auf Menschen zu verlassen." /></xhtml:p>
<xhtml:p>Wieso mir dieser Vers auf den Sack geht, erfahrt ihr u.a. im
(kurzen) Mailverkehr, den ich mit der Agentur C führte.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:strong>Ich bin verwirrt.</xhtml:strong></xhtml:p>
<xhtml:p>Guten Tag!</xhtml:p>
<xhtml:p>In Ihrer Werbung schreiben Sie Zitat "Es ist besser, Gott zu
vertrauen, als sich auf Menschen zu verlassen.". Sind Sie, die
Macher dieser Werbung, keine Menschen? Und wurde die Bibel, die Sie
zitieren, nicht von Menschen geschrieben, übersetzt und
verbreitet?</xhtml:p>
<xhtml:p>Ich bin verwirrt und bitte um Aufklärung.</xhtml:p>
<xhtml:p>Stets,<xhtml:br />
Philippe Gerber</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:strong>AW: Ich bin verwirrt.</xhtml:strong></xhtml:p>
<xhtml:p>Guten Tag Herr Gerber</xhtml:p>
<xhtml:p>Der zitierte Vers heisst: Es ist besser Gott zu vertrauen, als
sich auf Menschen zu verlassen.</xhtml:p>
<xhtml:p>Das "Es ist besser..." schliesst keinesfalls aus, dass man sich
auch auf Menschen, wenn auch meistens auf wenige, wirklich
verlassen kann.</xhtml:p>
<xhtml:p>Der Schreibende hat persönlich erlebt, wie Gott sich ihm in
seinen grössten geschäftlichen und privaten Problemen zuwendete als
alle Beziehungen zerbrachen. (nachzulesen auf Google Kurt Bühlmann
- erlebt) Es war sehr hart, aber auch ein gewaltiges Abenteuer die
Wahrheit in diesem Bibelvers zu erleben.</xhtml:p>
<xhtml:p>Wir hoffen, dass Sie mit diesen Erklärungen die Grundaussage
dieses Verses besser verstehen können.</xhtml:p>
<xhtml:p>Freundliche Grüsse<xhtml:br />
Kurt Bühlmann<xhtml:br />
Agentur C, Vorstand</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:strong>Re: AW: Ich bin verwirrt.</xhtml:strong></xhtml:p>
<xhtml:p>Guten Tag Herr Bühlmann</xhtml:p>
<xhtml:p>Besten Dank für Ihre Antwort!</xhtml:p>
<xhtml:p>Mein Problem mit dieser Werbung ist, dass sie suggeriert, man
könne sich nicht auf Menschen verlassen. Denn wenn das Eine besser
ist als das Andere, ist das Andere automatisch schlechter als das
Eine.</xhtml:p>
<xhtml:p>Vertrauen ist ein Grundpfeiler unserer Gesellschaft. Man muss
sich im täglichen Leben auf unzählige Menschen verlassen. Sobald
man sich in ein Auto setzt, hängt das Leben vom Fahrverhalten der
Mitmenschen ab. Wenn man ins Spital muss, ist man von zig Menschen
und deren Fachwissen abhängig. Wenn man im Laden Lebensmittel
kauft, muss man darauf vertrauen, dass bei der Herstellung,
Lieferung und Kontrolle keine Fehler passierten. Ein Leben ohne
(blindes) Vertrauen in unsere Mitmenschen funktioniert nicht.</xhtml:p>
<xhtml:p>Was Ihre Werbung aber vermittelt, ist, dass man sich nicht (zu
sehr) auf Menschen verlassen sollte. Das ist ein furchtbarer
Lebensrat.</xhtml:p>
<xhtml:p>Stets,<xhtml:br />
Philippe Gerber</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:strong>AW: AW: Ich bin verwirrt.</xhtml:strong></xhtml:p>
<xhtml:p>Guten Tag Herr Gerber</xhtml:p>
<xhtml:p>Wir machen eigentlich keine Werbung, sondern plakatieren einfach
Bibelverse um die Leute zum Nachdenken und vielleicht auch einmal
nachschlagen einlädt.</xhtml:p>
<xhtml:p>Aber jeden kann sich seine Gedanken selber darüber machen, wie
Sie das tun.</xhtml:p>
<xhtml:p>Wir wünschen Ihnen eine schöne Frühlingszeit.</xhtml:p>
<xhtml:p>Freundliche Grüsse</xhtml:p>
<xhtml:p>Susanne Wanner<xhtml:br />
Sekretariat</xhtml:p>
<xhtml:hr />
<xhtml:p>An diesem Punkt hab ich nicht mehr geantwortet, da es
unvernünftig wäre sich gegenseitig in etwas Unschönes
hochzuschaukeln.</xhtml:p>
<xhtml:p>Frau Wanner hat ja alles gesagt: Die Agentur C macht keine
Werbung. Sie mietet nur Wände bei den Gemeinden und schreibt dort
dann Text hin. Das Leute den lesen ist beabsichtig, sie dürfen sich
sogar davon beeinflussen und zum Nachdenken anregen lassen. Aber
beworben wurden sie damit natürlich nicht. Genial!</xhtml:p>
<xhtml:p>Auf meine eigentliche Argumentation ist sie erst gar nicht
eingegangen - das sagt eigentlich schon alles.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:strong>Edit</xhtml:strong></xhtml:p>
<xhtml:p>Hier gibt es übrigens noch <xhtml:a href="http://geniess-das-leben.ch/werbungpubpropaganda/agentur-cagence-cagenzia/">
ein nettes Archiv</xhtml:a> mit <xhtml:del>Werbung</xhtml:del> plakatierten Zeitungen
und Wänden.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/78/2011-04-19/wie-die-agentur-c-es-ist-besser-gott-zu-vertrauen-als-sich-auf-menschen-zu-verlassen-begruendet</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Ein Vorschaubild für ein PDF Dokument generieren]]></title>
    <published>2011-04-17T19:51:36+02:00</published>
    <updated>2011-04-17T19:51:36+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/_H048iKY4p0/ein-vorschaubild-fuer-ein-pdf-dokument-generieren" />
    <id>http://bigwhoop.ch/artikel/77/2011-04-17/ein-vorschaubild-fuer-ein-pdf-dokument-generieren</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Für meine berufliche Tätigkeit habe ich letzte Woche eine
Webanwendung programmiert, wo unsere Kunden Belegvorlagen als PDF
hochladen und anschliessend Platzhalter definieren können. Bei
einer Bestellung wird die Vorlage geladen, die Platzhalter werden
mit den vom Besteller eingegebenen Daten ersetzt und so ein
PDF-Beleg generiert. Damit unsere Kunden die Platzhalter
positionieren können wird ein grosses Bild des hochgeladenen PDFs
angezeigt.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/77/pdf.png" alt="PDF mit Platzhaltern" title="PDF mit Platzhaltern" /></xhtml:p>
<xhtml:p>Um aus den PDFs Bilder zu generieren habe ich nebst PHP folgende
Software genutzt:</xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:strong>ImageMagick</xhtml:strong> ist ein freies Softwarepaket zur
Erstellung und Bearbeitung von Rastergrafiken. Es kann mehr als 100
der üblichen Bildformate lesen, verändern und schreiben. Außerdem
lassen sich Bilder dynamisch generieren, weshalb es auch im Bereich
der Webanwendungen verwendet wird.<xhtml:br />
aus <xhtml:a href="http://de.wikipedia.org/wiki/ImageMagick">Wikipedia</xhtml:a> | <xhtml:a href="http://www.imagemagick.org/script/binary-releases.php">Download</xhtml:a></xhtml:p>
</xhtml:blockquote>
<xhtml:p>und</xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:strong>Ghostscript</xhtml:strong> ist ein freier Interpreter der
Seitenbeschreibungssprachen PostScript und Portable Document Format
(PDF). Es besteht aus einem Softwarepaket, das eine API mit
Funktionen bereitstellt, um PostScript und PDF auf Druckern oder
Bildschirmen darzustellen. Es bietet einen hohen Grad an
Kompatibilität mit dem proprietären „Original“ von Adobe.<xhtml:br />
aus <xhtml:a href="http://de.wikipedia.org/wiki/Ghostscript">Wikipedia</xhtml:a> | <xhtml:a href="http://sourceforge.net/projects/ghostscript/files/GPL%20Ghostscript/">
Download</xhtml:a></xhtml:p>
</xhtml:blockquote>
<xhtml:p>Die Installation ist selbsterklärend. Zu beachten gilt nur, dass
man die zum Betriebssystem passenden Versionen erwischt.</xhtml:p>
<xhtml:p>ImageMagick bietet ein Programm namens <xhtml:code>convert</xhtml:code> an
mit welchem sich so quasi alles in Bilder konvertieren lässt. Zur
Handhabung von PDFs greift es dabei auf Ghostscript zurück. Alles
was PHP nun tun muss ist dieses Programm mit den richtigen
Parametern aufzurufen.</xhtml:p>
<xhtml:ul>
<xhtml:li>Ich hatte etwas Schwierigkeiten die PATH-Umgebungsvariable
richtig zu setzen. Per CLI hat sie funktioniert, über SAPI/Apache
aber nicht. Schlussendlich entschloss ich mich die Variable direkt
im PHP-Script, vor dem Aufruf von <xhtml:code>convert</xhtml:code>, zu
setzen.</xhtml:li>
<xhtml:li>Weiter machte mir Probleme, dass <xhtml:code>convert</xhtml:code> seine
Argumente scheinbar in einer bestimmten Reihenfolge erwartet.
Ansonsten war das generierte Bild sehr pixelig.</xhtml:li>
</xhtml:ul>
<xhtml:p>Hier nun der Beispielcode:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
define('BIN_IMAGEMAGICK', 'C:\\Program Files\\ImageMagick-6.6.8-Q1');    
define('BIN_GHOSTSCRIPT', 'C:\\Program Files (x86)\\ghostscript\\gs9.01\\bin');

$pdfPath = '...';
$imgPath = '...';
$imgDimension = '600x'; // 600px breit, Höhe je nach Verhältnis

$cmd = sprintf(
    '%s -density 300 -quality 100 -resize %s %s %s 2&gt;&amp;1',
    'convert',
    escapeshellarg($imgDimension),
    escapeshellarg($pdfPath . '[0]'), // 0 = 1. Seite des PDFs
    escapeshellarg($imgPath)
);

$pathBefore = getenv('PATH');

$paths = array(
    BIN_IMAGEMAGICK,
    BIN_GHOSTSCRIPT,
    $pathBefore,
);

putenv('PATH=' . join(PATH_SEPARATOR, $paths));

exec($cmd);

putenv("PATH=$pathBefore");
</xhtml:pre></xhtml:div>
<xhtml:p>Hoffe das hilft jemandem. :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/77/2011-04-17/ein-vorschaubild-fuer-ein-pdf-dokument-generieren</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Was ist eigentlich Duck Typing?]]></title>
    <published>2011-01-27T01:11:44+01:00</published>
    <updated>2011-01-27T01:11:44+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/DFhmW0P9CE4/was-ist-eigentlich-duck-typing" />
    <id>http://bigwhoop.ch/artikel/73/2011-01-27/was-ist-eigentlich-duck-typing</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:blockquote>
<xhtml:p>"Wenn ich einen Vogel sehe, der wie eine Ente läuft, wie eine
Ente schwimmt und wie eine Ente schnattert, dann nenne ich diesen
Vogel eine Ente."<xhtml:br />
- <xhtml:em>James Whitcomb Riley</xhtml:em></xhtml:p>
</xhtml:blockquote>
<xhtml:p>Und was hat das jetzt mit Programmierung zu tun? <xhtml:a href="http://de.wikipedia.org/wiki/Duck_Typing">Wikipedia</xhtml:a> fasst das
ganz gut zusammen:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Duck-Typing ist ein Konzept der objektorientierten
Programmierung, bei dem der Typ eines Objektes nicht durch seine
Klasse beschrieben wird, sondern durch das Vorhandensein bestimmter
Methoden.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Normalerweise zeige ich meine Beispiele ja in PHP auf, doch für
diesen Artikel eignet sich Ruby wesentlich besser. Für PHPler:</xhtml:p>
<xhtml:ul>
<xhtml:li>Ruby ist eine <xhtml:a href="http://bigwhoop.ch/artikel/65/2011-01-11/Schwach-Dynamisch-Stark-Streng-Statisch-haeae">
dynamisch/eher streng typisierte</xhtml:a> Skriptsprache</xhtml:li>
<xhtml:li>In Ruby ist alles ein Objekt (inkl. Strings, Integers,
etc.)</xhtml:li>
<xhtml:li>Ruby kennt keine abstrakten Klassen oder Interfaces</xhtml:li>
<xhtml:li>Ruby kennt kein Type Hinting</xhtml:li>
</xhtml:ul>
<xhtml:p>Gucken wir uns mal diese äquivalenten Funktionen an:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
# Ruby
def copy_file(obj, dest_path)
    src_path = obj.get_path
    puts "Copying file \"#{src_path}\" to \"#{dest_path}\"."
end

// PHP
function copyFile($obj, $destPath)
{
    $srcPath = $obj-&gt;getPath();
    echo "Copying \"$srcPath\" to \"$destPath\".";
}
</xhtml:pre></xhtml:div>
<xhtml:p>Es kann also jeweils als erstes Argument ein Objekt übergeben
werden, von welchem per Methode <xhtml:code>get_path/getPath()</xhtml:code> der
aktuelle Speicherort einer Datei ermittelt und diese danach an den
durch das zweite Argumente definierten Pfad kopiert wird. Letzteres
ist im Beispiel nicht implementiert. Es wird nur eine
Debug-Nachricht ausgegeben.</xhtml:p>
<xhtml:p>Der Unterschied zwischen beiden Programmiersprachen ist nun
folgender:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>Da in Ruby alles ein Objekt ist, muss nur überprüft werden, ob
die Variable <xhtml:code>obj</xhtml:code> die Methode <xhtml:code>get_path</xhtml:code>
besitzt. Falls nicht, wird eine <xhtml:strong>NoMethodError</xhtml:strong>
Exception geworfen. Diese kann natürlich abgefangen werden.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>In PHP muss <xhtml:code>$obj</xhtml:code> nicht nur die Methode
<xhtml:code>getPath()</xhtml:code> implementieren, sondern in erster Linie erst
mal ein Objekt sein. Eine Methode auf einem String oder Integer
aufzurufen, endet nämlich <xhtml:em>fatal</xhtml:em>.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>In Ruby können wir also alle möglichen Typen von Objekten an die
Funktion <xhtml:code>copy_file</xhtml:code> übergeben. Sie müssen einfach nur
die Methode <xhtml:code>get_path</xhtml:code> besitzen, dann läuft alles gut.
<xhtml:strong>Das ist Duck Typing. Die Klassen/Typen dieser Objekte
interessieren niemanden. Es zählt was sie können, nicht woher sie
abstammen.</xhtml:strong></xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Video
    def get_path
        "/local/path/video.mp4"
    end
end

class Image
    def get_path
        "/local/path/image.png"
    end
end

copy_file(Video.new, "/remote/path/video.mp4")
copy_file(Image.new, "/remote/path/image.png")
</xhtml:pre></xhtml:div>
<xhtml:p>Um das selbe Verhalten in PHP zu ermöglichen, gibt es mehrere
Möglichkeiten.</xhtml:p>
<xhtml:a id="type-hint-mit-objekttyp" name="type-hint-mit-objekttyp" />
<xhtml:h3>Type Hint mit Objekttyp</xhtml:h3>
<xhtml:p>Das übergebene Objekt muss eine Instanz einer bestimmten Klasse
sein.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function copyFile(Video $obj, $destPath)
{
    $srcPath = $obj-&gt;getPath();
    echo "Copying \"$srcPath\" to \"$destPath\".";
}

class Video
{
    public function getPath()
    {
        return '/local/path/video.mp4';
    }
}

copyFile(new Video(), '/remote/path/video.mp4');
</xhtml:pre></xhtml:div>
<xhtml:p>Das Problem ist, dass ich so nur <xhtml:code>Video</xhtml:code> Objekte,
aber keine z.B. <xhtml:code>Image</xhtml:code> Objekte verarbeiten kann.
Ausserdem muss ich ausserhalb der Funktion abfangen, falls ein
falsches Objekt übergeben wurde
(<xhtml:code>try</xhtml:code>/<xhtml:code>catch</xhtml:code>). Schauen wir mal weiter.</xhtml:p>
<xhtml:a id="type-hint-mit-interface" name="type-hint-mit-interface" />
<xhtml:h3>Type Hint mit Interface</xhtml:h3>
<xhtml:p>Das übergebene Objekt muss ein bestimmtes Interface
implementieren.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function copyFile(Copyable $obj, $destPath)
{
    $srcPath = $obj-&gt;getPath();
    echo "Copying \"$srcPath\" to \"$destPath\".";
}

interface Copyable
{
    public function getPath();
}

class Video implements Copyable
{
    public function getPath()
    {
        return '/local/path/video.mp4';
    }
}

class Image implements Copyable
{
    public function getPath()
    {
        return '/local/path/image.png';
    }
}

copyFile(new Video(), '/remote/path/video.mp4');
copyFile(new Image(), '/remote/path/image.png');
</xhtml:pre></xhtml:div>
<xhtml:p>Das schaut ja schon mal ganz gut aus. Wenn ich aber für jeden
Kleinkram ein eigenes Interface schreiben muss, dann kann dies auch
schnell nervig und unübersichtlich werden. Weil plötzlich zwingt
mich ein Interface eine Methode zu implementieren, die für eine
bestimmte Klasse nicht zutrifft, für die 30 anderen aber schon.
Ausserdem haben wir immer noch das Problem, dass die Funktion nicht
selber reagieren kann, falls ein Objekt mit falschem Typ übergeben
wurde.</xhtml:p>
<xhtml:p>Gehen wir weiter zur Eigenbaulösung.</xhtml:p>
<xhtml:a id="selbstaendige-validierung-der-argumente" name="selbstaendige-validierung-der-argumente" />
<xhtml:h3>Selbständige Validierung der Argumente</xhtml:h3>
<xhtml:p>Das Argument wird innerhalb der Funktion auf bestimmte Merkmale
überprüft: Es muss ein Objekt sein und die Methode
<xhtml:code>getPath()</xhtml:code> besitzen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function copyFile($obj, $destPath)
{
    if (!is_object($obj) || !is_callable($obj, 'getPath')) {
        throw new InvalidArgumentException('Argu...');
    }

    $srcPath = $obj-&gt;getPath();
    echo "Copying \"$srcPath\" to \"$destPath\".";
}

class Video
{
    public function getPath()
    {
        return '/local/path/video.mp4';
    }
}

class Image
{
    public function getPath()
    {
        return '/local/path/image.png';
    }
}

copyFile(new Video(), '/remote/path/video.mp4');
copyFile(new Image(), '/remote/path/image.png');
</xhtml:pre></xhtml:div>
<xhtml:p>Anhand des Beispiels sieht man auch, wieso Duck Typing auch als
<xhtml:strong>implizite Interfaces</xhtml:strong> bezeichnet wird: Ein Argument
muss nur genau diese Methoden implementieren, die auch wirklich im
Funktionsrumpf genutzt werden.</xhtml:p>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h3>Fazit</xhtml:h3>
<xhtml:p>Ob Duck Typing schlussendlich etwas Gutes oder Schlechtes ist,
darüber scheiden (und streiten) sich die Geister. Für- und
Gegenargumente gibt es zahlreiche.</xhtml:p>
<xhtml:p>Ein Argument gegen Duck Typing ist, dass der Programmierer den
Code viel besser kennen muss, da der Quelltext weniger hervorseh-
und durchschaubar ist. So kann z.B. nicht direkt von der <xhtml:a href="http://de.wikipedia.org/wiki/Signatur_%28Programmierung%29">Funktionssignatur</xhtml:a>
abgelesen werden, welche Parameter(typen) erwartet werden. Das
Gegenargument dazu ist, dass der Programmierer den Code gefälligst
kennen sollte, wenn er ihn pflegen will und das etwaige Probleme
durch gutes Testing abgefangen werden können.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>"Wenn ich einen Vogel sehe, der wie eine Ente läuft und wie eine
Ente schnattert, dann könnte dies ein Drache sein, der eine Ente
nachmacht."</xhtml:p>
</xhtml:blockquote>
<xhtml:p>So, jetzt wisst ihr Bescheid. ;-) Meinungen und etwaige
Korrekturen gerne in den Kommentaren.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/73/2011-01-27/was-ist-eigentlich-duck-typing</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Schwach, Dynamisch, Stark, Streng, Statisch, hää?]]></title>
    <published>2011-01-11T22:58:51+01:00</published>
    <updated>2011-01-11T22:58:51+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/Q92kMUJq1u0/schwach-dynamisch-stark-streng-statisch-haeae" />
    <id>http://bigwhoop.ch/artikel/65/2011-01-11/schwach-dynamisch-stark-streng-statisch-haeae</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Schaffen wir erst mal Ordnung im Wortewirrwarr und gruppieren
die Begriffe:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>Static</xhtml:strong> (<xhtml:strong>Statisch</xhtml:strong>) vs.
<xhtml:strong>Dynamic</xhtml:strong> (<xhtml:strong>Dynamisch</xhtml:strong>)</xhtml:li>
<xhtml:li><xhtml:strong>Strong/Loose</xhtml:strong> (<xhtml:strong>Stark/Streng</xhtml:strong>)
vs. <xhtml:strong>Weak</xhtml:strong> (<xhtml:strong>Schwach</xhtml:strong>)</xhtml:li>
</xhtml:ul>
<xhtml:a id="staticdynamic-typing" name="staticdynamic-typing" />
<xhtml:h2>Static/Dynamic Typing</xhtml:h2>
<xhtml:p>Bei <xhtml:strong>static</xhtml:strong> und <xhtml:strong>dynamic typing</xhtml:strong>
(<xhtml:strong>statische</xhtml:strong> und <xhtml:strong>dynamische
Typisierung</xhtml:strong>) geht es um die Frage...</xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:strong>Wann</xhtml:strong> stehen die Datentypen im Quellcode
fest?</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Bei den meisten Programmiersprache (nicht so beim Gros der
Skriptsprachen) erhält jede Variable bei der Deklaration einen
festen Datentyp zugeordnet. So steht bereits bei der Kompilierung
des Quellcodes fest, welcher Datentyp wo verwendet wird. Das nennt
sich dann <xhtml:strong>statisch</xhtml:strong>-typisiert und hat zur Folge,
dass fehlerhafter Quellcode (auf Typsicherheit bezogen) gar nicht
erst kompiliert werden kann.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// C
int zahl;
</xhtml:pre></xhtml:div>
<xhtml:p>Bei einer <xhtml:strong>dynamisch</xhtml:strong>-typisierten Programmier-,
bzw. meist Skriptsprache, wiederum, stehen die Datentypen erst zur
Laufzeit fest. Variablen haben also bei der Deklaration keinen
festen Datentyp.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// PHP
$zahl;
</xhtml:pre></xhtml:div>
<xhtml:a id="strongweak-typing" name="strongweak-typing" />
<xhtml:h2>Strong/Weak Typing</xhtml:h2>
<xhtml:p>Bei <xhtml:strong>strong</xhtml:strong> und <xhtml:strong>weak typing</xhtml:strong>
(<xhtml:strong>starke/strenge</xhtml:strong> und <xhtml:strong>schwache
Typisierung</xhtml:strong>) geht es um die Frage...</xhtml:p>
<xhtml:blockquote>
<xhtml:p><xhtml:strong>Wie stark</xhtml:strong> unterscheidet eine Programmiersprache
die Datentypen?</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Und da seht ihr auch schon das Problem dieser Frage: Es gibt
keine allgemeingültige Skala, die man einfach so anwenden könnte,
um die Frage zu beantworten.</xhtml:p>
<xhtml:p>Wird eine Sprache als <xhtml:strong>schwach</xhtml:strong>-typisiert
bezeichnet, ist diese Aussage einigermassen nachvollziehbar; die
Sprache unterscheidet die Datentypen halt kaum. Die Skala nach
unten ist klar definiert.</xhtml:p>
<xhtml:p>Andererseits eine Sprache als <xhtml:strong>stark</xhtml:strong>-typisiert
zu bezeichnen ist eine sehr relative Aussage: Die Skala nach oben
hat kein definiertes Ende. So gibt es z.B. auch viele
<xhtml:strong>statisch</xhtml:strong>-typisierte Programmiersprachen, die aber
<xhtml:strong>Type-Casting</xhtml:strong> (Typumwandlung) erlauben. Also das
Umformen eines Wertes von einem Datentyp in einen anderen. Zum
Beispiel in <xhtml:strong>C</xhtml:strong> geschieht dies teilweise sogar
implizit (automatisch vom Compiler).</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
int a = 2;
short int b = 4;

// b wird zur Addition nach 'int' gecastet
int c = a + b;
</xhtml:pre></xhtml:div>
<xhtml:a id="merkmale-von-stark-typisierten-sprachen" name="merkmale-von-stark-typisierten-sprachen" />
<xhtml:h3>Merkmale von stark-typisierten Sprachen</xhtml:h3>
<xhtml:p>Ein Sprache gilt als <xhtml:strong>eher</xhtml:strong> (<xhtml:em>das
Zauberwort</xhtml:em>) <xhtml:strong>stark-typisiert</xhtml:strong>, wenn sie
möglichst viele der folgenden Eigenschaften aufweist:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>Möglichst grosses Wissen darüber, was zur Laufzeit
geschehen wird</xhtml:strong></xhtml:li>
<xhtml:li><xhtml:strong>Keine Möglichkeiten das Typsystem zu umgehen</xhtml:strong>.
Zum Beispiel durch das direkte Verändern von Werten im
Speicher.</xhtml:li>
<xhtml:li><xhtml:strong>Kein implizites Type-Casting</xhtml:strong> durch den
Profiler/Interpreter. Der Programmierer muss Type-Casts explizit
angeben</xhtml:li>
<xhtml:li><xhtml:strong>Objekte (Klasseninstanzen) können ihren Typ nicht
ändern</xhtml:strong></xhtml:li>
<xhtml:li><xhtml:strong>Möglichst hohe Type-Safety (Typsicherheit)</xhtml:strong>.
Also möglichst hohe Verhinderung von Typverletzungen zur
Laufzeit.</xhtml:li>
<xhtml:li><xhtml:strong>Beim Auftreten von Fehlern bei Typvergleichen folgen
klar definierte Aktionen</xhtml:strong> (Fehler, Exceptions/Ausnahmen,
etc.)</xhtml:li>
</xhtml:ul>
<xhtml:p>Sprachen die als <xhtml:strong><xhtml:em>eher</xhtml:em> stark</xhtml:strong>-typisiert
bezeichnet werden sind z.B. <xhtml:a href="http://de.wikipedia.org/wiki/Haskell_%28Programmiersprache%29">Haskell</xhtml:a>,
<xhtml:a href="http://de.wikipedia.org/wiki/LISP">Lisp</xhtml:a> oder <xhtml:a href="http://de.wikipedia.org/wiki/Java_%28Programmiersprache%29">Java</xhtml:a>.</xhtml:p>
<xhtml:a id="wikipedia-glossar" name="wikipedia-glossar" />
<xhtml:h3>Wikipedia Glossar</xhtml:h3>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://de.wikipedia.org/wiki/Typisierung_%28Informatik%29">Typisierung</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://de.wikipedia.org/wiki/Typumwandlung">Typumwandlung</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://de.wikipedia.org/wiki/Typsicherheit">Typsicherheit</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://de.wikipedia.org/wiki/Typverletzung">Typverletzung</xhtml:a></xhtml:li>
</xhtml:ul>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/65/2011-01-11/schwach-dynamisch-stark-streng-statisch-haeae</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[window.location vs. document.location]]></title>
    <published>2011-01-04T01:00:38+01:00</published>
    <updated>2011-01-04T01:00:38+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/XyH4nM7kghE/windowlocation-vs-documentlocation" />
    <id>http://bigwhoop.ch/artikel/72/2011-01-04/windowlocation-vs-documentlocation</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Programmiert man JavaScript für einen Browser, nutzt man
ziemlich sicher auch dessen DOM und begegnet so den Objekten
<xhtml:code>window</xhtml:code> und <xhtml:code>document</xhtml:code>. Ersteres
repräsentiert das Browserfenster, Letzteres das geladene
(DOM-)Dokument. Dass <xhtml:code>document</xhtml:code> eigentlich eine
Eigenschaft von <xhtml:code>window</xhtml:code> ist
(<xhtml:code>window.document</xhtml:code>) kann man aber getrost ignorieren, da
<xhtml:code>window</xhtml:code> dem globalen Wertebereich entspricht und
<xhtml:code>window.document</xhtml:code> deshalb direkt als
<xhtml:code>document</xhtml:code> verfügbar ist (wie z.B. die
<xhtml:code>window.alert</xhtml:code> Funktion auch). Als Randnotiz kann man
noch anmerken, dass jedes Browsertab ein eigenes
<xhtml:code>window</xhtml:code> Objekt besitzt.</xhtml:p>
<xhtml:p>Manchmal möchte man per JavaScript eine Seite neuladen oder auf
eine andere Seite verlinken. Dazu nutzt man normalerweise ein
<xhtml:code>Location</xhtml:code> Objekt. Doch verwirrenderweise bietet sowohl
das <xhtml:code>window</xhtml:code> als auch das <xhtml:code>document</xhtml:code> Objekt
Zugriff auf ein <xhtml:code>Location</xhtml:code> Objekt an (jeweils mittels
der Eigenschaft <xhtml:code>location</xhtml:code>). Doch wo liegen da die
Unterschiede? Und welche Variante sollte man nutzen?
<xhtml:code>window.location</xhtml:code> oder
<xhtml:code>document.location</xhtml:code>?</xhtml:p>
<xhtml:p>Ganz einfach: Das Objekt der Wahl verbirgt sich hinter
<xhtml:code>window.location</xhtml:code>. Denn <xhtml:code>document.location</xhtml:code>
war ursprünglich als <xhtml:em>read-only</xhtml:em> Eigenschaft gedacht und
sollte deshalb (für Schreibzugriffe) nicht verwendet werden. Da die
Browserhersteller diesen Missstand erkannt haben, bieten sie nun
die <xhtml:code>document.URL</xhtml:code> Eigenschaft an, die als String die
aktuelle URL repräsentiert und nicht überschrieben werden kann.</xhtml:p>
<xhtml:p>Doch wie funktioniert jetzt eigentlich eine korrekte
Weiterleitung? Möglichkeiten gibt es ja so einige:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
window.location = 'http://bigwhoop.ch';
window.location.href = 'http://bigwhoop.ch';
window.location.assign('http://bigwhoop.ch');
window.location.replace('http://bigwhoop.ch');
window.navigate('http://bigwhoop.ch');
</xhtml:pre></xhtml:div>
<xhtml:p><xhtml:code>window.navigate('...')</xhtml:code> vergessen wir gleich wieder.
Diese Funktion entspricht keinem Standard und ist ein IE-Ding.</xhtml:p>
<xhtml:p>Die ersten drei Möglichkeiten können als gleich betrachtet
werden. Die kurze Schreibweise von <xhtml:code>window.location =
'...'</xhtml:code> ist aber sicherlich zu bevorzugen. Technisch
funktioniert das übrigens so, dass das <xhtml:code>Location</xhtml:code> Objekt
mittels eines Strings überladen werden kann und wenn immer eine
Eigenschaft des <xhtml:code>Location</xhtml:code> Objektes verändert wird, die
Funktionalität von <xhtml:code>Location.assign()</xhtml:code> aufgerufen
wird.</xhtml:p>
<xhtml:p><xhtml:code>window.location.replace('...')</xhtml:code> unterscheidet sich
dadurch von den oberen drei Möglichkeiten, dass kein neuer Eintrag
in der Browser-History angelegt, sondern der alte überschrieben
wird. D.h. der Benutzer kann danach nicht mittels Zurück-Button auf
die aktuelle Seite zurückspringen.</xhtml:p>
<xhtml:p>Zusammengefasst:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Immer schön <xhtml:code>window.location = 'http://bigwhoop.ch';</xhtml:code>
nutzen! :)</xhtml:p>
</xhtml:blockquote>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/72/2011-01-04/windowlocation-vs-documentlocation</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Buzzworderia: First-class citizen]]></title>
    <published>2010-12-14T13:00:17+01:00</published>
    <updated>2010-12-14T13:00:17+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/3dcNfFFqHBU/buzzworderia-first-class-citizen" />
    <id>http://bigwhoop.ch/artikel/71/2010-12-14/buzzworderia-first-class-citizen</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:strong>First-class citizen</xhtml:strong> ist einer dieser Ausdrücke,
die ich schon zig Male gehört oder gelesen habe, aber mich trotzdem
nie um eine Begriffserklärung bemühte. Dies hab ich jetzt endlich
nachgeholt. Mein erlangtes Wissen teile ich nun gerne mit euch -
falls ihr auch wollt.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Willst du mit mir Wissen teilen?<xhtml:br />
[ ] Ja<xhtml:br />
[ ] Nein<xhtml:br />
[ ] Weiss nicht</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Okay, das war lahm. Beginnen wir!</xhtml:p>
<xhtml:a id="erklaerung" name="erklaerung" />
<xhtml:h2>Erklärung</xhtml:h2>
<xhtml:p>Ein <xhtml:strong>first-class citizen</xhtml:strong> oder auch
<xhtml:strong>first-class object</xhtml:strong> ist ein Objekt (<xhtml:em>nicht</xhtml:em>
im Sinne einer Klasseninstanz) einer Programmiersprache, das sich
durch folgende Merkmale auszeichnet:</xhtml:p>
<xhtml:ul>
<xhtml:li>Es kann zur Laufzeit erstellt werden</xhtml:li>
<xhtml:li>Es kann zur Laufzeit zerstört werden</xhtml:li>
<xhtml:li>Es kann einer Variable zugewiesen werden</xhtml:li>
<xhtml:li>Es kann als Parameter an Funktionen/Methoden übergeben
werden</xhtml:li>
<xhtml:li>Es kann als Resultat einer Funktion/Methode zurückgegeben
werden</xhtml:li>
</xhtml:ul>
<xhtml:a id="beispiel" name="beispiel" />
<xhtml:h2>Beispiel</xhtml:h2>
<xhtml:p>In PHP, eine Klasseninstanz ist ein <xhtml:strong>first-class
citizen</xhtml:strong>.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Sie kann zur Laufzeit erstellt und einer Variable zugewiesen werden
$user = new User();

// Sie kann an eine Funktion übergeben und zurückgegeben werden
function login(User $user) {
    // Loginroutine
    // ...

    return $user;
}

// Sie kann zerstört werden
unset($user);
</xhtml:pre></xhtml:div>
<xhtml:p>Ein noch einfacheres Beispiel wäre jede skalare Variable in PHP.
Diese erfüllen ebenfalls alle Anforderungen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = 10;
$b = 10.53;
$c = 'Hallo';
$d = null;
</xhtml:pre></xhtml:div>
<xhtml:p>Klassen hingegen sind in PHP <xhtml:strong>keine first-class
citizens</xhtml:strong>. Sie können nicht zur Laufzeit erstellt/definiert
oder an Funktionen übergeben werden. Es gibt aber durchaus
Programmiersprachen wo dies möglich ist, da Klassen dort als
Objekte abgebildet werden (z.B. LISP mit CLOS). <xhtml:small>Das
behauptet jedenfalls Wikipedia.</xhtml:small></xhtml:p>
<xhtml:a id="php-und-funktionen" name="php-und-funktionen" />
<xhtml:h2>PHP und Funktionen</xhtml:h2>
<xhtml:p>In <xhtml:strong>JavaScript</xhtml:strong> sind alle Funktionen
<xhtml:strong>first-class citizens</xhtml:strong>.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
var hello = function(name) {
    alert('Hello ' + name);
}

hello('World');
</xhtml:pre></xhtml:div>
<xhtml:p>Hingegen in <xhtml:strong>PHP</xhtml:strong> ist die Sache etwas
komplizierter: Obwohl PHP seit Version 5.3 <xhtml:strong>anonyme
Funktionen/Closures</xhtml:strong> anbietet, sind diese kein eigenes
Sprachkonstrukt, sondern ein Interpreter-Trick.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$hello = function($name) {
    echo "Hello $name";
};

$hello('World'); // Hello World
</xhtml:pre></xhtml:div>
<xhtml:p>Für jede anonyme Funktion wird automatisch ein Objekt der Klasse
<xhtml:code>Closure</xhtml:code> angelegt und dort die
<xhtml:code>__invoke()</xhtml:code>-Methode aufgerufen. Obiges Beispiel könnte
also theoretisch wie folgt beschrieben werden:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// ACHTUNG: Dieser Code funktioniert so natürlich nicht!
// Er dient nur der Veranschaulichung des internen Ablaufs.

class HelloClosure extends Closure
{
    public function __invoke($name)
    {
        echo "Hello $name";
    }
}

$hello = new HelloClosure();
$hello-&gt;__invoke('World'); // oder: $hello('World');
</xhtml:pre></xhtml:div>
<xhtml:p>PHP behandelt also Funktionen <xhtml:strong>nicht ganz</xhtml:strong> als
<xhtml:strong>first-class citizens</xhtml:strong>, sondern mimt deren Verhalten
nur.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/71/2010-12-14/buzzworderia-first-class-citizen</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Offener Brief ans Strassenverkehrsamt Bern]]></title>
    <published>2010-11-11T23:03:00+01:00</published>
    <updated>2010-11-11T23:03:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/QTkPc57go4M/offener-brief-ans-strassenverkehrsamt-bern" />
    <id>http://bigwhoop.ch/artikel/69/2010-11-11/offener-brief-ans-strassenverkehrsamt-bern</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Liebes Strassenverkehrsamt Bern,</xhtml:p>
<xhtml:p>Du kennst es: Seit ein paar Jahren besteht in der Schweiz die
sogenannte 2-Phasen-Prüfung. Das heisst, dass Neulenker nach der
praktischen Fahrprüfung einen "Führerschein auf Probe" (ich nenns
mal FaP) erhalten und innerhalb der nächsten drei Jahre zwei
Fortbildungskurse absolvieren müssen. Frühestens einen Monat vor
Ablauf dieser Frist kann der normale Führerausweis beantragt
werden. So weit, so gut.</xhtml:p>
<xhtml:p>Jetzt war die Situation folgende: Zusammen mit meiner Freundin
flog ich am Montag, 25.10.2010 in die USA. Ferienzeit. Durch den
Süden der USA cruisen. Mit Auto. Yay! Dummerweise war das Fristende
beschriebenen FaPs meiner Freundin genau in den Ferien. Also hat
sie Dir ihren FaP über zwei Wochen vor unserer Abreise mit einer
schriftlichen Erklärung ihrer Situation und der Bitte um prompte
Erledigung zugeschickt.</xhtml:p>
<xhtml:p>Der vorferienliche Stress began. Man kennt das ja: Alle
Rechnungen bezahlen, Post verwalten, Katze unterbringen, Nachbarn
zum Blumengiessen einspannen, etc.</xhtml:p>
<xhtml:p>So war dann auch bald Dienstag. 19ter des Oktobers. Noch 6 Tage
bis zu unserer Abreise. Leider noch immer keine Post von Dir. Also
rief meine Freundin bei Dir an. Ein netter Herr lobte sie für ihren
Anruf und versprach die sofortige Erledigung in die Wege zu leiten
- da diese eigentlich erst für Freitag eingeplant gewesen wäre.
Gutgläubig wie wir sind/waren, glaubten wir ihm und freuten
uns.</xhtml:p>
<xhtml:p>Die Tage verstrichen und schon war Freitag. Tee minus 3 Tage.
Immer noch keine Post von Dir. Magst Du uns nicht? Also klingelte
geliebte Freundin erneut bei Dir durch. Sie erhielt die Auskunft,
dass der Antrag heute Morgen bearbeitet wurde und bereits auf der
Post sei. Sie könne ihn deshalb auch nicht persönlich abholen. Da
freuten wir uns aber.</xhtml:p>
<xhtml:p>Es ist Samstag, der Postbote bringt nicht nur keinen Brief von
Dir, er demonstriert auch noch in Bern. Scheisse. Und ab Montag
lassen wir unsere Post zurückhalten. Rufen wir doch mal die gelben
Engel an und fragen, ob die uns den Brief an einer Verteilstelle
aushändigen können. Können sie, gegen Vorweisung eines amtlichen
Ausweises. Sehr gut, Plan B steht.</xhtml:p>
<xhtml:p>Doch Plan A ist zeitlich geeigneter: Am Montagmorgen, zwei
Stunden vor unserer Abreise, um halb Acht bei Dir aufmarschieren
und nicht ohne gültigen Führerausweis wieder gehen.</xhtml:p>
<xhtml:p>Es ist besagter Morgen, wir kämpfen uns aus dem Bett, erledigen
den letzten Abwasch, verräumen den Staubsauger und denken nochmals
an unsere Katze. Diese süsse Katze, wenn Du nur wüsstet... Also:
Meine Freundin baut sich mit Kaffee eine Strasse zu Dir und was
kriegt sie zur Antwort:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Gut sind Sie vorbeigekommen, ihr Führerausweis wurde noch nicht
verschickt. Sie können ihn gerne gleich mitnehmen.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Noch Fragen? Unser Anliegen wurde von Dir wie Dreck behandelt
und wir wurden von Dir mehrmals angelogen, bzw. falsch
informiert.</xhtml:p>
<xhtml:p>Wir hätten gerne die zwei schlaflosen Nächte vom Wochenende
zurück, liebes Strassenverkehrsamt Bern.</xhtml:p>
<xhtml:p>Deine unzufriedenen und enttäuschten Kunden<xhtml:br />
Philippe und Nani</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/69/2010-11-11/offener-brief-ans-strassenverkehrsamt-bern</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Buzzworderia: Sigil]]></title>
    <published>2010-10-19T11:14:56+02:00</published>
    <updated>2010-10-19T11:14:56+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/6nzqhfOI16g/buzzworderia-sigil" />
    <id>http://bigwhoop.ch/artikel/67/2010-10-19/buzzworderia-sigil</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:strong>Sigil</xhtml:strong>, ausgesprochen
<xhtml:strong>siitsch(e)l</xhtml:strong> oder <xhtml:strong>siig(e)l</xhtml:strong> ist ein
Zeichen, dass an Variablen angehängt wird (egal ob vorne oder
hinten), um deren Datentyp oder Gültigkeitsbereich (<xhtml:em>Scope</xhtml:em>)
zu definieren.</xhtml:p>
<xhtml:p>Das einfachste Beispiel ist <xhtml:strong>PHP</xhtml:strong>. Dort werden
alle Variablen - egal in welchem Gültigkeitsbereich - mit dem Sigil
<xhtml:code>$</xhtml:code> präfigiert. Also zum Beispiel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$string = 'Kinderschokolade';
</xhtml:pre></xhtml:div>
<xhtml:p>Etwas "komplexer" ist es in <xhtml:strong>Ruby</xhtml:strong>: Gewöhnliche
Variablen haben dort kein Sigil; alle globalen Variablen werden
aber mit dem Sigil <xhtml:code>$</xhtml:code> präfigiert. Alle Klassenvariablen
erhalten das Präfix <xhtml:code>@@</xhtml:code> und allen Instanzvariablen wird
<xhtml:code>@</xhtml:code> vorangestellt. Bei Ruby werden Sigils also genutzt,
um den Gültigkeitsbereich einer Variable zu definieren.</xhtml:p>
<xhtml:p>In <xhtml:strong>Perl</xhtml:strong> wiederum werden Sigils genutzt um den
Datentyp eine Variable zu bestimmen. <xhtml:code>$</xhtml:code> für skalare
Datentypen (Strings, Integers, etc.), <xhtml:code>@</xhtml:code> für Arrays,
<xhtml:code>%</xhtml:code> für Hashes (assoziative Arrays) und
<xhtml:code>&amp;</xhtml:code> für Subroutinen (Funktionen).</xhtml:p>
<xhtml:p>Anzumerken ist, dass das Sigil (meist) vom Compiler/Interpreter
erzwungen wird. Man darf es also nicht einfach weglassen. Als
Ausnahme wäre z.B. <xhtml:strong>C#</xhtml:strong> zu nennen, wo es dem
Programmierer überlassen ist, ob er Variablen mit dem Sigil
<xhtml:code>@</xhtml:code> präfigieren will.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/67/2010-10-19/buzzworderia-sigil</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Type Hinting in PHP: Ein Experiment.]]></title>
    <published>2010-09-19T17:19:57+02:00</published>
    <updated>2010-09-19T17:19:57+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/qV6YFE_crwo/type-hinting-in-php-ein-experiment" />
    <id>http://bigwhoop.ch/artikel/64/2010-09-19/type-hinting-in-php-ein-experiment</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:a id="vorne-weg" name="vorne-weg" />
<xhtml:h2>Vorne weg...</xhtml:h2>
<xhtml:blockquote>
<xhtml:p>Auf dieser Artikelseite steht Geschwafel über <xhtml:em>Type
Hinting</xhtml:em>, <xhtml:em>Method Overloading</xhtml:em> und <xhtml:em>DocBlocks</xhtml:em>.
Das Resultat namens <xhtml:em>TypeHintMe</xhtml:em> findest du auf der zweiten
Seite.</xhtml:p>
</xhtml:blockquote>
<xhtml:a id="type-hinting" name="type-hinting" />
<xhtml:h2>Type Hinting</xhtml:h2>
<xhtml:p><xhtml:em>Type Hinting</xhtml:em> nennt sich das Vorgeben des Datentypes
eines Funktionsparameters. In vielen Programmiersprachen (C, C++,
Java) ist dies Pflicht, in den meisten Scriptsprachen schlicht
inexistent. PHP bietet eine Mischform: So gibt es zwar Type Hinting
für Objekte (über deren Klassennamen) und Arrays, aber nicht für
skalare Datentypen (Strings, Integers, etc.).</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// OK
function printName(User $user)
{}

// Syntax Error
function printName(string $forename, string $surname)
{}
</xhtml:pre></xhtml:div>
<xhtml:p>Bei PHP gibt's übrigens noch den Sonderfall, dass Parameter mit
einem Type Hint für ein Objekt den Standardwert <xhtml:code>null</xhtml:code>
haben dürfen. Das kann ziemlich nützlich sein.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
function printName(User $user, Language $language = null)
{
    if (!$language) {
        $language = Language::getCurrent();
    }

    // ...
}
</xhtml:pre></xhtml:div>
<xhtml:p>Aber genug mit dem Exkurs über Type Hinting. Lösen wir das
Problem des fehlendes Type Hintings für skalare Parameter mit den
vorhandenen Mitteln.</xhtml:p>
<xhtml:a id="method-overloading" name="method-overloading" />
<xhtml:h2>Method Overloading</xhtml:h2>
<xhtml:p>Das erste Puzzleteil ist <xhtml:em>Method Overloading</xhtml:em>.</xhtml:p>
<xhtml:p>Das Überladen von Methoden ist in PHP wiederum etwas anderes als
beispielsweise in C++. Damit ist nämlich nicht gemeint, dass eine
Methode mehrmals mit unterschiedlichen Parameter-Signaturen
deklariert werden kann...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
void printUser(User user)
{}

void printUser(string firstname, string lastname)
{}
</xhtml:pre></xhtml:div>
<xhtml:p>...sondern, dass eine Methode dynamisch zur Laufzeit "erzeugt"
werden kann. Dies geschieht aber nur, wenn die Methode nicht
deklariert wurde oder im aktuellen Sichtbarkeitsbereich (Scope)
nicht, ähm, sichtbar ist.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class User
{
    protected $forename;
    protected $surname;

    public function __construct($forename, $surname)
    {
        $this-&gt;forename = $forename;
        $this-&gt;surname  = $surname;
    }

    public function __call($method, array $params)
    {
        switch ($method)
        {
            case 'getName':
                $format = isset($params[0])
                        ? $params[0]
                        : '%s %s';
                return sprintf($format, $this-&gt;forename, $this-&gt;surname);

            default:
                throw new BadMethodCallException("Method '$method' was not declared.");
        }
    } 
}

$user = new User('Tom', 'Jones');
$user-&gt;getName();         // prints 'Tom Jones'
$user-&gt;getName('%s, %s'); // prints 'Tom, Jones'
</xhtml:pre></xhtml:div>
<xhtml:a id="docblocks" name="docblocks" />
<xhtml:h2>DocBlocks</xhtml:h2>
<xhtml:p>Als Nächstes müssen wir einen Weg finden, um den Datentyp eines
Parameters irgendwie zu definieren. Da wir die Syntax von PHP nicht
verändern können (würde ja zu einem Syntaxfehler führen) und als
professionelle Programmierer unseren Code eh schon mit dem de-facto
Standard <xhtml:em>phpDocumentor</xhtml:em> dokumentieren, können wir doch auch
gleich dessen Kommentare nutzen, oder? Sorry, das war ein langer
Satz.</xhtml:p>
<xhtml:p>Ein typischer <xhtml:em>phpDocumentor</xhtml:em> DocBlock einer Methode
schaut etwa so aus:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Auth
{
    /**
     * Try to authenticate a user by his credentials
     * 
     * @param string $username
     * @param string $password
     * @param bool $regenerateSessionId
     * @return bool
     */
    public function authenticate($username, $password, $regenerateSessionId)
    {
        return false; // Hihi
    }
}
</xhtml:pre></xhtml:div>
<xhtml:p>Und da sind sie auch schon, unsere Metadaten. Die
<xhtml:code>@param</xhtml:code>-Tags sagen uns nun, dass die ersten beiden
Parameter vom Typ <xhtml:code>string</xhtml:code> und der dritte Parameter vom
Typ <xhtml:code>boolean</xhtml:code> sein sollte. Sehr gut.</xhtml:p>
<xhtml:a id="ein-wrap-mit-allem-bitte" name="ein-wrap-mit-allem-bitte" />
<xhtml:h2>Ein Wrap mit allem, bitte.</xhtml:h2>
<xhtml:p>Ein Problem haben wir aber noch. Wie geschrieben funktioniert
die Überladung von Methoden in PHP nur, wenn diese nicht deklariert
wurden. Um unser Type Hinting zu implementieren, müssen wir uns
aber bei jedem Methodenaufruf einklinken können - auch bei
deklarierten Methoden.</xhtml:p>
<xhtml:p>Um dieses Problem zu lösen können wir das Proxy-Pattern nutzen.
D.h. wir umwickeln ein Objekt mit unserem eigenen und fangen
mittels <xhtml:code>__call</xhtml:code> jeden Methodenaufruf ab, um ihn zu
überprüfen (und weiterzuleiten).</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Wrapper
{
    protected $_object;

    public function __construct($object)
    {
        $this-&gt;_object = $object;
    }

    public function __call($method, array $params)
    {
        // DocBlock von $this-&gt;_object-&gt;$method auslesen
        // und die @param-Tags mit den Werten in $params
        // überprüfen...

        return call_user_func_array(array($this-&gt;_object, $method), $params);
    }
}

$auth = new Auth();
$auth = new Wrapper($auth);
$auth-&gt;authenticate('ch.blocher', 'IchMagKätzchenH1h1h1');
</xhtml:pre></xhtml:div>
<xhtml:p>Das schaut doch schon mal ganz schick aus. Auf der nächsten
Seite stell ich euch nun <xhtml:strong>TypeHintMe</xhtml:strong> vor. :-)</xhtml:p>
<xhtml:p>Mehr gibt es nach dem <xhtml:a href="http://bigwhoop.ch/artikel/64/2010-09-19/type-hinting-in-php-ein-experiment">
Sprung</xhtml:a>! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/64/2010-09-19/type-hinting-in-php-ein-experiment</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Fremdsprachen an Team-Meetings]]></title>
    <published>2010-09-10T12:57:04+02:00</published>
    <updated>2010-09-10T12:57:04+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/3qil4-WYVR8/fremdsprachen-an-team-meetings" />
    <id>http://bigwhoop.ch/artikel/62/2010-09-10/fremdsprachen-an-team-meetings</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Wir alle kennen es: Um 06:45 Uhr bereitet der Wecker dem Schlaf
ein jähes Ende. Wir und unser geliebter Schlaf kämpfen wacker
dagegen an, doch um 06:53 Uhr schlägt der Wecker erneut zu. Der
Schlaf kontaktiert seine Anwälte: Verdacht auf vorsätzliche Tötung.
Wären wir bloss früher ins Bett gestiegen...</xhtml:p>
<xhtml:p>Bei flexiblen Arbeitszeiten ist man sich Frühaufstehen einfach
nicht gewohnt. Doch selbst Zähneputzen mit Kaffee kann an der
Tatsache nichts ändern: Heute ist Meeting. Um 08:00 Uhr.</xhtml:p>
<xhtml:p>Mit Müh und Not landet man pünktlich in einem unbequemen
IKEA-Stuhl und dann kommt's: *<xhtml:strong>BÄNG</xhtml:strong>* ...
Englisch!</xhtml:p>
<xhtml:hr />
<xhtml:p>Es gibt gute Gründe ein Meeting auf Englisch zu führen, z.B.
wenn ein Teilnehmer kein Deutsch versteht. Doch oft geht dabei
leider vergessen, dass nicht alle anderen Teilnehmer perfekt
Englisch sprechen. Ich persönlich gehöre zur Sorte
<xhtml:em>Verstehe-eigentlich-alles-und-kann-einigermassen-gut-schreiben-aber-spreche-viel-zu-selten</xhtml:em>.
Und selbst wenn ich es schaffe die passenden Wörter zu finden, ich
kann mein Anliegen nie so gut rüberbringen wie auf Deutsch. Dazu
müsste ich die Fremdspache einfach perfekt beherrschen. Und das tue
ich nicht - wie viele andere.</xhtml:p>
<xhtml:p>Was wir also feststellen ist folgendes:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Eine Fremdsprache zu verstehen ist in der Regel einiges
einfacher, als sie zu sprechen.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Für unser Meeting bedeutet dies nun, dass sobald der
englischsprechende Teilnehmer das Deutsche einigermassen verstünde,
es keinen Grund gäbe, dass wir anderen Teilnehmer in einer
Fremdsprache sprechen müssten. Besagter Teilnehmer könnte seine
Meinung aber immer noch in seiner Muttersprache auftischen (solange
wir sie verstünden, natürlich).</xhtml:p>
<xhtml:p>Meiner Meinung nach sollte ein Meeting nicht zu einem Sprachkurs
verkommen. Dazu sind die auszutauschenden Informationen doch
einfach zu wichtig. Wenn die Beherrschung einer Fremdsprache für
die Mitarbeiter dem Arbeitgeber so wichtig ist, sollte er geführte,
interne Sprachkurse organisieren. So profitieren alle.</xhtml:p>
<xhtml:p>Absurde Züge nimmt das Ganze übrigens dann an, wenn alle
Teilnehmer deutschsprachig sind, aber das Meeting in Englisch
geführt wird (wie mir von einem Kollegen so erzählt wurde, und
Anlass für diesen Artikel war).</xhtml:p>
<xhtml:p>(Ich habe für Beispiel zwar die englische Sprache gewählt, aber
ich denke, man kann die Problematik problemlos auf andere Sprachen
übertragen.)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/62/2010-09-10/fremdsprachen-an-team-meetings</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[SVN2FTP 1.0.0-beta jetzt verfügbar]]></title>
    <published>2010-09-07T23:25:13+02:00</published>
    <updated>2010-09-07T23:25:13+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/seveyD8UAjU/svn2ftp-100-beta-jetzt-verfuegbar" />
    <id>http://bigwhoop.ch/artikel/61/2010-09-07/svn2ftp-100-beta-jetzt-verfuegbar</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Habt bedauern. Ich gehöre zu der Sorte Programmierer, die mit
einem billigen Shared Hosting ohne Shell-Zugriff leben müssen. Da
gute Programmierer - und so einer möchte ich doch sein - ihre
Arbeit versionieren, nutze ich unter anderem Subversion für einige
meiner privaten Projekte. Zum Beispiel für diese Webseite.</xhtml:p>
<xhtml:p>Da man nicht einfach ein ausgechecktes SVN Repository auf den
Server laden sollte (die <xhtml:code>.svn</xhtml:code>-Verzeichnisse beinhalten
sensible Metadaten), ist ein <xhtml:code>svn export</xhtml:code> plus
anschliessende Synchronisation angesagt. Bei grösseren Repositories
kann dies aber zu lange dauern oder das Zusammenfrickeln von
Revisions ziemlich nervig werden - besonders unter Windows.</xhtml:p>
<xhtml:p>Deshalb präsentiere ich euch die erste Version von
<xhtml:strong>SVN2FTP</xhtml:strong>.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/61/svn2ftp.png" alt="SVN2FTP Screenshot" title="SVN2FTP Screenshot" /></xhtml:p>
<xhtml:a id="darum-geht-es" name="darum-geht-es" />
<xhtml:h2>Darum geht es</xhtml:h2>
<xhtml:p>SVN2FTP ist ein kleines CLI-Tool (geschrieben in PHP 5.3), dass
angegebene Revisionen aus einem SVN Repository runter- und per FTP
auf einen Server hochlädt. Natürlich kann es auch Dateien
löschen.</xhtml:p>
<xhtml:p>Obwohl ich noch ein paar Todos aufgeschrieben habe, und mit der
Code Base nicht wirklich glücklich bin, will ich euch das bisher
Vorhandene nicht vorenthalten.</xhtml:p>
<xhtml:a id="konfiguration" name="konfiguration" />
<xhtml:h2>Konfiguration</xhtml:h2>
<xhtml:p>Für jedes Projekt kann eine eigene Konfigurationsdatei angelegt
werden, die die wichtigsten Angaben wie Host- und Benutzernamen
beinhaltet. Falls gewünscht können auch Passwörter direkt in den
Konfigurationsdateien geschrieben werden; ansonsten werdet ihr zur
gegebenen Zeit zur Eingabe aufgefordert.</xhtml:p>
<xhtml:p>Momentan werden nur <xhtml:code>.ini</xhtml:code>-Dateien unterstützt. Und
die sollten in etwa so aussehen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
[project]
; The name of the project.
; default: "Unknown Project"
name=Sample Project

; If set to true, SVN2FTP wont ask you whether you want
; to continue uploading/deleting the selected paths.
; default: false
force=false


[svn]
; Location of the Subversion executables
; default: none, value is required
bin=C:\Program Files\SlikSvn\bin
;bin=/usr/bin/svn

; The URI of the Subversion repository
; default: none, value is required
uri=https://svn.example.org/repos/example

; The name of the Subversion user
; default: none, value is required
user=john

; The password of the Subversion user
; default: &lt;SVN2FTP will prompt you for the password&gt;
password=j0hnRul3z!


[ftp]
; The URI of the remote directory on the FTP server.
; default: none, value is required
uri=ftp://example.org:21/path1/path2

; The username of the FTP user
; default: none, value is required
user=john

; The password of the FTP user
; default: &lt;SVN2FTP will prompt you for the password&gt;
password=sl1ce0fbr3ad
</xhtml:pre></xhtml:div>
<xhtml:a id="anwendung" name="anwendung" />
<xhtml:h2>Anwendung</xhtml:h2>
<xhtml:p>Die <xhtml:code>svn2ftp.php</xhtml:code> erwartet nur zwei Parameter:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>-r</xhtml:code> oder <xhtml:code>--revision</xhtml:code> - Eine
Revisionsangabe im Stile von Subversion</xhtml:li>
<xhtml:li><xhtml:code>-c</xhtml:code> oder <xhtml:code>--config</xhtml:code> - Der Pfad zu einer
<xhtml:code>.ini</xhtml:code>-Konfigurationsdatei</xhtml:li>
</xhtml:ul>
<xhtml:p>Ein Beispiel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
cd C:\Path\To\SVN2FTP\bin
php svn2ftp.php -c C:\Path\To\Project.ini -r 175:HEAD
</xhtml:pre></xhtml:div>
<xhtml:p>Für Windows-User empfiehlt sich das
<xhtml:code>C:\Path\To\SVN2FTP\bin</xhtml:code>-Verzeichnis in die
<xhtml:code>PATH</xhtml:code>-Umgebungsvariable zu legen, dadurch kann man die
<xhtml:code>svn2ftp.bat</xhtml:code> per <xhtml:code>svn2ftp</xhtml:code> aus jedem
Verzeichnis aus aufrufen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
svn2ftp -c C:\Path\To\Project.ini -r 150
</xhtml:pre></xhtml:div>
<xhtml:a id="download" name="download" />
<xhtml:h2>Download</xhtml:h2>
<xhtml:p>SVN2FTP ist auf github (<xhtml:a href="http://github.com/bigwhoop/SVN2FTP/tree/1.0.0-beta">github.com/bigwhoop/SVN2FTP</xhtml:a>)
verfügbar:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="git://github.com/bigwhoop/SVN2FTP.git">per
Git</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://svn.github.com/bigwhoop/SVN2FTP.git">per
SVN</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://github.com/bigwhoop/SVN2FTP/zipball/1.0.0-beta">als
ZIP-Archiv</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://github.com/bigwhoop/SVN2FTP/tarball/1.0.0-beta">als
Tarball</xhtml:a></xhtml:li>
</xhtml:ul>
<xhtml:a id="disclaimer" name="disclaimer" />
<xhtml:h2>Disclaimer</xhtml:h2>
<xhtml:p>Da SVN2FTP bis jetzt nur bei mir im Einsatz ist, sind die
Features auch auf meine Bedürfnisse zugeschnitten. Falls ihr Hilfe
benötigt oder etwas vermisst, schreibt bitte in die Comments.</xhtml:p>
<xhtml:p>Ahja, ich übernehme natürlich keinerlei Verantwortung - für was
auch immer ihr mit SVN2FTP anstellt. :]</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/61/2010-09-07/svn2ftp-100-beta-jetzt-verfuegbar</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Eine Auswahl unglaublich guter Musik - Teil II]]></title>
    <published>2010-08-25T09:24:00+02:00</published>
    <updated>2010-08-25T09:24:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/4N46zBVqiQ8/eine-auswahl-unglaublich-guter-musik-teil-ii" />
    <id>http://bigwhoop.ch/artikel/59/2010-08-25/eine-auswahl-unglaublich-guter-musik-teil-ii</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Irgendwie hab ich die letzten zwei Monate nachgeholt, was ich in
meiner Kindheit/frühen Jugend alles verpasst habe. Das hat zur
Folge das der Grossteil der heutigen Tipps aus den 90ern/frühen
Nullerjahren stammen. Aber schaut und hört einfach selbst... :D</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/AZf9eIw-0y8&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/AZf9eIw-0y8&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Nathan Gray</xhtml:strong> (ehemals
<xhtml:strong>boysetsfire</xhtml:strong>)<xhtml:br />
Song: <xhtml:strong>With Every Intention</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Tomorrow Come Today</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2003</xhtml:strong></xhtml:p>
<xhtml:p>... in einer unglaublich emotionalen und mittreisenden
Akustik-Version. :'/</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/MLt0iTAi6tY&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/MLt0iTAi6tY&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Ween</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Cold Blows the Wind</xhtml:strong><xhtml:br />
Album: <xhtml:strong>The Mollusk</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>1997</xhtml:strong></xhtml:p>
<xhtml:p>Wenn wir schon bei melancholischer Musik sind: <xhtml:em>Cold Blows
the Wind</xhtml:em> ist <xhtml:em>Ween</xhtml:em>'s Interpretation des englischen
Folk-Songs <xhtml:em>The Unquiet Grave</xhtml:em>. Darin geht es um einen Mann,
der ein Jahr und einen Tag um seine wahre Liebe trauert. Nach
dieser Zeit beklagt sich die Betrauerte, dass sie deshalb nicht
ruhen kann. Er bettelt um einen letzten Kuss und sie entgegnet,
dass ihn das töten würde und um ihn dann wegzuschicken.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/b0wfu3tOrtQ&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/b0wfu3tOrtQ&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Fastball</xhtml:strong><xhtml:br />
Song: <xhtml:strong>The Way</xhtml:strong><xhtml:br />
Album: <xhtml:strong>All the Pain Money Can Buy</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>1998</xhtml:strong></xhtml:p>
<xhtml:p>Den Refrain dieses Song kennt ihr - jede Wette. Doch kennt ihr
auch den Rest um die romantisierte Geschichte eines texanisches
Ehepaars, dass sich mit dem Auto auf den Weg zu einem Festival
machte, später aber weit entfernt der eigentlich Destination tot
aufgefunden wurde? Fastball-Bassist <xhtml:em>Tony Scalzo</xhtml:em> dichtet
die Geschichte so um, dass die beiden Eheleute nach einer Autopanne
zu Fuss weiterreisten und durch die Abgrenzung zu Welt zurück zum
Glück fanden.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/YDAXltfj8-Y&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/YDAXltfj8-Y&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Marcy Playground</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Sex and Candy</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Marcy Playground</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>1997</xhtml:strong></xhtml:p>
<xhtml:p><xhtml:em>Sex and Candy</xhtml:em> ist der Song, der 1997 <xhtml:em>Oasis'
Wonderwall</xhtml:em> als längsten Nummer-1-Hit in den
US-Billboard-Charts ablöste. Ich kannte ihn bis vor kurzem nicht.
Und du?</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/Yp1ZGW9MdbI&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/Yp1ZGW9MdbI&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Toad The Wet Sprocket</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Something's Always Wrong</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Dulcinea</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>1994</xhtml:strong></xhtml:p>
<xhtml:p>Den schönsten Refrain in diesem Artikel findet ihr in diesem
tollen Song von <xhtml:em>Four Young﻿ Studs and Glen</xhtml:em>. Sing
along!</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/l6nVCZpgT2s&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/l6nVCZpgT2s&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Janelle Monáe</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Cold War</xhtml:strong><xhtml:br />
Album: <xhtml:strong>The ArchAndroid (Suites II and III)</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2010</xhtml:strong></xhtml:p>
<xhtml:p>Zum Abschluss jetzt noch etwas ganz anderes. Sowohl musikalisch
also auch zeitlich. Von den 90ern direkt zu den Charts. Enjoy!
:)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/59/2010-08-25/eine-auswahl-unglaublich-guter-musik-teil-ii</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Apache 2.2 mit SSL-Unterstützung installieren (Windows)]]></title>
    <published>2010-08-01T14:10:31+02:00</published>
    <updated>2010-08-01T14:10:31+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/_yIN_ve-J8Q/apache-22-mit-ssl-unterstuetzung-installieren-windows" />
    <id>http://bigwhoop.ch/artikel/56/2010-08-01/apache-22-mit-ssl-unterstuetzung-installieren-windows</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Neulich habe ich Apache 2.2 mit OpenSSL-Unterstützung auf einem
Windows 7-Rechner installiert. Das Ganze hat etwas länger gedauert
als erwartet, da es ein paar Stolpersteine aus dem Weg zu kicken
galt. Damit es das nächste Mal schneller geht, schreib ich hier mal
für mich und natürlich auch euch nieder, wie es am schnellsten
geht.</xhtml:p>
<xhtml:a id="installation-von-apache-mit-ssl-unterstuetzung" name="installation-von-apache-mit-ssl-unterstuetzung" />
<xhtml:h2>Installation von Apache mit SSL-Unterstützung</xhtml:h2>
<xhtml:p>Damit ihr HTTP mit SSL (HTTPS) nutzen könnt, braucht ihr einen
Apachen mit OpenSSL-Federschmuck. Das passende Packet findet ihr
auf http://apache.mirror.testserver.li/httpd/binaries/win32/ (oder
nem anderen Mirror). Ihr müsst eine Datei im Stile von
<xhtml:code>httpd-2.2.15-win32-x86-openssl-0.9.8m-r2.msi</xhtml:code>
runterladen.</xhtml:p>
<xhtml:p>Falls ihr bereits eine Apache-Installation am Laufen habt,
empfiehlt es sich, diese jetzt zu deinstallieren.</xhtml:p>
<xhtml:p>Danach installiert ihr den frisch runtergeladenen Apache. Das
kriegt ihr alleine hin - ich glaube an euch!</xhtml:p>
<xhtml:a id="zertifikat-fuer-codelocalhostcode-generieren" name="zertifikat-fuer-codelocalhostcode-generieren" />
<xhtml:h2>Zertifikat für <xhtml:code>localhost</xhtml:code> generieren</xhtml:h2>
<xhtml:p>Jetzt öffnet wir erst mal eine Konsole. Falls ihr Windows
7-Nutzer seid, ist es wichtig, dass ihr die Konsole mit
Admin-Rechnen öffnet.</xhtml:p>
<xhtml:p>Danach wechselt ihr ins Installationsverzeichnis von Apache. Zum
Beispiel:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
cd "c:\Program Files (x86)\Apache Software Foundation\Apache2.2"
</xhtml:pre></xhtml:div>
<xhtml:p>Dann erstellen wir erst mal ein Verzeichnis wo wir unsere
Zertifikate aufbewahren wollen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
mkdir conf\ssl
</xhtml:pre></xhtml:div>
<xhtml:p>So. Nun ist alles bereit. Zuerst müssen wir eine
Zertifikatsignierungsanfrage plus privaten Schlüssel
generieren.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
.\bin\openssl req -config conf\openssl.cnf -new -out conf\ssl\localhost.csr -keyout conf\ssl\localhost.pem
</xhtml:pre></xhtml:div>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/56/ssl01.png" alt="Generierung von Zertifikatsignierungsanfrage und privatem Schlüssel" title="Generierung von Zertifikatsignierungsanfrage und privatem Schlüssel" /></xhtml:p>
<xhtml:p>Ihr werdet zu folgenden Eingaben aufgefordert:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>PEM pass phrase</xhtml:strong> - Ein längeres, komplexes
Passwort</xhtml:li>
<xhtml:li><xhtml:strong>Country Name</xhtml:strong> - z.B. <xhtml:code>CH</xhtml:code> für
Schweiz oder <xhtml:code>DE</xhtml:code> für Deutschland</xhtml:li>
<xhtml:li><xhtml:strong>State or Province Name</xhtml:strong> - Das Bundesland/der
Kanton in dem ihr lebt (oder ein Fantasiewert)</xhtml:li>
<xhtml:li><xhtml:strong>Locality Name</xhtml:strong> - Die Stadt in der ihr lebt
(oder ein Fantasiewert)</xhtml:li>
<xhtml:li><xhtml:strong>Organization Name</xhtml:strong> - Euer Arbeitgeber/eure
Firma (oder ein Fantasiewert)</xhtml:li>
<xhtml:li><xhtml:strong>Organizational Unit Name</xhtml:strong> - Die Abteilung der
Firma (oder ein Fantasiewert)</xhtml:li>
<xhtml:li><xhtml:strong>Common Name</xhtml:strong> - Hier müsst ihr nun die Domain
eingeben, für die das Zertifikat erstellt werden soll. Also in
unserem Falle <xhtml:code>localhost</xhtml:code>.</xhtml:li>
<xhtml:li><xhtml:strong>Email Address</xhtml:strong> - Die E-Mail-Adresse für den
technischen Kontakt des Zertifikatinhabers. Also eure
E-Mail-Adresse (oder ein Fantasiewert).</xhtml:li>
<xhtml:li><xhtml:strong>A challenge password</xhtml:strong> - Dieses Attribut könnt
ihr ignorieren indem ihr <xhtml:em>Enter</xhtml:em> drückt. Wir werden unser
Zertifikat selber signieren.</xhtml:li>
<xhtml:li><xhtml:strong>An optional company name</xhtml:strong> - Ebenfalls
ignorieren.</xhtml:li>
</xhtml:ul>
<xhtml:p>Als nächstes entfernen wir die Passphrase/das Passwort aus dem
privaten Schlüssel und speichern ihn in einer eigenen Datei. Das
geht so:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
.\bin\openssl rsa -in conf\ssl\localhost.pem -out conf\ssl\localhost.key
</xhtml:pre></xhtml:div>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/56/ssl02.png" alt="Entfernung der Passphrase aus dem privaten Schlüssel" title="Entfernung der Passphrase aus dem privaten Schlüssel" /></xhtml:p>
<xhtml:p>Zu guter Letzt generieren wir uns noch unseres eigenens
Zertifikat. Normalerweise würde dies eine autorisierte Stelle
übernehmen, doch für den Selbstgebraucht ist das nicht
notwendig.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
.\bin\openssl x509 -in conf\ssl\localhost.csr -out conf\ssl\localhost.crt -req -signkey conf\ssl\localhost.key -days 1825
</xhtml:pre></xhtml:div>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/56/ssl03.png" alt="Generierung des Zertifikates" title="Generierung des Zertifikates" /></xhtml:p>
<xhtml:p>Durch die Angabe von <xhtml:code>-days 1825</xhtml:code> wird dieses
Zertifikat für 5 Jahre gültig sein. Das sollte reichen.</xhtml:p>
<xhtml:p>Zusammengefasst haben wir nun folgende Dateien erstellt:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>localhost.crs</xhtml:code> - Eine Anfrage für eine
Zertifikatsignierung</xhtml:li>
<xhtml:li><xhtml:code>localhost.pem</xhtml:code> - Der private Schlüssel</xhtml:li>
<xhtml:li><xhtml:code>localhost.key</xhtml:code> - Die Passphrase des privaten
Schlüssels</xhtml:li>
<xhtml:li><xhtml:code>localhost.crt</xhtml:code> - Das eigentliche, signierte
Zertifikat</xhtml:li>
</xhtml:ul>
<xhtml:a id="konfiguration-von-apache-mit-ssl-unterstuetzung" name="konfiguration-von-apache-mit-ssl-unterstuetzung" />
<xhtml:h2>Konfiguration von Apache mit SSL-Unterstützung</xhtml:h2>
<xhtml:p>Was wir jetzt noch tun müssen ist unserem Apachen den
Federschmuck aufsetzen. Dazu öffnen wir erst mal die
<xhtml:code>httpd.conf</xhtml:code> im Konfigurationsverzeichnis von Apache.
Dort gilt es folgende Schritte durchzuführen:</xhtml:p>
<xhtml:ul>
<xhtml:li>Die Zeile <xhtml:code>#LoadModule ssl_module
modules/mod_ssl.so</xhtml:code> auskommentieren</xhtml:li>
<xhtml:li>Die Zeile <xhtml:code>#Include conf/extra/httpd-ssl.conf</xhtml:code>
auskommentieren</xhtml:li>
</xhtml:ul>
<xhtml:p>Nun öffnen wir eben diese <xhtml:code>httpd-ssl.conf</xhtml:code> und machen
folgendes:</xhtml:p>
<xhtml:ul>
<xhtml:li>Die Zeile beginnend mit <xhtml:code>SSLCertificateFile</xhtml:code> suchen
und das Ende des Pfades auf <xhtml:code>conf/ssl/localhost.crt</xhtml:code>
ändern. Also z.B. <xhtml:code>SSLCertificateFile "C:/Program Files
(x86)/Apache Software
Foundation/Apache2.2/conf/ssl/localhost.crt"</xhtml:code>.</xhtml:li>
<xhtml:li>Die Zeile beginnend mit <xhtml:code>SSLCertificateKeyFile</xhtml:code>
suchen und das Ende des Pfades auf
<xhtml:code>conf/ssl/localhost.key</xhtml:code> ändern. Also z.B.
<xhtml:code>SSLCertificateKeyFile "C:/Program Files (x86)/Apache Software
Foundation/Apache2.2/conf/ssl/localhost.key"</xhtml:code>.</xhtml:li>
</xhtml:ul>
<xhtml:p>Jetzt nur das Speichern nicht vergessen, den Apachen vom Pferden
holen und wieder drauf setzen (= geniale Metapher für Neustarten)
und schon sollte <xhtml:a href="https://localhost">https://localhost</xhtml:a>
funktionieren. :]</xhtml:p>
<xhtml:a id="wichtig-fuer-windows-7-benutzer" name="wichtig-fuer-windows-7-benutzer" />
<xhtml:h3>Wichtig für Windows 7-Benutzer</xhtml:h3>
<xhtml:p>Falls ihr Apache im Standardverzeichnis installiert habt,
beinhaltet euer Pfad bei <xhtml:code>C:/Program Files
(x86)/Apac...</xhtml:code> runde Klammern. Dies führt zur Fehlermeldung
<xhtml:strong>SSLSessionCache: Invalid argument: size has to be &gt;=
8192 bytes</xhtml:strong> beim Versuch den Apache zu starten.</xhtml:p>
<xhtml:p>Abhilfe schafft eine Verknüpfung auf das Apache-Verzeichnis z.B.
im Root von <xhtml:code>C:\</xhtml:code>. Da es mir wegen den Rechten nicht
gelang eine Verknüpfung direkt in <xhtml:code>C:\</xhtml:code> zu erstellen,
habe ich diese zuerst auf dem Desktop erstellt und danach nach
<xhtml:code>C:\</xhtml:code> kopiert.</xhtml:p>
<xhtml:p>Schlussendlich solltet ihr einfach eine Verknüpfung à la
<xhtml:code>C:\Apache2.2</xhtml:code> nach <xhtml:code>C:\Program Files (x86)\Apache
Software Foundation\Apache2.2</xhtml:code> haben.</xhtml:p>
<xhtml:p>Danach sucht ihr im <xhtml:code>httpd-ssl.conf</xhtml:code> die Zeile
beginnend mit <xhtml:code>SSLSessionCache</xhtml:code> und ersetzt den
bestehenden Pfad mit dem neuen, klammerlosen Pfad der Verknüpfung.
Zum Beispiel <xhtml:code>SSLSessionCache
"shmcb:C:/Apache2.2/logs/ssl_scache(512000)"</xhtml:code>.</xhtml:p>
<xhtml:p>Jetzt sollte der Apache mit HTTPS auch unter Windows 7
rocken!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/56/2010-08-01/apache-22-mit-ssl-unterstuetzung-installieren-windows</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Eine Auswahl unglaublich guter Musik - Teil I]]></title>
    <published>2010-06-29T15:58:37+02:00</published>
    <updated>2010-06-29T15:58:37+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/HgKYEIpMq6c/eine-auswahl-unglaublich-guter-musik-teil-i" />
    <id>http://bigwhoop.ch/artikel/55/2010-06-29/eine-auswahl-unglaublich-guter-musik-teil-i</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/gbv-yqqmLH0&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/gbv-yqqmLH0&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Emancipator</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Lionheart</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Soon It Will Be Cold Enough</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2006</xhtml:strong></xhtml:p>
<xhtml:p>Hinter <xhtml:em>Emancipator</xhtml:em> steckt Produzent und
Multiinstrumentalist (gibt's dieses Wort?) Doug Appling. In
<xhtml:em>Lionheart</xhtml:em> findet ihr ein ruhiges, leicht melancholisches
Instrumental, das jeden Endzeitfilm aufwerten würde. Zum Entspannen
und Träumen.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="385"><xhtml:param name="movie" value="http://www.youtube.com/v/7wKhrEFzLfM&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/7wKhrEFzLfM&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Minuit</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Aotearoa</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Find Me Before I Die A Lonely
Death.com</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2009</xhtml:strong></xhtml:p>
<xhtml:p><xhtml:em>Minuit</xhtml:em> ist eine Neuseeländische Elektroband die mit
<xhtml:em>Aotearoa</xhtml:em> einen eher Breakbeatigen Song mit einem tollen
Video zur jungen Geschichte ihres Landes.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/yu6zUwDv-o4&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/yu6zUwDv-o4&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Tal Wilkenfeld</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Table For One</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Transformation</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2007</xhtml:strong></xhtml:p>
<xhtml:p><xhtml:em>Tal Wilkenfeld</xhtml:em> ist eine blutjunge (Jahrgang 1986!),
australische Jazz-Bassistin, die zu den Newcomern der letzten Jahre
zählt.</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/Eyz0WraN3LU&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/Eyz0WraN3LU&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>The Rolling Stones</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Rip This Joint</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Exile on Main St.</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>1972</xhtml:strong></xhtml:p>
<xhtml:p>Die <xhtml:em>Rolling Stones</xhtml:em> kennt jeder. Diesen Song aber nicht.
Jahrzehntelang verschwand er gänzlich aus der Setliste der Stones.
Tanzt!</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/GxZuq57_bYM&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/GxZuq57_bYM&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>The Winstons</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Amen, Brother</xhtml:strong><xhtml:br />
Album: B-Seite von <xhtml:strong>Color Him Father</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>1969</xhtml:strong></xhtml:p>
<xhtml:p>In diesem Lied gibt es einen kurzen Schlagzeug-Break der keine
unwesentliche Rolle in der Entwicklung von Hip-Hop-Musik und Drum
'n Bass spielte, wurde er doch tausendfach wiederverwertet. Man
geht davon aus, dass dieser sogenannte <xhtml:em>Amen Break</xhtml:em> das am
häufigsten genutzte Sample in diesen Musikrichtungen ist. Aber auch
sonst <xhtml:em>funk</xhtml:em>t <xhtml:em>Amen, Brother</xhtml:em> ganz gut. (haha
;-))</xhtml:p>
<xhtml:hr />
<xhtml:p><xhtml:object width="640" height="505"><xhtml:param name="movie" value="http://www.youtube.com/v/_9wPvlTBgZw&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/_9wPvlTBgZw&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505" /></xhtml:object></xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Incubus</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Anna Molly</xhtml:strong><xhtml:br />
Album: <xhtml:strong>Light Grenades</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2006</xhtml:strong></xhtml:p>
<xhtml:p>Zugegeben, viele werden <xhtml:em>Incubus</xhtml:em> und damit wohl auch
<xhtml:em>Anna Molly</xhtml:em> kennen. An mir ging dieses Lied irgendwie
gänzlich vorbei. Wenn es dir auch so erging: Reinhören!</xhtml:p>
<xhtml:hr />
<xhtml:p>Einbetten wurde leider deaktiviert. Ein Klick lohnt sich aber
auf jeden Fall! <xhtml:a href="http://www.youtube.com/watch?v=8-8nkkOA_AM">Klick</xhtml:a>.</xhtml:p>
<xhtml:p>Künstler: <xhtml:strong>Mat Weddle</xhtml:strong> von der Band
<xhtml:strong>Obadiah Parker</xhtml:strong> (im Original von
<xhtml:strong>OutKast</xhtml:strong><xhtml:br />
Song: <xhtml:strong>Hey Ya</xhtml:strong><xhtml:br />
Album: <xhtml:strong>-</xhtml:strong><xhtml:br />
Erscheinungsjahr: <xhtml:strong>2006</xhtml:strong> (via YouTube)</xhtml:p>
<xhtml:p><xhtml:em>Hey Ya</xhtml:em> von <xhtml:em>OutKast</xhtml:em> (grosses K?) kennt man aus
den Charts. Was aber <xhtml:em>Mat Weddle</xhtml:em> mit seiner Cover-Version
daraus gemacht hat gibt dem Lied ein ganz neue Tiefe. Unglaublich
gefühlvoll.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/55/2010-06-29/eine-auswahl-unglaublich-guter-musik-teil-i</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Neue Bürger braucht das Land]]></title>
    <published>2010-06-26T17:34:56+02:00</published>
    <updated>2010-06-26T17:34:56+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/PO166rtDNsA/neue-buerger-braucht-das-land" />
    <id>http://bigwhoop.ch/artikel/54/2010-06-26/neue-buerger-braucht-das-land</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Zugegeben, die <xhtml:a href="http://www.tagesanzeiger.ch/schweiz/standard/SVP-will-der-Schweiz-Nachbargebiete-einverleiben/story/23529806">
Meldung</xhtml:a> ist schon ein paar Tage alt, aber nach dem Ausscheiden
unserer Fussballnationalmannschaft könnten ein paar weitere
Fussballer gut gebrauchen. :]</xhtml:p>
<xhtml:a id="sport" name="sport" />
<xhtml:h2>Sport</xhtml:h2>
<xhtml:p><xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/dennis-aogo.jpg" alt="Dennis Aogo" title="Dennis Aogo" /></xhtml:p>
<xhtml:p><xhtml:strong>Dennis Aogo</xhtml:strong>, geboren am 14. Januar 1987 in
Karlsruhe, ist ein deutscher Fussballnationalspieler. Den jungen
Defensivmann würde Otti bestimmt irgendwo unterbringen.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/gianluca-zambrotta.jpg" alt="Gianluca Zambrotta" title="Gianluca Zambrotta" />
<xhtml:p><xhtml:strong>Gianluca Zambrotta</xhtml:strong>, geboren am 19. Februar 1977
in Como, ist ein italienischer Fussballnationalspieler. Zugegeben,
der Herr ist schon etwas alt, könnte aber die nächsten vier Jahre
bestimmt noch mitspielen und viel seiner Erfahrung weitergeben.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/oliver-kahn.jpg" alt="Oliver Kahn" title="Oliver Kahn" />
<xhtml:p><xhtml:strong>Oliver Kahn</xhtml:strong>, geboren am 15. Juni 1969 in
Karlsruhe, war der beste Fussballtorwart der Welt. Als Motivator
würde er Wunder vollbringen. Jawohl.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/regina-halmich.jpg" alt="Regina Halmich" title="Regina Halmich" />
<xhtml:p><xhtml:strong>Regina Halmich</xhtml:strong>, geboren am 22. November 1976 in
Karlsruhe, war bis zu ihrem Rücktritt über 12 Jahre hinweg die
beste Profiboxerin der Welt. Zur Feier der Einbürgerung dürfte sie
in einer pompösen Galashow gegen Blocher in den Ring steigen.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/arsene-wenger.jpg" alt="Arsène Wenger" title="Arsène Wenger" />
<xhtml:p><xhtml:strong>Arsène Wenger</xhtml:strong>, geboren am 22. Oktober 1949 in
Strassburg, ist einer der renommiertesten Fussballtrainer der
Welt.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/jochen-hecht.jpg" alt="Jochen Hecht" title="Jochen Hecht" />
<xhtml:p><xhtml:strong>Jochen Hecht</xhtml:strong>, geboren am 21. Juni 1977 in
Mannheim, ist ein deutscher Eishockeynationalspieler. Zurzeit
spielt der Stürmer in der weltbesten Eishockeyliga - der NHL.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/tania-cagnotto.jpg" alt="Tania Cagnotto" title="Tania Cagnotto" />
<xhtml:p><xhtml:strong>Tania Cagnotto</xhtml:strong>, geboren am 15. Mai 1985 in
Bozen, ist eine italienische Kunst- und Turmspringerin. Hier ist
die Vizewelt- und Europameisterin zwar total unbekannt, dies würde
sicher aber bestimmt rasch ändern. Und vielleicht zieht sich ja
dann auch für den Playboy aus.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:a id="musik" name="musik" />
<xhtml:h2>Musik</xhtml:h2>
<xhtml:p>Zugegeben, die Auswahl ist spärlich, aber die Scorpions kommen
halt nicht aus Baden-Württemberg.</xhtml:p>
<xhtml:p><xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/xavier-naidoo.jpg" alt="Xavier Naidoo" title="Xavier Naidoo" /></xhtml:p>
<xhtml:p><xhtml:strong>Xavier Naidoo</xhtml:strong>, geboren am 2. Oktober 1971 in
Mannheim, ist ein deutscher Schnulzensänger. Er ist in dieser Liste
weil die Masse seine Musik irgendwie mag...</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/max-herre.jpg" alt="Max Herre" title="Max Herre" />
<xhtml:p><xhtml:strong>Max Herre</xhtml:strong>, geboren am 22. April 1973 in
Stuttgart, ist ein deutscher Musiker, bekannt geworden als
Frontmann von Freundeskreis.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/kool-savas.jpg" alt="Kool Savas" title="Kool Savas" />
<xhtml:p><xhtml:strong>(King) Kool Savas</xhtml:strong>, geboren am 10. Februar 1975
in Aachen, ist laut HipHop-Magazin "Juice" einer der besten
deutschen MCs. Ausserdem ist er Vegetarierer, wodurch er meinen
voll krassen Respekt hat. Yo!</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:a id="sonstige" name="sonstige" />
<xhtml:h2>Sonstige</xhtml:h2>
<xhtml:p><xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/til-schweiger.jpg" alt="Til Schweiger" title="Til Schweiger" /></xhtml:p>
<xhtml:p><xhtml:strong>Til Schweiger</xhtml:strong>, geboren am 19. Dezember 1963 in
Freiburg im Breisgau, ist der deutsche Brad Pitt. 'Nuff said.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/marie-tussaud.jpg" alt="Marie Tussaud" title="Marie Tussaud" />
<xhtml:p><xhtml:strong>Marie Tussaud</xhtml:strong>, geboren am 12. Dezember 1761 in
Strassburg, war eine einflussreiche Wachsbildnerin. In London
gibt's eine bekannte Touristenattraktion die nach ihr benannt
wurde. Post mortem könnte man ihr den roten Ehrenpass vergeben.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/54/albert-schweitzer.jpg" alt="Albert Schweitzer" title="Albert Schweitzer" />
<xhtml:p><xhtml:strong>Albert Schweitzer</xhtml:strong>, geboren am 14. Januar 1875
in Kaysersberg, war ein französischer Friedensnobelpreisträger über
den ich jetzt mal nichts weiter schreibe. So bin ich.</xhtml:p>
<xhtml:div style="clear: left;" />
<xhtml:p>Ergänzungen bitte in die Kommentare. :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/54/2010-06-26/neue-buerger-braucht-das-land</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wenn PHP einfach nicht mit dem lokalen MySQL-Server verbinden will (Windows)]]></title>
    <published>2010-06-25T07:07:16+02:00</published>
    <updated>2010-06-25T07:07:16+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/qeuG2-U9940/wenn-php-einfach-nicht-mit-dem-lokalen-mysql-server-verbinden-will-windows" />
    <id>http://bigwhoop.ch/artikel/53/2010-06-25/wenn-php-einfach-nicht-mit-dem-lokalen-mysql-server-verbinden-will-windows</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Folgendes Script ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?php
new mysqli('localhost', 'root', '*********');
</xhtml:pre></xhtml:div>
<xhtml:p>... resultierte im Fehler:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Warning: mysqli::mysqli(): (HY000/2002): Ein Verbindungsversuch
ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten
Zeitspanne nicht richtig reagiert hat, oder die hergestellte
Verbindung war fehlerhaft, da der verbundene Host nicht reagiert
hat</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Über die Kommandozeile konnte ich mich aber problemlos mit dem
MySQL-Server verbinden.</xhtml:p>
<xhtml:p>Mr. Guughel riet mir dann anstatt <xhtml:code>localhost</xhtml:code> einfach
<xhtml:code>127.0.0.1</xhtml:code> zu verwenden, <xhtml:strong>was auch
funktionierte</xhtml:strong>.</xhtml:p>
<xhtml:p>Das war aber nur Symptombekämpfung und so suchte ich nach der
Ursache des Problems. Schlussendlich fand ich raus, dass das
Problem bei der Namensauflösung liegt.</xhtml:p>
<xhtml:p>In der <xhtml:code>hosts</xhtml:code>-Datei von Windows 7 steht nämlich:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
# localhost name resolution is handled within DNS itself.
#127.0.0.1       localhost
</xhtml:pre></xhtml:div>
<xhtml:p>Die Auflösung für <xhtml:code>localhost</xhtml:code> wird also nicht in der
<xhtml:code>hosts</xhtml:code>-Datei gemacht. Das ist kein Problem,
<xhtml:strong>solange man keine eigenen Hosts für <xhtml:code>127.0.0.1</xhtml:code>
definiert hat</xhtml:strong>. Denn dann steht die Zuweisung
<xhtml:code>127.0.0.1</xhtml:code> gleich <xhtml:code>localhost</xhtml:code> nicht mehr "an
erster Stelle" - und das mag MySQL (oder PHP?) überhaupt nicht.</xhtml:p>
<xhtml:p>Als einfache Lösung kann man also einfach <xhtml:strong>den Kommentare
für <xhtml:code>127.0.0.1</xhtml:code> in der <xhtml:code>hosts</xhtml:code>-Datei
entfernen</xhtml:strong> und <xhtml:strong>seine eigenen Hosts erst danach
definieren</xhtml:strong>.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/53/2010-06-25/wenn-php-einfach-nicht-mit-dem-lokalen-mysql-server-verbinden-will-windows</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Flattr Invites zu vergeben]]></title>
    <published>2010-06-12T10:00:00+02:00</published>
    <updated>2010-06-12T10:00:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/eC91VHcORJU/flattr-invites-zu-vergeben" />
    <id>http://bigwhoop.ch/artikel/50/2010-06-12/flattr-invites-zu-vergeben</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:object width="640" height="385"><xhtml:param name="movie" value="http://www.youtube.com/v/9zrMlEEWBgY&amp;hl=de_DE&amp;fs=1&amp;" />
<xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:embed src="http://www.youtube.com/v/9zrMlEEWBgY&amp;hl=de_DE&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385" /></xhtml:object></xhtml:p>
<xhtml:p>Über <xhtml:a href="http://flattr.com">Flattr</xhtml:a> muss ich gar nicht
mehr viele Worte verlieren, dass haben <xhtml:a href="http://uarrr.org/2010/04/26/von-flattr-facebook-und-fantastischen-visionen/">
andere</xhtml:a> schon zu genüge getan. Jedoch hab ich noch
<xhtml:del>zweieinen</xhtml:del>keinen <xhtml:em>Invite Code</xhtml:em> zu vergeben.
<xhtml:del>Bei Interesse einfach kurz hier einen Kommentar hinterlassen.
:-)</xhtml:del></xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/50/2010-06-12/flattr-invites-zu-vergeben</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Webapplikationsupdate trotz Wartungsseite testen]]></title>
    <published>2010-06-03T10:00:00+02:00</published>
    <updated>2010-06-03T10:00:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/Rqwc-F_eu00/webapplikationsupdate-trotz-wartungsseite-testen" />
    <id>http://bigwhoop.ch/artikel/49/2010-06-03/webapplikationsupdate-trotz-wartungsseite-testen</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Heute kam die Frage auf, wie wir morgen ein grösseres Update
unserer Webapplikation durchführen und testen können, ohne dass
unsere Kundschaft in Server-Fehler und Exceptions reinläuft.
Schnell war klar, dass wir die Webseite in den Wartungsmodus setzen
müssen. Damit wir als Entwickler während dieses Updates aber
trotzdem auf die Webseiten zugreifen können, hab ich mir folgende
Lösung ausgedacht:</xhtml:p>
<xhtml:p><xhtml:strong>Die Entwickler senden einen speziellen HTTP Request
Header, wodurch sie nicht auf die Wartungsseite weitergeleitet
werden.</xhtml:strong></xhtml:p>
<xhtml:p>Manchmal sind Lösung echt simpel ... ;-)</xhtml:p>
<xhtml:a id="eigenen-http-request-header-senden" name="eigenen-http-request-header-senden" />
<xhtml:h2>Eigenen HTTP Request Header senden</xhtml:h2>
<xhtml:p>Bestimmt gibt es auch andere Tools, doch wir haben uns für das
Firefox-Addon <xhtml:a href="https://addons.mozilla.org/en-US/firefox/addons/policy/0/967/50889?src=addondetail">
Modify Headers</xhtml:a> entschieden. Dieses Addon ist schlicht gehalten
und einfach zu bedienen.</xhtml:p>
<xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/49/modify-headers.png" alt="Modify Headers Screenshot" /></xhtml:p>
<xhtml:p>Oben wählt ihr zuerst die Action aus. In unserem Fall ist das
<xhtml:code>Add</xhtml:code>, da wir einen neuen Header hinzufügen wollen.
Danach kommt der Name des Headers, der natürlich eindeutig sein
sollte. Also zum Beispiel <xhtml:code>X-MyProject-Maintenance</xhtml:code>.
Danach folgt der Wert des Headers. Empfehlenswert ist eine längere
Zeichenkette, die nicht erraten werden kann. Zum Schluss kommt noch
ein Kommentarfeld, dass ihr aber auch leer lassen könnt.</xhtml:p>
<xhtml:p>Nach dem Klick auf <xhtml:strong>Add</xhtml:strong> erscheint der Wert unten
in der Liste. Durch einen Doppelklick oder die Buttons rechts,
könnt ihr den Header aktivieren, bzw. deaktivieren.
<xhtml:strong>Achtung: Wenn ihr <xhtml:em>Modify Headers</xhtml:em> schliesst, wird
der erstellte Header nicht mehr mitgeschickt.</xhtml:strong></xhtml:p>
<xhtml:a id="rewriting" name="rewriting" />
<xhtml:h2>Rewriting</xhtml:h2>
<xhtml:p>Da wir mit Zend Framework arbeiten haben wir eh schon
<xhtml:strong>mod_rewrite</xhtml:strong> im Einsatz. Deshalb gehe ich jetzt
auch nur darauf ein.</xhtml:p>
<xhtml:p>Was wir jetzt noch wollen sind zwei Dinge:</xhtml:p>
<xhtml:ol>
<xhtml:li>Alle Requests auf die Wartungsseite weiterleiten</xhtml:li>
<xhtml:li>Ausnahme: Wenn ein Request mit unserem speziellen Header daher
kommt</xhtml:li>
</xhtml:ol>
<xhtml:p>Ersteres wird mit folgender Rewrite Rule bewerkstelligt:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
RewriteRule ^.*$ maintenance.php [NC,L]
</xhtml:pre></xhtml:div>
<xhtml:p>Das Zweite mit der folgenden Rewrite Condition direkt oberhalb
der Rewrite Rule:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
RewriteCond %{HTTP:X-MyProject-Maintenance} !^super-secret-key$
</xhtml:pre></xhtml:div>
<xhtml:p>Mit Zend Framework sieht das dann zum Beispiel so aus:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
# Ignore static resources
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

# Show maintenance page
RewriteCond %{HTTP:X-MyProject-Maintenance} !^super-secret-key$
RewriteRule ^.*$ maintenance.php [NC,L]

# Rewrite everything to the bootstrapper
RewriteRule ^.*$ index.php [NC,L]
</xhtml:pre></xhtml:div>
<xhtml:a id="zwischen-wartungs-und-live-modus-hin-und-herschalten" name="zwischen-wartungs-und-live-modus-hin-und-herschalten" />
<xhtml:h2>Zwischen Wartungs- und Live-Modus hin- und herschalten</xhtml:h2>
<xhtml:p>Um in den Live-Modus zu wechseln, kommentiert ihr einfach die
beiden <xhtml:code>.htaccess</xhtml:code>-Zeilen aus. Für den Wartungsmodus
entfernt ihr die <xhtml:code>#</xhtml:code>s einfach wieder.</xhtml:p>
<xhtml:p>So, ich hoffe das hilft irgendwem. Für alternative Ideen bin ich
natürlich offen. :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/49/2010-06-03/webapplikationsupdate-trotz-wartungsseite-testen</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Doctrine Flagable Behavior/Template]]></title>
    <published>2010-05-28T13:55:21+02:00</published>
    <updated>2010-05-28T13:55:21+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/PR93im3RD0g/doctrine-flagable-behaviortemplate" />
    <id>http://bigwhoop.ch/artikel/48/2010-05-28/doctrine-flagable-behaviortemplate</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Doctrine 1.2 ist mein bevorzugter OR-Mapper für PHP. Durch
sogenannte <xhtml:a href="http://www.doctrine-project.org/projects/orm/1.2/docs/manual/behaviors/en#behaviors">
Behaviors</xhtml:a> lassen sich Models mit Funktionalität, als auch
Struktur erweitern. Diese Behaviors werden im Datenbankschema an
beliebige Tabellen angehängt und klinken sich dann sowohl bei der
Generierung der Datenbankstruktur, also auch zur Script-Laufzeit
ein.</xhtml:p>
<xhtml:a id="was-sind-flags" name="was-sind-flags" />
<xhtml:h2>Was sind Flags?</xhtml:h2>
<xhtml:p>Stellen wir uns als Beispiel eine Tabelle <xhtml:code>messages</xhtml:code>
vor. Diese könnte wie folgt aussehen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
+----------------------+--------------+
| Feld                 | Typ          |
+----------------------+--------------+
| id                   | INTEGER(6)   |
| sender_id            | INTEGER(3)   |
| recipient_id         | INTEGER(3)   |
| subject              | VARCHAR(255) |
| message              | TEXT         |
| sent_at              | TIMESTAMP    |
| read                 | TINYINT(1)   |
| favored              | TINYINT(1)   |
| deleted_by_sender    | TINYINT(1)   |
| deleted_by_recipient | TINYINT(1)   |
+----------------------+--------------+
</xhtml:pre></xhtml:div>
<xhtml:p>Etwas was ich bei Tabellen öfters verwende ist ein
<xhtml:code>flags</xhtml:code>-Feld. Mit diesem kann ich obige bool'schen
Felder in ein einziges Feld packen. Dies geschieht mit Hilfe einer
<xhtml:a href="http://de.wikipedia.org/wiki/Bitmaske">Bitmaske</xhtml:a>.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
+--------------+--------------+
| Feld         | Typ          |
+--------------+--------------+
| id           | INTEGER(6)   |
| sender_id    | INTEGER(3)   |
| recipient_id | INTEGER(3)   |
| subject      | VARCHAR(255) |
| message      | TEXT         |
| sent_at      | TIMESTAMP    |
| flags        | INTEGER(6)   |
+--------------+--------------+

FLAG_READ                 = 1
FLAG_FAVORED              = 2
FLAG_DELETED_BY_SENDER    = 4
FLAG_DELETED_BY_RECIPIENT = 8
</xhtml:pre></xhtml:div>
<xhtml:p>Möchte ich nun die Nachricht als gelesen und vom Empfänger
gelöscht markieren, setze ich dem <xhtml:code>flags</xhtml:code>-Feld den Wert
<xhtml:code>9</xhtml:code> (<xhtml:code>1</xhtml:code> + <xhtml:code>8</xhtml:code>). Dieser Wert ist
eindeutig für diesen beiden Flags. Er lässt sich mit keiner anderen
Kombinationen der Zahlen <xhtml:code>1</xhtml:code>, <xhtml:code>2</xhtml:code>,
<xhtml:code>4</xhtml:code> und <xhtml:code>8</xhtml:code> bilden.</xhtml:p>
<xhtml:p>Der grosse Vorteil eines <xhtml:code>flags</xhtml:code>-Feldes ist, dass man
neue Flags hinzufügen kann, ohne die Datenbankstruktur verändern zu
müssen. Per Bit-Operatoren lassen sich die Flags ausserdem auf
simple Weise testen. Weiter in die Thematik von Bitmasken möchte
ich aber gar nicht eingehen, dafür gibt's genügend gute Ressourcen
im Internet. :-)</xhtml:p>
<xhtml:a id="api" name="api" />
<xhtml:h2>API</xhtml:h2>
<xhtml:p>Die <xhtml:code>PHPhil_Doctrine_Template_Flagable</xhtml:code>-Klasse bietet
das Folgende:</xhtml:p>
<xhtml:a id="konfigurationsoptionen" name="konfigurationsoptionen" />
<xhtml:h3>Konfigurationsoptionen</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
+---------+-------------+----------------------+-------------------------------+
| Name    | Typ         | Standardwert         | Beschreibung                  |
+---------+-------------+----------------------+-------------------------------+
| name    | string      | 'flags'              | Name des Feldes               |
| alias   | string|null | null                 | Name der Klasseneigenschaft   |
| type    | string      | 'int'                | Typ des Feldes                |
| length  | int         | 12                   | Grösse des Feldes             |
| options | array       | array(               | Sonstige Doctrine-spezifische |
|         |             |   'default' =&gt; 0,    | Optionen des Feldes           |
|         |             |   'notnull' =&gt; true, |                               |
|         |             | )                    |                               |
+---------+-------------+----------------------+-------------------------------+
</xhtml:pre></xhtml:div>
<xhtml:a id="an-models-vererbte-methoden" name="an-models-vererbte-methoden" />
<xhtml:h3>An Models "vererbte" Methoden</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
+----------------------+-----------------+--------------------------------------------+
| Methode              | Rückgabewert    | Beschreibung                               |
+----------------------+-----------------+--------------------------------------------+
| getFlags()           | int             | Gibt den Wert des Feldes zurück            |
| setFlags(int $flags) | Doctrine_Record | Setzt den Wert des Feldes                  |
| hasFlag(int $flag)   | boolean         | Prüft ob ein bestimmtes Flag gesetzt wurde |
| setFlag(int $flag)   | Doctrine_Record | Setzt ein bestimmtes Flag                  |
| unsetFlag(int $flag) | Doctrine_Record | Entfernt ein gesetztes Flag                |
| getFlagConstants()   | array           | Gibt alle Klassenkonstanten mit einem      |
|                      |                 | bestimmten Prefix zurück. Komfortfunktion. |
+----------------------+-----------------+--------------------------------------------+
</xhtml:pre></xhtml:div>
<xhtml:a id="anwendungsbeispiel" name="anwendungsbeispiel" />
<xhtml:h2>Anwendungsbeispiel</xhtml:h2>
<xhtml:a id="konfiguration-im-schemayml" name="konfiguration-im-schemayml" />
<xhtml:h3>Konfiguration im schema.yml</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
Message:
  tableName: messages
  columns:
    id:
      type: in...
  actAs:
    PHPhil_Doctrine_Template_Flagable:
</xhtml:pre></xhtml:div>
<xhtml:a id="model-erweitern" name="model-erweitern" />
<xhtml:h3>Model erweitern</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Message extends BaseMessage
{
    const FLAG_READ                 = 1;
    const FLAG_FAVORED              = 2;
    const FLAG_DELETED_BY_SENDER    = 4;
    const FLAG_DELETED_BY_RECIPIENT = 8;

    public function isRead()
    {
        return $this-&gt;hasFlag(self::FLAG_READ);
    }

    public function markAsRead()
    {
        $this-&gt;setFlag(self::FLAG_READ)
             -&gt;save();

        return $this;
    }

    public function markAsUnread()
    {
        $this-&gt;unsetFlag(self::FLAG_READ)
             -&gt;save();

        return $this;
    }
}
</xhtml:pre></xhtml:div>
<xhtml:a id="code" name="code" />
<xhtml:h2>Code</xhtml:h2>
<xhtml:p>Und hier nun der eigentliche Code. Viel Spass!</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class PHPhil_Doctrine_Template_Flagable extends Doctrine_Template
{
    /**
     * @var array
     */
    protected $_options = array(
        'name'    =&gt; 'flags',
        'alias'   =&gt; null,
        'type'    =&gt; 'int',
        'length'  =&gt; 12,
        'options' =&gt; array(
            'default' =&gt; 0,
            'notnull' =&gt; true,
        ),
    );


    /**
     * Add field to table
     */
    public function setTableDefinition()
    {
        $name = $this-&gt;getOption('name');
        if ($this-&gt;getOption('alias')) {
            $name .= ' as ' . $this-&gt;getOption('alias');
        }

        $this-&gt;hasColumn($name, $this-&gt;getOption('type'), $this-&gt;getOption('length'), $this-&gt;getOption('options'));
    }


    /**
     * Return all flags
     * 
     * @return int
     */
    public function getFlags()
    {
        return (int)$this-&gt;getInvoker()-&gt;get($this-&gt;getOption('name'));
    }


    /**
     * Set the 'flags' property
     * 
     * @param int flags
     * @return Doctrine_Record
     */
    public function setFlags($flags)
    {
        $this-&gt;getInvoker()-&gt;set($this-&gt;getOption('name'), (int)$flags);

        return $this-&gt;getInvoker();
    }


    /**
     * Check if a specifc flag is set
     * 
     * @param int $flag
     * @return boolean
     */
    public function hasFlag($flag)
    {
        return (bool)($this-&gt;getFlags() &amp; (int)$flag);
    }


    /**
     * Set a specific flag
     *
     * @param int $flag
     * @return Doctrine_Record
     */
    public function setFlag($flag)
    {
        $this-&gt;setFlags((int)$flag | $this-&gt;getFlags());

        return $this-&gt;getInvoker();   
    }


    /**
     * Delete a specific flag
     *
     * @param int $flag
     * @return Doctrine_Record
     */
    public function unsetFlag($flag)
    {
        $this-&gt;setFlags($this-&gt;getFlags() &amp; ~(int)$flag);

        return $this-&gt;getInvoker();
    }


    /**
     * Return all constants of the model beginning with a specific needle
     * 
     * @param string $needle
     * @return array
     */
    public function getFlagConstants($needle = 'FLAG_')
    {
        $flags = array();

        $reflection = new ReflectionClass($this-&gt;getInvoker());
        foreach ($reflection-&gt;getConstants() as $name =&gt; $value) {
            if (0 === strpos($name, $needle)) {
                $flags[$name] = $value;
            }
        }

        return $flags;
    }
}
</xhtml:pre></xhtml:div>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/48/2010-05-28/doctrine-flagable-behaviortemplate</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Kinobar für TV Serien]]></title>
    <published>2010-05-26T21:50:18+02:00</published>
    <updated>2010-05-26T21:50:18+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/XJW3uqL2b3U/kinobar-fuer-tv-serien" />
    <id>http://bigwhoop.ch/artikel/47/2010-05-26/kinobar-fuer-tv-serien</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Willkommen zur neuen Rubrik "Ideen". In dieser möchte ich in
Zukunft Hirngespinste aus allen möglichen Bereichen des Lebens
zusammenfassen. Los geht's heute mit der "Kinobar für
TV-Serien".</xhtml:p>
<xhtml:a id="die-idee" name="die-idee" />
<xhtml:h2>Die Idee</xhtml:h2>
<xhtml:p>Zugegeben, ich bin ein Serienjunkie! Bei LOST nahm dieses Hobby
seinen Höhepunkt, aber schon Jahre zuvor konnte ich alle
Friends-Episoden in- und auswendig. Von Begleitern meiner Jungend
wie den Simpsons will ich jetzt gar nicht anfangen. Ups. Egal.</xhtml:p>
<xhtml:p>Jedenfalls kenne ich persönliche wenige (bis gar keine)
Menschen, die dieses Hobby teilen und erst noch auf das selbe Zeugs
stehen wie ich (Testees. Flight of the Conchords. Anyone?).
Meistens macht ein gemeinsames Mitfiebern und Lachen aber mehr
Spass. Bier und eine Grossleinwand würden ihr Übriges tun.</xhtml:p>
<xhtml:p>Rechnen wir zusammen: <xhtml:strong>Grossleinwand</xhtml:strong>
<xhtml:strong>Bier</xhtml:strong> (wahlweise auch Gin Buck)
<xhtml:strong>TV-Serien</xhtml:strong><xhtml:br />
Ergebnis: <xhtml:strong>Die Kinobar für TV-Serien</xhtml:strong></xhtml:p>
<xhtml:a id="das-lokal" name="das-lokal" />
<xhtml:h2>Das Lokal</xhtml:h2>
<xhtml:p>Eine offener, geräumiger Raum mit grosser Kinoleinwand. Es gibt
verschiedene Nischen (für konzentrierte Zuschauer, für gesellige
Gruppen, etc), normale Steh- und Sitzplätze und eine Theke/Bar wo
nebst Getränken natürlich auch Popcorn, Chips, Pizza, etc. serviert
wird.</xhtml:p>
<xhtml:a id="preis" name="preis" />
<xhtml:h2>Preis</xhtml:h2>
<xhtml:p>Eventuell gibt es eine kleine Eintrittsgebühr (so um die CHF
5.-). Hauptfinanzierung soll aber durch den Umsatz von Verpflegung
gemacht werden. Als Anreiz gibt es pro gekauftes Nahrungsmittel
einen kleinen Zettel mit Barcode/Nummer. Mit dieser lässt sich
online (Homepage, Smartphone-App, etc.) abstimmen, welche Serie
(evtl. Episode) wann gespielt werden soll.</xhtml:p>
<xhtml:a id="die-serien" name="die-serien" />
<xhtml:h2>Die Serien</xhtml:h2>
<xhtml:p>Bestenfalls werden die Serien vor oder zeitgleich zur
TV-Premiere gezeigt. Es gibt aber auch viele alte Klassiker, die
auch heute noch Spass machen. Weiter könnte man Themenabende
einführen, Serienroulette spielen oder Specials veranstalten, usw.
Die Möglichkeiten sind da fast unbegrenzt. "Fast". ;-)</xhtml:p>
<xhtml:a id="die-probleme" name="die-probleme" />
<xhtml:h2>Die Probleme</xhtml:h2>
<xhtml:p>Das grösste Problem nebst der Finanzierung (wie will man all
diese Gebühren bezahlen?!) ist wohl die rechtliche Lage. Da ich
mich da überhaupt nicht auskenne, machts auch nicht gross Sinn was
Genaueres dazu zu schreiben. Stelle es mir jedenfalls schwierig
vor, sich gegen Fernsehstationen und all die verschiedenen
Produzenten und Vertriebshäuser zu behaupten.</xhtml:p>
<xhtml:p>Das war's fürs Erste. Kommentare und haufenweise Zaster sind
erwünscht! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/47/2010-05-26/kinobar-fuer-tv-serien</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[WPA Key mit Sonderzeichen unter Ubuntu]]></title>
    <published>2009-11-02T10:45:00+01:00</published>
    <updated>2009-11-02T10:45:00+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/TlCpols3NLc/wpa-key-mit-sonderzeichen-unter-ubuntu" />
    <id>http://bigwhoop.ch/artikel/44/2009-11-02/wpa-key-mit-sonderzeichen-unter-ubuntu</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Nehmen wir an, ich möchte folgendes drahtlose Netzwerk
einrichten:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
SSID: BlindMelon
WPA Key: SieSagenDieGrösseSpieleKeineRolle
</xhtml:pre></xhtml:div>
<xhtml:p>So weit ich das Problem verstanden habe, liegt der Fehler dort,
dass die meisten Router nocht mit ISO 8859-1 arbeiten, Ubuntu aber
standardmässig mit UTF-8. Dadurch wird der von Hand eingegebene Key
aber falsch übermittelt.</xhtml:p>
<xhtml:p>Die Lösung liegt darin, dass anstelle des lesbaren Keys auch ein
64-stelliger Hexstring genutzt werden kann. Um diesen zu berechnen
kann man unter Ubuntu das kleine CLI-Tool
<xhtml:code>wpa_passphrase</xhtml:code> nutzen.</xhtml:p>
<xhtml:p>Und so funktionierts ...</xhtml:p>
<xhtml:p>1) Wir öffnen erstmal ein Terminal.</xhtml:p>
<xhtml:p>2) Danach setzen wir das Encoding des Terminals auf ISO
8859-1.</xhtml:p>
<xhtml:p>3) Anschliessen tippen wir <xhtml:code>wpa_passphrase BlindMelon
SieSagenDieGrösseSpieleKeineRolle</xhtml:code> ein und erhalten folgende
Ausgabe:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
network={
    ssid="BlindMelon"
    #psk="SieSagenDieGrösseSpieleKeineRolle"
    psk=b9a67b4c042a391fc44ba8ad81c2010d41bf699cd5c5f95a60056fda58724ead
}
</xhtml:pre></xhtml:div>
<xhtml:p>4) Die Zeile mit <xhtml:code>psk=b9a...</xhtml:code> ist nun der Key von
Interesse und welchen wir anstelle des lesbaren Keys verwenden
können.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/44/2009-11-02/wpa-key-mit-sonderzeichen-unter-ubuntu</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Die Ethik der Programmierer]]></title>
    <published>2009-08-13T00:39:36+02:00</published>
    <updated>2009-08-13T00:39:36+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/zsbxb5GlwuY/die-ethik-der-programmierer" />
    <id>http://bigwhoop.ch/artikel/40/2009-08-13/die-ethik-der-programmierer</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Zuerst möchte ich das Thema von Programmierern auf einen
speziellen Teil der IT ausweiten: Die geliebten Sysadmins.</xhtml:p>
<xhtml:p>Aus Erfahrung haben Mitarbeiter der IT grundsätzlich mehr
Zugriffsrechte als normale Angestellte. Diese Rechte beziehen sich
nicht nur auf "digitale Rechte", sondern z.B. auch auf Zugang zu
Bereichen des Firmengeländes. Wie soll ein Router gewartet werden,
wenn der Techniker keinen Zutritt hat?! Ausserdem haben
IT-Mitarbeiter in der Regel Zugriff auf  sehr sensible Daten:
Buchhaltung, Passwörter, E-Mails, etc. Programmierer bringen
desweiteren eine grosse Verantwortung mit, wenn sie mit diesen
Daten etwas machen sollen. Unsichere Software kann da schon mal
geschäftskritisch sein.</xhtml:p>
<xhtml:p>Bei meinem letzten Arbeitgeber wurde eine Buchhalterin per
sofort freigestellt, als man sich entschloss, das Arbeitsverhältnis
aufzulösen. Ich lies mir sagen, dass dies in solch kritischen
Geschäftsbereichen normal ist. Gleichzeitig musste ich aber auch
die Stirn runzeln und mich selbst fragen: "Wissen die da oben
überhaupt, welches Wissen und welche "Macht" ich habe oder ohne
weiteres erlangen kann?"</xhtml:p>
<xhtml:p>Die Frage ist jetzt, ob sich Firmen dieses Risikos nicht bewusst
sind, nichts dagegen unternehmen wollen oder schlicht damit Leben
müssen? Da mich letzteres schockieren würde tippe ich trotz meiner
relativ kurzen Berufserfahrung auf ersteres und hoffe, dass sich
dieser Umstand in Zukunft ändern wird.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/40/2009-08-13/die-ethik-der-programmierer</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Wie ich Zend Certified Engineer wurde (mit Gewinnspiel)]]></title>
    <published>2009-08-12T18:01:25+02:00</published>
    <updated>2009-08-12T18:01:25+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/uR-G5x83ES0/wie-ich-zend-certified-engineer-wurde-mit-gewinnspiel" />
    <id>http://bigwhoop.ch/artikel/39/2009-08-12/wie-ich-zend-certified-engineer-wurde-mit-gewinnspiel</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:a id="mein-vorwissen" name="mein-vorwissen" />
<xhtml:h2>Mein Vorwissen</xhtml:h2>
<xhtml:p>Zur Zeit bin ich 22 Jahre alt. Angefangen PHP zu programmieren
habe ich irgendwann zwischen 2001 und 2002, also mit etwa 14/15
Jahren. Es müsste demnach eine 4.1.x Version von PHP gewesen sein.
Ziemlich lange war dieses Interesse aber sehr oberflächlich.
Während meiner Ausbildung lernte ich vor allem ASP und C , wodurch
PHP zum Hobby verkam. Nach der Ausbildung und während meiner ersten
beruflichen Tätigkeit begann das Interesse an PHP zu wachsen.
Gründe waren die tollen, neuen Möglichkeiten von PHP 5 und die
Tatsache, dass es mein damaliger Arbeitgeber verpasste von ASP (in
meinen Augen einfach nur eine Zangengeburt) auf ASP.NET zu
wechseln. Unterm Strich war PHP einfach anwenderfreundlich,
leistungsstark und ... gratis!</xhtml:p>
<xhtml:p>Zwar kannte ich objektorientierte Programmierung aus C etwas,
einen tieferen Einblick erlangte ich aber erst mit PHP 5(.1). In
dieser Zeit begann ich auch mich vermehrt mit weiterführenden
Themen der Programmierung zu befassen: Design Patterns (MVC, ARP),
Security, Caching, usw.</xhtml:p>
<xhtml:p>Von Sommer 2007 an arbeitete ich dann zwei Jahre bei einem
Arbeitgeber wo ich endlich PHP beruflich programmieren konnte.
Durch ein sehr abwechslungsreiches und grosses Projekt und dank
meines direkten Mitarbeiters im Backend-Bereich, der mich ständig
mitzog, konnte ich sehr, sehr viel lernen. Ich lernte das Zend
Framework kennen (und damit viele gute Ansätze in Sachen
Webdevelopment), Propel ORM und vor allem all die kleinen Dinge die
man nicht auflisten kann. In meiner Freizeit beschäftigte ich mich
ebenfalls stetig mit dem gesamten Spektrum von <xhtml:a class="DefaultLink" href="http://de.wikipedia.org/wiki/Webwork" target="_blank">Webwork</xhtml:a> und versuchte mich stetig
weiterzuentwicklen.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Zusammenfassend hatte ich ein gutes, umfassendes Vorwissen in
PHP und vor allem OOP (in PHP). Wegen der Benutzung von
Fremdbibliotheken und Frameworks und der dahingehenden Abstraktion
verlor ich mit der Zeit aber etwas den Bezug zu den Basics. Als
Beispiel nenne ich da jetzt mal die mysql<xhtml:em>*- oder neueren
mysqli</xhtml:em>*-Funktionen (PDO ist eh das einzige Wahre :P).</xhtml:p>
</xhtml:blockquote>
<xhtml:a id="meine-vorbereitung" name="meine-vorbereitung" />
<xhtml:h2>Meine Vorbereitung</xhtml:h2>
<xhtml:p>Anfangs 2009 spielte ich erstmals mit dem Gedanken die Zend
Zertifizierung zu machen. Dieser Gedanke wurde aber nie richtig
konkret und so ging er in Vergessenheit. Per Ende Juni kündigte ich
dann meine damalige Arbeitsstelle und die Idee zur Zertifizierung
kam zwecks Stellensuche und sinnvoller Freizeitgestaltung wieder
auf.</xhtml:p>
<xhtml:p>Zuerst begann ich im Internet nach Erfahrungsberichten zu
suchen. Diese beinhalteten allerdings meisten nur den Tipp, einfach
das PHP Manual Wort für Wort zu lesen. So blöd es klingt, dieser
Tipp ist in der Tat der beste, um sich das am Testtag gefragte
Wissen über PHP anzueignen. Wie sinnvoll dieses Wissen ist, sei
dahingestellt. Es ist aber durchaus von Vorteil wenn man z.B. weiss
in welcher Reihenfolge bei bekannten String-Funktionen die
Parameter erwartet werden oder wann und wie PHP die Datentypen
dynamisch wechselt. Viel dieses Wissens ist in der Praxis nicht
wirklich von Nöten, da man z.B. dank Autocomplete nicht alle
Funktionen auswendig kennen muss und schon gar nicht, in welcher
Reihenfolge die Argumente erwartet werden (PHP ist da ja nicht
gerade sehr konsistent).</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Dennoch: Manual gut lesen! Man muss die Stream-Funktionen
kennen, das PHP 5 OO Model, die Unterschiede zwischen PHP 4 und 5,
all die verschiedenen XML Parser und vor allem die gesamten Basics
wie Syntax, Datentypen (Arrays!), usw.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Damit ich mir ein Bild machen konnte wie die Prüfung abläuft,
kaufte ich zehn ZCE Mock Exams (fünf davon habe ich noch und werde
sie am Ende dieses Artikels als kleines Gewinnspiel ausschreiben).
Der Test findet am Computer statt und man wird mit Single Choice-,
Multiple Choice- und Freetext-Fragen konfrontiert. Bei Multiple
Choice-Fragen steht jeweils wie viele Antworten erwartet werden und
bei den Freetext-Aufgaben muss man jeweils nur ein Wort schreiben,
z.B. "Singleton". Der Test besteht aus 70 Fragen, wofür man 90
Minuten Zeit hat. Man kann jede Frage am Ende des Tests nochmals
öffnen und ändern.</xhtml:p>
<xhtml:p>Diese Probeexamen lernten mich vor allem eines: Man muss an das
Undenkbare denken! Es werden Fragen gestellt, die auf absichtlichem
Missbrauch von PHP basieren. Ausserdem halfen mir die Teste mich
besser auf meine Schwächen konzentrieren zu können und sie gaben
mir auch immer wieder Schlagwörter, die mich zu neuen Erkenntnissen
führten. Zum Beispiel "Cross-Site Request Forgery". Ein paar
<xhtml:a class="DefaultLink" href="http://bigwhoop.ch/artikel/28/2009-07-07/Some-ZCE-Mock-Exam-Questions" target="_blank">Beispielfragen</xhtml:a> habe ich in meinem Blog bereits
gepostet.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Vom Niveau her fand ich die eigentliche Prüfung etwas
schwieriger als die Probeexamen. Da diese aber nicht allzu teuer
sind, kann ich jedem nur empfehlen, drei bis fünf Tests zu kaufen.
Mehr braucht's nicht! Ausserdem wiederholen sich die Fragen dann
schon ...</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Etwa zwei Wochen beschäftigte ich mich intensiv (damit meine ich
vielleicht zwei Stunden/Tag) mit der Prüfungsvorbereitung. Danach
viel ich irgendwie wieder in ein kleines Loch, worauf ich mich
spontan in den frühen Morgenstunden (nach einem Samstagabend ...)
für den Test anmeldete - für den kommenden Mittwoch. Die nächsten
drei Tage lernte ich deshalb nochmals fleissig, machte noch einen
Probeexamen und freute mich dann ganz entspannt auf die Prüfung.
:P</xhtml:p>
<xhtml:a id="meine-pruefung" name="meine-pruefung" />
<xhtml:h2>Meine Prüfung</xhtml:h2>
<xhtml:p>Besagten Mittwoch um 10:30 Uhr stand ich auf der Matte eines
Pearson VUE Testcenters in Bern. Pearson VUE führt für Zend die
Examen in zertifizierten Testcentern durch. Dies hat den Vorteil,
dass man sogar in jeder grösseren Schweizer Stadt die
Zertifizierung machen kann. Sehr praktisch, da man sich Ort, Datum
und Zeit ziemlich flexibel aussuchen kann.</xhtml:p>
<xhtml:p>Nach einem Schluck Wasser und meiner Unterschrift unter dem
Antrittsformular wurde ich auch schon in einen Raum voller Computer
geführt. Nebst mir waren nur etwa zwei weitere Personen anwesend,
die aber (ziemlich sicher) eine andere Zertifizierung machten. Ein
Aufseher war nicht im Raum, jedoch wurde der Raum Kameraüberwacht.
Ich fand die Atmosphäre allerdings sehr entspannt und ich konnte
mich gut konzentrieren.</xhtml:p>
<xhtml:p>Was mir etwas Probleme bereitete, war, dass ich den Test auf
Deutsch machte, obwohl ich mich ganzheitlich auf Englisch
vorbereitete. Gewisse Fachbegriffe klangen einfach komisch und ich
übersetzte mir die Fragen desöfteren ins Englische, damit ich ein
besseres Verständnis erlangte. Je nach Englischkenntnissen würde
ich also empfehlen, den Test auf Englisch zu machen.<xhtml:br />
Ausserdem gab es eine Multiple Choice-Frage die laut Fragestellung
drei Antworten erwartete, man aber nur zwei auswählen konnte. Die
etwas überforderte Angestellte des Testcenters konnte mir dabei
auch nicht wirklich helfen (nach dem Motto: "Reboot tut immer
gut").</xhtml:p>
<xhtml:p>Die 90 Minuten waren - wie schon bei den Probeexamen - mehr als
gut berechnet und so konnte ich ohne Probleme nochmals alle Fragen
durchgehen und trotzdem frühzeitig beenden (etwa nach 70 - 75
Minuten). Die Schwierigkeit des Tests würde ich als
"fortgeschritten" einstufen. Man muss sicher kein Profi sein, wer
sich jedoch nicht tiefer mit der Sprache beschäftigt, wird kaum
eine Chance haben.</xhtml:p>
<xhtml:p>Und ja, erfreulicherweise bestand ich und seit dem 22. Juli darf
ich mich offiziell "Zend Certified Engineer" nennen. :-)</xhtml:p>
<xhtml:p>@See: <xhtml:a class="DefaultLink" href="http://www.zend.com/zce.php?c=ZEND011434&amp;r=231232923" target="_blank">Mein ZCE Profil</xhtml:a></xhtml:p>
<xhtml:p>Fragen beantworte ich natürlich gerne in den Comments!</xhtml:p>
<xhtml:a id="gewinnspiel" name="gewinnspiel" />
<xhtml:h2>Gewinnspiel</xhtml:h2>
<xhtml:p><xhtml:del>Wie geschrieben habe ich noch fünf offene Testexamen zu
verschenken.</xhtml:del> Per Twitter (@phphil) möchte ich deshalb gerne
wissen, an welchem Wochentag ich mich für den Test angemeldet
(nicht teilgenommen) habe. Sobald ein paar Teilnahmen eingegangen
sind, werde ich einen Gewinner auslosen. Viel Glück!</xhtml:p>
<xhtml:p><xhtml:strong>Herzlichen Glückwunsch an <xhtml:a href="http://twitter.com/benni3005">Benni Hofmann</xhtml:a>! Die richtige
Antwort war natürlich <xhtml:em>Sonntag</xhtml:em>.</xhtml:strong></xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/39/2009-08-12/wie-ich-zend-certified-engineer-wurde-mit-gewinnspiel</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[FizzBuzz, Baby!!!]]></title>
    <published>2009-07-29T11:00:52+02:00</published>
    <updated>2009-07-29T11:00:52+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/J0ZFu6iuUNE/fizzbuzz-baby" />
    <id>http://bigwhoop.ch/artikel/35/2009-07-29/fizzbuzz-baby</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Das Thema ist zwar schon etwas älter, hat mich aber erst jetzt
erreicht.</xhtml:p>
<xhtml:p>Eine These besagt, dass Programmierer die einfache Probleme
nicht lösen können, auch ihre Mühe mit komplexe(re)n Problemen
haben - selbst wenn sie seit langem programmieren und als erfahren
gelten. Dies soll sich vorallem durch lange Entwicklungszeit
ausdrücken.</xhtml:p>
<xhtml:p>Da sich auf ausgeschriebene Stellen scheinbar viele
Interessenten bewerben (keine Ahnung inwiefern man dies auf Europa
und speziell aufs Webdevelopment übertragen kann), hat <xhtml:a class="DefaultLink" href="http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/" target="_blank">ein gewitzer, junger Herr namens Imran</xhtml:a> ein
Kinderspiel für die Softwareentwicklung adaptiert: Die sogenannten
FizzBuzz Fragen.</xhtml:p>
<xhtml:p>Dazu nennt er ein Beispiel, welches von einem Bewerber während
des Vorstellungsgespräches gelöst werden soll:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Write a program that prints the numbers from 1 to 100. But for
multiples of three print “Fizz” instead of the number and for the
multiples of five print “Buzz”. For numbers which are multiples of
both three and five print “FizzBuzz”.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Frei übersetzt ...</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Schreibe eine Anwendung, welche die Nummern 1 bis 100 ausgibt.
Anstelle von Vielfachen von 3 soll aber das Wort "Fizz", anstelle
von Vielfachen von 5 das Wort "Buzz" und anstelle von Vielfachen
von 3 und 5 das Wort "FizzBuzz" ausgegeben werden.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Laut mehreren Posts in der Blogosphäre scheinen an dieser doch
relativ einfachen Aufgabe viele, viele Anwärter zu scheitern, bzw.
mehr als 10 Minuten zu brauchen. Klingt aus meiner Sicht
unglaublich ...</xhtml:p>
<xhtml:p>Mehr gibt es nach dem <xhtml:a href="http://bigwhoop.ch/artikel/35/2009-07-29/fizzbuzz-baby">Sprung</xhtml:a>!
:-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/35/2009-07-29/fizzbuzz-baby</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Der Unterschied zwischen <em>valid</em> und <em>well-formed</em>]]></title>
    <published>2009-07-27T11:39:35+02:00</published>
    <updated>2009-07-27T11:39:35+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/fLGMcZS9Lfs/der-unterschied-zwischen-emvalidem-und-emwell-formedem" />
    <id>http://bigwhoop.ch/artikel/34/2009-07-27/der-unterschied-zwischen-emvalidem-und-emwell-formedem</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Ein Beispiel erleichtert wie immer den Einstieg.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;root &gt;&lt;/root&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Entgegen weitverbreiteter Annahme ist dieses XML Snippet nicht
<xhtml:em>valid</xhtml:em>, sondern "nur" <xhtml:em>well-formed</xhtml:em> (wohlgeformt).
Dies bedeutet, dass zwar die Regeln der XML Syntax eingehalten
wurden und ein Parser problemlos mit dem Code umgehen könnte, aber
die verwendete Struktur und deren Elemente nicht einer bestimmten
Grammatik unterliegen. Man kann dies durchaus mit der Grammatik der
deutschen Sprache vergleichen. In dieser ist zum Beispiel
definiert, dass Nomen gross geschrieben werden. Ergo ist die
Grammatik falsch, sobald ein Nomen klein geschrieben wird.</xhtml:p>
<xhtml:p>Da XML eine Form der Darstellung ist (als Vergleich können die
lateinischen Zeichen herhalten), enhält sie per se keine
grammatikalischen Regeln. Genauso wie ich mit den lateinischen
Zeichen sowohl deutsche, also auch englische Texte schreiben kann.
Will ich einen Satz auf deutsche Grammatik überprüfen, muss da
irgendwie ein Bezug bestehen. Bei der Sprache ist dieser durch
Metadaten (z.B. sagt mir jemand der folgende Text ist Deutsch) oder
durch Erraten (wenn ich einen Text lese, erkenne ich grundsätzlich
in welcher Sprache er geschrieben ist, solange ich die Sprache
"kenne") gegeben.</xhtml:p>
<xhtml:p>Bei XML muss dieser Bezug aber explizit hergestellt werden. Und
dazu gibt es zwei Möglichkeiten:</xhtml:p>
<xhtml:ul>
<xhtml:li>per Document Type Definition (DTD)</xhtml:li>
<xhtml:li>per XML Schemas</xhtml:li>
</xhtml:ul>
<xhtml:p>Da letztere Möglichkeit für unser Beispiel nicht von Relevanz
ist, möchte ich auch nicht näher darauf eingehen.</xhtml:p>
<xhtml:a id="document-type-definition" name="document-type-definition" />
<xhtml:h2>Document Type Definition</xhtml:h2>
<xhtml:blockquote>
<xhtml:p>Eine Dokumenttypdefinition (englisch Document Type Definition,
DTD, auch Schema-Definition oder DOCTYPE) ist ein Satz an Regeln,
der benutzt wird, um Dokumente eines bestimmten Typs zu
deklarieren. [...] Die Dokumenttypdefinition besteht dabei aus
Elementtypen, Attributen von Elementen, Entitäten und Notationen.
Konkret heißt das, dass in einer DTD die Reihenfolge, die
Verschachtelung der Elemente und die Art des Inhalts von Attributen
festgelegt wird - kurz gesagt: die Struktur des Dokuments.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Soviel zur Wikipedia-Definition. Auch hier sagt ein Beispiel
wieder mehr als lange, kryptische Sätze. Vergleichen wir die DTD
für <xhtml:a class="DefaultLink" href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" target="_blank">XHTML 1.0 Strict</xhtml:a> und <xhtml:a class="DefaultLink" href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" target="_blank">XHTML 1.0 Transitional</xhtml:a> bezüglich der erlaubten
Attribute des <xhtml:code>a</xhtml:code>-Elements (Anchor).</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;!ATTLIST A
  id          ID             #IMPLIED
  class       CDATA          #IMPLIED
  style       %StyleSheet;   #IMPLIED
  title       %Text;         #IMPLIED
  lang        %LanguageCode; #IMPLIED
  xml:lang    %LanguageCode; #IMPLIED
  dir         (ltr|rtl)      #IMPLIED
  onclick     %Script;       #IMPLIED
  ondblclick  %Script;       #IMPLIED
  onmousedown %Script;       #IMPLIED
  onmouseup   %Script;       #IMPLIED
  onmouseover %Script;       #IMPLIED
  onmousemove %Script;       #IMPLIED
  onmouseout  %Script;       #IMPLIED
  onkeypress  %Script;       #IMPLIED
  onkeydown   %Script;       #IMPLIED
  onkeyup     %Script;       #IMPLIED
  accesskey   %Character;    #IMPLIED
  tabindex    %Number;       #IMPLIED
  onfocus     %Script;       #IMPLIED
  onblur      %Script;       #IMPLIED
  charset     %Charset;      #IMPLIED
  type        %ContentType;  #IMPLIED
  name        NMTOKEN        #IMPLIED
  href        %URI;          #IMPLIED
  hreflang    %LanguageCode; #IMPLIED
  rel         %LinkTypes;    #IMPLIED
  rev         %LinkTypes;    #IMPLIED
  shape       %Shape;        "rect"
  coords      %Coords;       #IMPLIED
&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Dies ist der Auszug aus der DTD von XHTML 1.0 Strict. Die
Definition für XHTML 1.0 Transitional unterscheidet sich nur in
einer zusätzlichen Zeile:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
target      %FrameTarget;  #IMPLIED
</xhtml:pre></xhtml:div>
<xhtml:p>Diese erlaubt, wie man sich denken kann, die Verwendung des
<xhtml:code>target</xhtml:code>-Attributes in XHTML 1.0 Transitional.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;!-- Nicht valid in XHTML 1.0 Strict --&gt;
&lt;!-- Valid in XHTML 1.0 Transitional --&gt;
&lt;a href="http://example.org" target="_blank"&gt;Test&lt;/a&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Zur Erinnerung: Der Code ist auch <xhtml:em>well-formed</xhtml:em>,
allerdings hat dies nichts mit der DTD zu tun, sondern mit der XML
Syntax.</xhtml:p>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h2>Fazit</xhtml:h2>
<xhtml:p>Da der Unterschied zwischen <xhtml:em>well-formed</xhtml:em> und
<xhtml:em>valid</xhtml:em> jetzt klar ist, muss man sich nur selbst etwas an
der Nase nehmen und im Kontext stehts den richtigen Ausdruck
verwenden. Aus Erfahrung passiert der Fehler meist in Gesprächen
und aus der Tatsache, dass für eigene XML Strukturen keine DTD
geschrieben werden.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/34/2009-07-27/der-unterschied-zwischen-emvalidem-und-emwell-formedem</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Namenskonvention von Interfaces und abstrakten Klassen in PHP 5.3]]></title>
    <published>2009-07-19T13:53:32+02:00</published>
    <updated>2009-07-19T13:53:32+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/EXrZhW6dLoA/namenskonvention-von-interfaces-und-abstrakten-klassen-in-php-53" />
    <id>http://bigwhoop.ch/artikel/33/2009-07-19/namenskonvention-von-interfaces-und-abstrakten-klassen-in-php-53</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Als überzeugter Zend Framework-Nutzer folge ich beim
Programmieren auch dessen Coding Guidelines. Dies bedeutet für
Interfaces und abstrakte Klassen folgende Konvention:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/View/Interface.php
interface Zend_View_Interface {}

// Abstrakte Klasse in Zend/View/Abstract.php
abstract class Zend_View_Abstract {}
</xhtml:pre></xhtml:div>
<xhtml:p>Diese Konvention hat den Vorteil, dass man durch das Ersetzen
des Unterstrichs durch den Verzeichnisseparator auf einfache Art
auf den Speicherort der Klasse/des Interfaces schliessen kann.</xhtml:p>
<xhtml:p>Da wir aber mittlerweile alle wissen, dass in PHP 5.3 Namespaces
eingeführt wurden, ändert sich diese Konventionen grundlegend.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/View/Interface.php
namespace Zend\View;
interface Interface {}

// Abstrakte Klasse in Zend/View/Abstract.php
namespace Zend\View;
abstract class Abstract {}
</xhtml:pre></xhtml:div>
<xhtml:p>Wie ihr bestimmt bemerkt hab ist obiges Beispiel unbrauchbar. Da
<xhtml:code>interface</xhtml:code> und <xhtml:code>abstract</xhtml:code> reservierte Wörter
sind, können wir sie nicht für Deklarationen verwenden.</xhtml:p>
<xhtml:p>Als Lösungansatz schweben mir da mehrere Varianten vor.</xhtml:p>
<xhtml:a id="hungarische-notation" name="hungarische-notation" />
<xhtml:h2>"Hungarische Notation"</xhtml:h2>
<xhtml:p><xhtml:code>I</xhtml:code> für Interface und <xhtml:code>A</xhtml:code> für abstrakte
Klassen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/View/IView.php
namespace Zend\View;
interface IView {}

// Abstrakte Klasse in Zend/View/AView.php
namespace Zend\View;
abstract class AView {}
</xhtml:pre></xhtml:div>
<xhtml:p>... oder ohne das Package ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/IView.php
namespace Zend;
interface IView {}

// Abstrakte Klasse in Zend/AView.php
namespace Zend;
abstract class AView {}
</xhtml:pre></xhtml:div>
<xhtml:a id="als-teil-des-subpackages" name="als-teil-des-subpackages" />
<xhtml:h2>Als Teil des Subpackages</xhtml:h2>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/ViewInterface.php
namespace Zend;
interface ViewInterface {}

// Abstrakte Klasse in Zend/ViewAbstract.php
namespace Zend;
abstract class ViewAbstract {}
</xhtml:pre></xhtml:div>
<xhtml:p>... oder in umgekehrter Schreibweise ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/InterfaceView.php
namespace Zend;
interface InterfaceView {}

// Abstrakte Klasse in Zend/AbstractView.php
namespace Zend;
abstract class AbstractView {}
</xhtml:pre></xhtml:div>
<xhtml:a id="beschreibende-interface-namen" name="beschreibende-interface-namen" />
<xhtml:h2>Beschreibende Interface-Namen</xhtml:h2>
<xhtml:p>Wie in der SPL: <xhtml:code>Countable</xhtml:code>,
<xhtml:code>Traversable</xhtml:code>, etc.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Interface in Zend/View/Viewable.php
namespace Zend\View;
interface Viewable {}
</xhtml:pre></xhtml:div>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/33/2009-07-19/namenskonvention-von-interfaces-und-abstrakten-klassen-in-php-53</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Mathematik revisited: Umrechnen von Zahlensystemen]]></title>
    <published>2009-07-16T02:42:00+02:00</published>
    <updated>2009-07-16T02:42:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/5fRxO4PN0VM/mathematik-revisited-umrechnen-von-zahlensystemen" />
    <id>http://bigwhoop.ch/artikel/32/2009-07-16/mathematik-revisited-umrechnen-von-zahlensystemen</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:a id="hexadezimal-code0xe6facode-nach-oktal" name="hexadezimal-code0xe6facode-nach-oktal" />
<xhtml:h2>Hexadezimal <xhtml:code>0xE6FA</xhtml:code> nach Oktal</xhtml:h2>
<xhtml:p>Zur erfolgreichen Umrechnung muss das Hexadezimalsystem bekannt
sein. D.h. man muss wissen, dass A = 10, B = 11, ... F = 15 ist.
Zur Umrechnung ins oktale Zahlensystem gehen wir den Umweg über das
Dezimalsystem.</xhtml:p>
<xhtml:a id="1-hexadezimal-nach-dezimal-basis-16" name="1-hexadezimal-nach-dezimal-basis-16" />
<xhtml:h3>1. Hexadezimal nach Dezimal (= Basis 16)</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
E/14 * 16 *   16 *   16 = 57344
        6 *   16 *   16 =  1536
            F/15 *   16 =   240
                   A/10 =    10
-------------------------------
                        = 59130
</xhtml:pre></xhtml:div>
<xhtml:p>Die Basis ist austauschbar. Wenn man vom Oktal- ins
Dezimalsystem rechnen möchte, müsste man einfach mit 8
multiplizieren.</xhtml:p>
<xhtml:a id="2-dezimal-nach-oktal-basis-8" name="2-dezimal-nach-oktal-basis-8" />
<xhtml:h3>2. Dezimal nach Oktal (= Basis 8)</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
59130 / 8 = 7391   Rest 2
 7391 / 8 =  923   Rest 7
  923 / 8 =  115   Rest 3
  115 / 8 =   14   Rest 3
   14 / 8 =    1   Rest 6
    1 / 8 =    0   Rest 1
-------------------------
               -&gt; 0163372
</xhtml:pre></xhtml:div>
<xhtml:p>Das Result ergibt sich hier aus den zusammengefassten
Restzahlen. Auch hier kann man die Basis einfach austauschen.
Möchte man vom Dezimal- ins Hexadezimalsystem umrechnen, würde man
durch 16 teilen (und natürlich Rest = 13 noch in Rest = D
umwandeln).</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/32/2009-07-16/mathematik-revisited-umrechnen-von-zahlensystemen</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Zend Extensions in PHP 5.3 laden]]></title>
    <published>2009-07-12T10:47:37+02:00</published>
    <updated>2009-07-12T10:47:37+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/bRWZiFvhzCk/zend-extensions-in-php-53-laden" />
    <id>http://bigwhoop.ch/artikel/31/2009-07-12/zend-extensions-in-php-53-laden</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Gestern räumte ich meine lokale Entwicklungsumgebung auf. XAMPP
flog raus, Apache 2.2 und PHP 5.3 kamen "standalone" rein (MySQL
läuft bei mir auf einem Heimserver). Mir war das ganze Gewurstel
einfach zu unübersichtlich geworden.</xhtml:p>
<xhtml:p>Jedenfalls kam ich im Zuge dieser
Neuinstallationen-/konfigurationen auch an den Punkt, wo ich mein
geliebtes Xdebug installieren wollte. Aus irgendeinem Grund wollte
sich dieses jedoch nicht als Zend Extension laden lassen. Eine
Fehlermeldung erhielt ich nicht und als normale Extension klappte
es wunderbar.</xhtml:p>
<xhtml:p>Heute konnte mir der Twitter-Channel von Xdebug die einfache
Lösung mitteilen: <xhtml:strong>Anstatt
<xhtml:code>zend<xhtml:em>extension</xhtml:em>ts</xhtml:code> muss in PHP 5.3 nur noch
<xhtml:code>zend<xhtml:em>extension</xhtml:em></xhtml:code> <xhtml:em>verwendet
werden.</xhtml:em></xhtml:strong> <xhtml:em>Die Direktiven
<xhtml:code>zend</xhtml:code></xhtml:em><xhtml:code>extension<xhtml:em>ts</xhtml:em></xhtml:code> <xhtml:em>und
<xhtml:code>zend</xhtml:code></xhtml:em><xhtml:code>extension_debug</xhtml:code> werden seit PHP
5.3 ignoriert.</xhtml:p>
<xhtml:p>Leider findet sich zu diesem Change weder im <xhtml:a class="DefaultLink" href="http://ch.php.net/manual/en/ini.core.php#ini.zend-extension-ts" target="_blank">PHP Manual</xhtml:a>, noch im <xhtml:a class="DefaultLink" href="http://xdebug.org/docs/install" target="_blank">Xdebug
Installation Guide</xhtml:a> ein Hinweis. Ich hoffe, dies ändert sich
noch ... :-)</xhtml:p>
<xhtml:p>Den einzigen Hinweis fand ich im <xhtml:a class="DefaultLink" href="http://ch.php.net/manual/en/migration53.ini.php" target="_blank">Migration Guide für PHP 5.3</xhtml:a>:
<xhtml:em>"zend</xhtml:em>extensiondebug and zend<xhtml:em>extension</xhtml:em>ts have been
removed. Use the zend_extension directive to load all Zend
Extensions."</xhtml:p>
<xhtml:a id="nachtrag" name="nachtrag" />
<xhtml:h2>Nachtrag</xhtml:h2>
<xhtml:p>Derick hat soeben die Xdebug Dokumentation geupdatet. Wunderbar.
:-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/31/2009-07-12/zend-extensions-in-php-53-laden</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PHP Arrays - Eine All-In-One Lösung]]></title>
    <published>2009-07-09T05:16:00+02:00</published>
    <updated>2009-07-09T05:16:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/yyD3NX9nFUI/php-arrays-eine-all-in-one-loesung" />
    <id>http://bigwhoop.ch/artikel/29/2009-07-09/php-arrays-eine-all-in-one-loesung</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Das PHP Array ist ein enorm mächtiges Konstrukt. Es ist - wie
PHP auch - sehr flexibel gebaut und auf viele, unterschiedliche
Arten verwendbar. Im Folgenden setze ich das Grundwissen voraus,
wie Arrays in PHP angewandt werden. Sicherheitshalber noch einmal
ein paar Fakten:</xhtml:p>
<xhtml:ul>
<xhtml:li>Indexe (Keys) können vom Typ Integer oder String sein. Floats
werden zu einem Integer gecastet</xhtml:li>
<xhtml:li>Arrays oder Objekte können nicht als Index verwendet
werden</xhtml:li>
</xhtml:ul>
<xhtml:p>Oder in Code ausgedrückt:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// Array mit numerischen Indexen
$a = array('Eins', 'Zwei', 'Drei');

// Assoziatives Array
$a = array('Null' =&gt; 'Eins', 'Eins' =&gt; 'Zwei', 'Zwei' =&gt; 'Drei');

// Mixed Array
$a = array(4 =&gt; 'Eins', 'Fünf' =&gt; 'Zwei', 'Drei');
</xhtml:pre></xhtml:div>
<xhtml:p>Der interne Zeiger wird bei jedem numerischen Key um eins
hochgezählt. Im letztem Beispiel hat das Element <xhtml:code>Drei</xhtml:code>
deshalb den Index <xhtml:code>5</xhtml:code>.</xhtml:p>
<xhtml:p>In den meisten Programmiersprachen gibt es mehrere Konstrukte
zur Haltung von Daten. Dies hat vor allem den Vorteil, dass die
Daten klarer strukturiert und je nach Anwendung auf definierte
Weise gehandhabt werden. Im Folgenden möchte ich auf ein paar
dieser Konstrukte eingehen, sie auf einfache Art erklären und
anschliessend zeigen, wie sie mittels SPL auch in PHP verwendet
werden können.</xhtml:p>
<xhtml:a id="hashtable" name="hashtable" />
<xhtml:h2>Hashtable</xhtml:h2>
<xhtml:p>Eine Hashtable, oder auch Hashmap, kann man sich als
klassisches, assoziatives PHP Array vorstellen. Allerdings ohne
besagte Limitierungen hinsichtlich Indexe. Die Definition ist ein
bisschen wässerig, da es in PHP keine strenge Typisierung gibt. In
vielen anderen Programmiersprachen ist ein Array immer von nur
einem Typ (String-Array, Byte-Array, etc.).</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Hashtable implements ArrayAccess 
{
    protected $_data = array();

    public function offsetSet($key, $value)
    {
        $key = $this-&gt;_normalizeKey($key);
        $this-&gt;_data[$key] = $value;
    }

    public function offsetGet($key)
    {
        $key = $this-&gt;_normalizeKey($key);
        return $this-&gt;_data[$key];
    }

    public function offsetUnset($key)
    {
        $key = $this-&gt;_normalizeKey($key);
    unset($this-&gt;_data[$key]);
    }

    public function offsetExists($key)
    {
        $key = $this-&gt;_normalizeKey($key);
        return isset($this-&gt;_data[$key]);
    }

    protected function _normalizeKey($key)
    {
        if ($key instanceof stdClass) {
            $key = spl_object_hash($key);
        }
        elseif (is_array($key)) {
            $key = md5(serialize($key));
        }

        return $key;
    }
}

$h  = new Hashtable();
$o1 = new stdClass();
$o2 = new stdClass();
$h[$o1] = $o2;
</xhtml:pre></xhtml:div>
<xhtml:p>In der sogenannten Standard PHP Library (SPL) gibt es eine
Klasse zum Speichern von Objekten. Da diese fest in PHP integriert
ist, hat sie klare Geschwindigkeitsvorteile gegenüber einer eigenen
Lösung in PHP. Etienne Kneuss hat dazu in <xhtml:a href="http://www.colder.ch/news/01-08-2009/34/splobjectstorage-for-a-fa.html" target="_blank">seinem Blog</xhtml:a> weitere, interessante
Informationen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$s  = new SplObjectStorage();
$o1 = new stdClass();
$o2 = new stdClass();

// Seit PHP 5.1
$s-&gt;attach($o1);
$s-&gt;detach($o1);

// Seit PHP 5.3
$s[$o1] = $o2;
</xhtml:pre></xhtml:div>
<xhtml:a id="queue" name="queue" />
<xhtml:h2>Queue</xhtml:h2>
<xhtml:p>Eine Queue iteriert im sogenannten FIFO-Modus (First In, First
Out) über die Elemente. Dies bedeutet, dass die Elemente zuerst
zurückgegeben werden, die auch zuerst hinzugefügt wurden. Dies
entspring dem Standard-Iterierungsverfahren von Arrays in PHP (z.B.
bei <xhtml:code>foreach()</xhtml:code>).</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Queue
{
    protected $_data = array();

    public function enqueue($value)
    {
        $this-&gt;_data[] = $value;
        return $this;
    }

    public function dequeue()
    {
        return array_shift($this-&gt;_data);
    }
}

$q = new Queue();
$q-&gt;enqueue('Eins')
  -&gt;enqueue('Zwei')
  -&gt;enqueue('Drei');

echo $q-&gt;dequeue(); // Eins
echo $q-&gt;dequeue(); // Zwei
echo $q-&gt;dequeue(); // Drei
</xhtml:pre></xhtml:div>
<xhtml:p>Auch hier kann die SPL <xhtml:strong>seit PHP 5.3</xhtml:strong> helfen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$q = new SplQueue();
$q[] = 1;
$q[] = 2;
$q[] = 3;

// 1, 2, 3
foreach ($q as $e)  {
    echo $e;
}
</xhtml:pre></xhtml:div>
<xhtml:a id="stack" name="stack" />
<xhtml:h2>Stack</xhtml:h2>
<xhtml:p>Der Stack ist sowas wie das Gegenstück zu einer Queue. Er
verwendet das LIFO-Verfahren (Last In, First Out), welches die
Element zuerst zurückgibt, die zuletzt angehängt wurden.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Stack
{
    protected $_data = array();

    public function push($value)
    {
        $this-&gt;_data[] = $value;
        return $this;
    }

    public function pop()
    {
        return array_pop($this-&gt;_data);
    }
}

$s = new Stack();
$s-&gt;push('Eins')
  -&gt;push('Zwei')
  -&gt;push('Drei');

echo $s-&gt;pop(); // Drei
echo $s-&gt;pop(); // Zwei
echo $s-&gt;pop(); // Eins
</xhtml:pre></xhtml:div>
<xhtml:p>Und wieder kann uns die SPL helfen. Wiederum ist <xhtml:strong>PHP
5.3</xhtml:strong> Kriterium.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$q = new SplStack();
$q[] = 1;
$q[] = 2;
$q[] = 3;

// 3, 2, 1
foreach ($q as $e)  {
    echo $e;
}
</xhtml:pre></xhtml:div>
<xhtml:a id="dictionary" name="dictionary" />
<xhtml:h2>Dictionary</xhtml:h2>
<xhtml:p>Den Dictionary kann man sich als assoziatives Array mit fest
definierten Typen für Key und Value vorstellen. Hier eine sehr
abstrakte Implementierung.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class Dictionary
{
    protected $_keyType   = null;
    protected $_valueType = null;
    protected $_data      = array();

    public function __construct($keyType, $valueType)
    {
        $this-&gt;_keyType   = $keyType;
        $this-&gt;_valueType = $valueType;
    }

    public function add($key, $value)
    {
        if (!$this-&gt;_assert($this-&gt;_keyType, $key)) {
            throw new Exception('Key must be of type "' . $this-&gt;_keyType . '"');
        }

        if (!$this-&gt;_assert($this-&gt;_valueType, $value)) {
            throw new Exception('Value must be of type "' . $this-&gt;_valueType . '"');
        }

        // Adding key/value pair
        // ...
    }

    protected function _assert($type, $value)
    {
        if (function_exists('is_' . $type)) {
            return call_user_func('is_' . $type, $value);
        }

        return $value instanceof $type;
    }
}

$d = new Dictionary('int', 'stdClass');
$d-&gt;add(1, new stdClass());   // Success
$d-&gt;add('1', new stdClass()); // Fail
$d-&gt;add(1, 'foobar');         // Fail
</xhtml:pre></xhtml:div>
<xhtml:p>Hierzu gibt es leider keine Klasse in der SPL.</xhtml:p>
<xhtml:a id="weitere-datenstrukturen-in-der-spl" name="weitere-datenstrukturen-in-der-spl" />
<xhtml:h2>Weitere Datenstrukturen in der SPL</xhtml:h2>
<xhtml:p>Die SPL kennt noch weitere Konstrukte zur Datenhaltung, wie
SplHeap, SplPriorityQueue, etc. Hier möchte ich aber nur noch auf
eine bestimmte Struktur eingehen:
<xhtml:strong>SplFixedArray</xhtml:strong>.</xhtml:p>
<xhtml:p>Das SplFixedArray gibt es ebenfalls erst seit PHP 5.3 und
unterscheidet sich in folgenden Punkten vom klassischen PHP
Array:</xhtml:p>
<xhtml:ul>
<xhtml:li>Das Array hat eine feste Grösse, wird also nicht dynamisch
erweitert</xhtml:li>
<xhtml:li>Das Array kann nur numerische Indexe haben</xhtml:li>
<xhtml:li>Das SplFixedArray ist eine viel schnellere und schlankere
Implementierung als herkömmliche Arrays</xhtml:li>
</xhtml:ul>
<xhtml:p>Und so schaut es aus:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = new SplFixedArray(2);
$a[0] = 'Eins';
$a[1] = 'Zwei';

// Triggert eine RuntimeException, da die Grösse des Arrays überschritten wurde
$a[2] = 'Drei';

// Folgendes geht aber
$a-&gt;setSize(3);
$a[2] = 'Drei';
</xhtml:pre></xhtml:div>
<xhtml:p>Ich empfehle als Lektüre die <xhtml:a class="DefaultLink" href="http://ch2.php.net/spl" target="_blank">PHP Dokumentation zur
SPL</xhtml:a>. Ausserdem findet ihr im Entwicklerblog von studiVZ eine
<xhtml:a href="http://developer.studivz.net/2009/03/18/php-spl-data-structures-benchmark/" target="_blank">interessante Benchmark betreffend SplQueue und
SplStack</xhtml:a>, und im Blog von IDONTPLAYDARTS eine <xhtml:a href="http://www.idontplaydarts.com/2009/06/benchmarking-splfixedarray-access-speed/">
Benchmark zu SplFixedArray</xhtml:a>.</xhtml:p>
<xhtml:p>Haut rein, in die Tasten! :)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/29/2009-07-09/php-arrays-eine-all-in-one-loesung</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Some ZCE Mock Exam Questions]]></title>
    <published>2009-07-07T11:01:52+02:00</published>
    <updated>2009-07-07T11:01:52+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/zssXNkPXPT8/some-zce-mock-exam-questions" />
    <id>http://bigwhoop.ch/artikel/28/2009-07-07/some-zce-mock-exam-questions</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>You'll find my answers on the next page. Have fun!</xhtml:p>
<xhtml:a id="question-1" name="question-1" />
<xhtml:h2>Question 1</xhtml:h2>
<xhtml:p>What are the primary benefits of object oriented
programming?</xhtml:p>
<xhtml:p>Answers: (choose 3)</xhtml:p>
<xhtml:ul>
<xhtml:li>Maintainability</xhtml:li>
<xhtml:li>Execution Speed</xhtml:li>
<xhtml:li>Encapsulation</xhtml:li>
<xhtml:li>Code Reuse</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-2" name="question-2" />
<xhtml:h2>Question 2</xhtml:h2>
<xhtml:p>The <xhtml:code>_____</xhtml:code> keyword is used to block any overriding
of a class/method by a subclass.</xhtml:p>
<xhtml:p>Answers:</xhtml:p>
<xhtml:ul>
<xhtml:li>static</xhtml:li>
<xhtml:li>None of the above</xhtml:li>
<xhtml:li>protected</xhtml:li>
<xhtml:li>final</xhtml:li>
<xhtml:li>private</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-3" name="question-3" />
<xhtml:h2>Question 3</xhtml:h2>
<xhtml:p>Event-based XML parsing is an example of which parsing
model?</xhtml:p>
<xhtml:p>Answers:</xhtml:p>
<xhtml:ul>
<xhtml:li>SAX</xhtml:li>
<xhtml:li>DOM</xhtml:li>
<xhtml:li>XML Object Mapping</xhtml:li>
<xhtml:li>XPath</xhtml:li>
<xhtml:li>XQuery</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-4" name="question-4" />
<xhtml:h2>Question 4</xhtml:h2>
<xhtml:p>Which functions would be needed to translate the following
string:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
I love PHP 5
</xhtml:pre></xhtml:div>
<xhtml:p>to the following?</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
5 PHP EVOL I
</xhtml:pre></xhtml:div>
<xhtml:p>Answers: (choose 2)</xhtml:p>
<xhtml:ul>
<xhtml:li>mirror()</xhtml:li>
<xhtml:li>strtoupper()</xhtml:li>
<xhtml:li>toupper()</xhtml:li>
<xhtml:li>str_reverse()</xhtml:li>
<xhtml:li>strrev()</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-5" name="question-5" />
<xhtml:h2>Question 5</xhtml:h2>
<xhtml:p>Which two internal PHP interfaces provide functionality which
allow you to treat an object like an array?</xhtml:p>
<xhtml:p>Answers: (choose 2)</xhtml:p>
<xhtml:ul>
<xhtml:li>iteration</xhtml:li>
<xhtml:li>arrayaccess</xhtml:li>
<xhtml:li>objectarray</xhtml:li>
<xhtml:li>iterator</xhtml:li>
<xhtml:li>array</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-6" name="question-6" />
<xhtml:h2>Question 6</xhtml:h2>
<xhtml:p>Consider the following code snippet:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$query = "INSERT INTO mytable 
          (myinteger, mydouble, myblob, myvarchar)
          VALUES (?, ?, ?, ?)";
$statement = mysqli_prepare($link, $query);

if(!$statement)
{
  die(mysqli_error($link));
}

/* The variables being bound to by MySQLi
   don't need to exist prior to binding */
mysqli_bind_param($statement, "idbs",
  $myinteger, $mydouble, $myblob, $myvarchar);

/* ???????????? */ 

/* execute the query, using the variables as defined. */

if(!mysqli_execute($statement))
{
  die(mysqli_error($link));
}
</xhtml:pre></xhtml:div>
<xhtml:p>Assuming this snippet is a smaller part of a correctly written
script, what actions must occur in place of the ????? in the above
code snippet to insert a row with the following values: 10, 20.2,
foo, string ?</xhtml:p>
<xhtml:p>Answer…</xhtml:p>
<xhtml:ul>
<xhtml:li>A transaction must be begun and the variables must be
assigned</xhtml:li>
<xhtml:li>Each value must be assigned prior to calling
<xhtml:code>mysqli_bind_param()</xhtml:code>, and thus nothing should be
done</xhtml:li>
<xhtml:li>Use <xhtml:code>mysqli_bind_value()</xhtml:code> to assign each of the
values</xhtml:li>
<xhtml:li>Assign <xhtml:code>$myinteger</xhtml:code>, <xhtml:code>$mydouble</xhtml:code>,
<xhtml:code>$myblob</xhtml:code>, <xhtml:code>$myvarchar</xhtml:code> the proper
values</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-7" name="question-7" />
<xhtml:h2>Question 7</xhtml:h2>
<xhtml:p>Given the string:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$var = "john@php.net";
</xhtml:pre></xhtml:div>
<xhtml:p>Which of the following will extract the TLD (top level domain)
of ".net" from the string?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>strstr($var, strpos($var, "."));</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>substr($var, strpos($var, "@"));</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>substr($var, strstr($var, "."));</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>substr($var, strpos($var, ".") 1);</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>substr($var, strpos($var, "."));</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-8" name="question-8" />
<xhtml:h2>Question 8</xhtml:h2>
<xhtml:p>The ____ construct is particularly useful to assign your own
variable names to values within an array.</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>array_get_variables</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>current</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>each</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>import_variables</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>list</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-9" name="question-9" />
<xhtml:h2>Question 9</xhtml:h2>
<xhtml:p>Given the following XML document in a SimpleXML object:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
&lt;!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
  &lt;head&gt;
    &lt;title&gt;XML Example&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;
      Moved to &lt;&lt;a href="http://example.org/"&gt;http://www.example.org/&lt;/a&gt;.&gt;
      &lt;br/&gt;
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Select the proper statement below which will display the HREF
attribute of the anchor tag.</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>$sxe-&gt;body-&gt;p[0]-&gt;a[1]['href']</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>$sxe-&gt;body-&gt;p-&gt;a-&gt;href</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>$sxe-&gt;body-&gt;p-&gt;a['href']</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>$sxe['body']['p'][0]['a']['href']</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>$sxe-&gt;body-&gt;p[1]-&gt;a['href']</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-10" name="question-10" />
<xhtml:h2>Question 10</xhtml:h2>
<xhtml:p>Consider the following script:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$dom = new DOMDOcument();
$dom-&gt;load("myxmlfile.xml");
foreach($dom-&gt;documentElement-&gt;childNodes as $child)
{
  if(($child-&gt;nodeType == XML_ELEMENT_NODE) &amp;&amp;
      $child-&gt;nodeName == "item")
  {
    foreach($child-&gt;childNodes as $item)
    {
      if(($item-&gt;nodeType == XML_ELEMENT_NODE) &amp;&amp;
         ($item-&gt;nodeName == "title"))
      {
        print "$item-&gt;firstChild-&gt;data\n";
      }
    }
  }
}
</xhtml:pre></xhtml:div>
<xhtml:p>Assuming the referenced XML document exists and matches the
parsing logic, what should be displayed when this script is
executed?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>None of the above</xhtml:li>
<xhtml:li>The XML of each 'title' node</xhtml:li>
<xhtml:li>The XML of each 'item' node</xhtml:li>
<xhtml:li>"Title" for every title node in the document</xhtml:li>
<xhtml:li>The contents of every 'title' node which exists under an 'item'
node</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-11" name="question-11" />
<xhtml:h2>Question 11</xhtml:h2>
<xhtml:p>Which of the following is the best way to split a string on the
"-=-" pattern?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>They all are equally proper methods</xhtml:li>
<xhtml:li><xhtml:code>str_split($string, strpos($string, "-=-"))</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>preg_split("-=-", $string);</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>explode("-=-" $string);</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-12" name="question-12" />
<xhtml:h2>Question 12</xhtml:h2>
<xhtml:p>SimpleXML objects can be created from what types of data
sources?</xhtml:p>
<xhtml:p>Answers: (choose 3)</xhtml:p>
<xhtml:ul>
<xhtml:li>A String</xhtml:li>
<xhtml:li>An array</xhtml:li>
<xhtml:li>A DomDocument object</xhtml:li>
<xhtml:li>A URI</xhtml:li>
<xhtml:li>A Database resource</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-13" name="question-13" />
<xhtml:h2>Question 13</xhtml:h2>
<xhtml:p>Which of the following are valid PHP variables?</xhtml:p>
<xhtml:p>Answers: (choose 4)</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>@$foo</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>&amp;$variable</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>${0x0}</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>$variable</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>$0x0</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-14" name="question-14" />
<xhtml:h2>Question 14</xhtml:h2>
<xhtml:p>When implementing a permissions system for your Web site, what
should always be done with regards to the session?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>None of the above</xhtml:li>
<xhtml:li>You should not implement permission systems using sessions</xhtml:li>
<xhtml:li>Sessions should be cleared of all data and re-populated</xhtml:li>
<xhtml:li>The session key should be regenerated</xhtml:li>
<xhtml:li>The session should be destroyed</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-15" name="question-15" />
<xhtml:h2>Question 15</xhtml:h2>
<xhtml:p>SQL Injections can be best prevented using which of the
following database technologies?</xhtml:p>
<xhtml:p>Answers: (choose 1)</xhtml:p>
<xhtml:ul>
<xhtml:li>All of the above</xhtml:li>
<xhtml:li>Prepared Statements</xhtml:li>
<xhtml:li>Persistent Connections</xhtml:li>
<xhtml:li>Unbuffered Queries</xhtml:li>
<xhtml:li>Query escaping</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-16" name="question-16" />
<xhtml:h2>Question 16</xhtml:h2>
<xhtml:p>When attempting to prevent a cross-site scripting attack, which
of the following is most important?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>Not writing Javascript on the fly using PHP</xhtml:li>
<xhtml:li>Filtering Output used in form data</xhtml:li>
<xhtml:li>Filtering Output used in database transactions</xhtml:li>
<xhtml:li>Writing careful Javascript</xhtml:li>
<xhtml:li>Filtering all input</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-17" name="question-17" />
<xhtml:h2>Question 17</xhtml:h2>
<xhtml:p>What three special methods can be used to perform special logic
in the event a particular accessed method or member variable is not
found?</xhtml:p>
<xhtml:p>Answers: (choose 3)</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>__get($variable)</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>__call($method, $params)</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>__get($method)</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>__set($variable, $value)</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>__call($method)</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-18" name="question-18" />
<xhtml:h2>Question 18</xhtml:h2>
<xhtml:p>When running PHP in a shared host environment, what is the major
security concern when it comes to session data?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>Sessions on shared hosts are easily hijacked by outside
malicious users</xhtml:li>
<xhtml:li>All of the above</xhtml:li>
<xhtml:li>You cannot use a custom data store in shared hosts</xhtml:li>
<xhtml:li>Session data stored in the file system can be read by other
scripts on the same shared host</xhtml:li>
<xhtml:li>Users outside the shared host can access any site which created
a session for them</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-19" name="question-19" />
<xhtml:h2>Question 19</xhtml:h2>
<xhtml:p>A fingerprint of a string can be determined using which of the
following?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>md5()</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>hash()</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>fingerprint()</xhtml:code></xhtml:li>
<xhtml:li>None of the above</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-20" name="question-20" />
<xhtml:h2>Question 20</xhtml:h2>
<xhtml:p>When embedding PHP into XML documents, what must you ensure is
true in order for things to function properly?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>Disabling of the short_tags PHP.ini directive</xhtml:li>
<xhtml:li>Enabling the asp_tags PHP.ini directive</xhtml:li>
<xhtml:li>That you have XPath support enabled in PHP 5</xhtml:li>
<xhtml:li>That your XML documents are well-formed</xhtml:li>
<xhtml:li>None of the above, PHP can be embedded in XML in all
cases.</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-21" name="question-21" />
<xhtml:h2>Question 21</xhtml:h2>
<xhtml:p>What is the output of the following code?</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$string = "111221";
for($i = 0; $i &lt; strlen($string); $i  ) {
    $current = $string[$i];
    $count = 1;
    while(isset($string[$i   $count]) &amp;&amp; ($string[$i   $count] == $current)) $count  ;
        $newstring .= "$count{$current}";
        $i  = $count-1;
}
print $newstring;
</xhtml:pre></xhtml:div>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>312211</xhtml:li>
<xhtml:li>3312212</xhtml:li>
<xhtml:li>11221221</xhtml:li>
<xhtml:li>221131</xhtml:li>
<xhtml:li>3211122</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-22" name="question-22" />
<xhtml:h2>Question 22</xhtml:h2>
<xhtml:p>When working with a database, which of the following can be used
to mitigate the possibility of exposing your database credientials
to a malicious user?</xhtml:p>
<xhtml:p>Answers: (choose 3)</xhtml:p>
<xhtml:ul>
<xhtml:li>Moving all database credentials into a single file</xhtml:li>
<xhtml:li>Moving all database credentials outside of the document
root</xhtml:li>
<xhtml:li>Restricting access to files not designed to be executed
independently</xhtml:li>
<xhtml:li>Setting creditial information as system environment
variables</xhtml:li>
<xhtml:li>Using PHP constants instead of variables to store
credentials</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-23" name="question-23" />
<xhtml:h2>Question 23</xhtml:h2>
<xhtml:p>Consider the following code:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
session_start();
if(!empty($_REQUEST['id'])
   &amp;&amp; !empty($_REQUEST['quantity'])) {
  $id = scrub_id($_REQUEST['id']);
  $quantity = scrub_quantity($_REQUEST['quantity'])
  $_SESSION['cart'][] = array('id' =&gt; $id,
                              'quantity' =&gt; $quantity)
}
/* .... */
</xhtml:pre></xhtml:div>
<xhtml:p>What potential security hole would this code snippet
produce?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>Cross-Site Scripting Attack</xhtml:li>
<xhtml:li>There is no security hole in this code</xhtml:li>
<xhtml:li>Code Injection</xhtml:li>
<xhtml:li>SQL Injection</xhtml:li>
<xhtml:li>Cross-Site Request Forgery</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-24" name="question-24" />
<xhtml:h2>Question 24</xhtml:h2>
<xhtml:p>Which statement will return the third parameter passed to a
function?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>$argv[3];</xhtml:li>
<xhtml:li>$argv[2];</xhtml:li>
<xhtml:li>func<xhtml:em>get</xhtml:em>args(3);</xhtml:li>
<xhtml:li>func<xhtml:em>get</xhtml:em>arg(2);</xhtml:li>
<xhtml:li>func<xhtml:em>get</xhtml:em>arg(3);</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-25" name="question-25" />
<xhtml:h2>Question 25</xhtml:h2>
<xhtml:p>When is it important to validate data coming from an HTML
form?</xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>Only when the fields are required</xhtml:li>
<xhtml:li>Only when accepting file uploads</xhtml:li>
<xhtml:li>Everywhere, except cookies</xhtml:li>
<xhtml:li>Only when accepting forms using an input type of text or a
<xhtml:code>&lt;textarea&gt;</xhtml:code> field</xhtml:li>
<xhtml:li>None of the above</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-26" name="question-26" />
<xhtml:h2>Question 26</xhtml:h2>
<xhtml:p>Which of the following extensions are no longer part of PHP 5
and have been moved to PECL?</xhtml:p>
<xhtml:p>Answers: (choose 2)</xhtml:p>
<xhtml:ul>
<xhtml:li>tidy</xhtml:li>
<xhtml:li>mysql</xhtml:li>
<xhtml:li>w32api</xhtml:li>
<xhtml:li>curl</xhtml:li>
<xhtml:li>dio</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-27" name="question-27" />
<xhtml:h2>Question 27</xhtml:h2>
<xhtml:p>The following is a common XML structure used in service oriented
architectures, what does it represent?</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;?xml version="1.0"?&gt;
&lt;methodCall&gt;
 &lt;methodName&gt;myMethod&lt;/methodName&gt;
 &lt;params&gt;
  &lt;param&gt;
   &lt;value&gt;&lt;string&gt;HI!&lt;/string&gt;&lt;/value&gt;
  &lt;/param&gt;
 &lt;/params&gt;
&lt;/methodCall&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li>None of the above</xhtml:li>
<xhtml:li>A fragment of a complete SOAP request</xhtml:li>
<xhtml:li>XML-RPC</xhtml:li>
<xhtml:li>REST</xhtml:li>
<xhtml:li>SOAP</xhtml:li>
</xhtml:ul>
<xhtml:a id="question-28" name="question-28" />
<xhtml:h2>Question 28</xhtml:h2>
<xhtml:p>Which of the following functions could be used to break a string
into an array?</xhtml:p>
<xhtml:p>Answers: (choose 3)</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>array_split()</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>split()</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>string_split()</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>preg_match_all()</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>explode()</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:a id="question-29" name="question-29" />
<xhtml:h2>Question 29</xhtml:h2>
<xhtml:p>Which PCRE regular expression will match the string
<xhtml:code>PhP5-rocks?</xhtml:code></xhtml:p>
<xhtml:p>Answer...</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>/^[hp1-5]*\-.*/i</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>/[hp1-5]*\-.?/</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>/[hp][1-5]*\-.*/</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>/[PhP]{3}[1-5]{2,3}\-.*$/</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>/[a-z1-5\-]*/</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p>Mehr gibt es nach dem <xhtml:a href="http://bigwhoop.ch/artikel/28/2009-07-07/some-zce-mock-exam-questions">
Sprung</xhtml:a>! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/28/2009-07-07/some-zce-mock-exam-questions</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Die schnelle Website startet vorne, nicht hinten]]></title>
    <published>2009-07-05T22:14:19+02:00</published>
    <updated>2009-07-05T22:14:19+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/GmTiQS_ab80/die-schnelle-website-startet-vorne-nicht-hinten" />
    <id>http://bigwhoop.ch/artikel/27/2009-07-05/die-schnelle-website-startet-vorne-nicht-hinten</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Auf Grund diverser Posts auf <xhtml:a href="http://stackoverflow.com">stackoverflow.com</xhtml:a> und in diversen
Foren, auf Grund Googles Fettnäpfchenbeitrag zum Thema "<xhtml:a href="http://code.google.com/intl/de-DE/speed/articles/optimizing-php.html">Geschwindigkeitsptimierung
in PHP</xhtml:a>" und einem Artikel von Nils Langner auf phphatesme.com
hinsichtlich <xhtml:a href="http://www.phphatesme.com/blog/allgemein/mikro-optimierung/trackback/">
Mikro-Optimierung in PHP</xhtml:a>, entschloss ich mich, betiteltes Thema
aufzugreifen. :-)</xhtml:p>
<xhtml:p>Bei mir gibt es mal grundsätzlich eine Devise: <xhtml:strong>Zuerst
Wartbarkeit, danach Geschwindigkeit</xhtml:strong>!</xhtml:p>
<xhtml:p>Dieser Leitfaden zieht sich durch viele Aspekte meines
Programmierens: Ich vermeide zum Beispiel kryptische Einzeiler,
schliesslich muss ich niemandem beweisen wie gut ich bin. Lieber
verstehe ich die Funktionalität ein Jahr später direkt auf Anhieb.
Dann ziehe ich das Ding mit den Kommentaren konsequent durch. Das
ist schon fast ein bisschen pedantisch, aber eine Methode ohne
Docblock sieht einfach scheisse aus. Um es mal salopp auszudrücken.
;-)</xhtml:p>
<xhtml:p>Meist sind es PHP Anfänger die mit Fragen hinsichtlich
Geschwindigkeitsoptimierung antraben. Dabei denke ich mir immer
(ohne arrogant zu wirken), dass sie sich dann um sowas kümmern
sollten, wenn es wirklich notwendig wird. Also zu einem späteren
Zeitpunkt, wenn sie wirklich geschwindigkeitskritische
Applikationen schreiben. Ob jetzt nämlich <xhtml:code>echo()</xhtml:code> oder
<xhtml:code>print()</xhtml:code> schneller ist interessiert im Endeffekt
niemanden - auch die Performancetests nicht. Bei sowas geht es nur
um subjektives Empfinden, was man als hübscher empfindet und ob man
in seinem kommenden PHP’ler Leben lieber tausendfach
<xhtml:code>echo()</xhtml:code> oder <xhtml:code>print()</xhtml:code> schreiben möchte.</xhtml:p>
<xhtml:p>Aber eigentlich will ich ja gar nicht auf Optimierung im Backend
eingehen. Was mich immer wieder erstaunt ist eher die Tatsache,
dass sich viele (sehr viele) Webentwickler einen Deut um ihr
Frontend scheren. Dabei geht da, durchschnittlich, viel mehr Zeit
verloren als im Backend.</xhtml:p>
<xhtml:p>Ein Beispiel: Jeder Request für ein eingebundenes Bild, eine
CSS- oder JavaScript-Datei braucht vergleichsweise viel Zeit. Ein
HTTP-Request muss gesendet werden, der Server muss ihn verarbeiten
und der Client die Antwort verwerten. Besonders schlimm wird es
dann, wenn keine ordentlichen Headers mitgeschickt und die Dateien
deshalb vom Browser nicht gecachet werden. Man denke mal an ein 500
KiB Foto das bei jedem Seitenaufruf geladen werden muss …
autsch!</xhtml:p>
<xhtml:p>Vor etwa einem Jahr las ich Yahoo!’s "<xhtml:a href="http://developer.yahoo.com/performance/rules.html">Best Practices
for Speeding Up Your Web Site</xhtml:a>". Damals noch ein 12-Punkte-,
heute ein 34-Punkte-Programm mit nützlichen Tipps zum Beschleunigen
von Websites. Dabei geht es genau darum, worauf ich eigentlich
hinaus will: <xhtml:strong>Programmierer, schaut euch euer Frontend
an!</xhtml:strong></xhtml:p>
<xhtml:p>Ich kann jedem Entwickler nur raten, sich die Punkte mal
durchzulesen. Nicht alle sind für den individuellen Zweck sinnig,
doch bekommt man gute Denkanstösse die man nach Möglichkeiten auch
umsetzen sollte.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/27/2009-07-05/die-schnelle-website-startet-vorne-nicht-hinten</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Welcome to the Federated Tables of MySQL]]></title>
    <published>2009-07-05T15:32:38+02:00</published>
    <updated>2009-07-05T15:32:38+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/mynDoXaB6Ic/welcome-to-the-federated-tables-of-mysql" />
    <id>http://bigwhoop.ch/artikel/24/2009-07-05/welcome-to-the-federated-tables-of-mysql</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/24/teaser.png" alt="Federated Tables of MySQL and Mysqlasia" /></xhtml:p>
<xhtml:p>Hinter dem Begriff Federated Tables verbirgt sich eine Technik
zum Verlinken (/Verb(i|ü)nden/) von Tabellen über die Grenzen einer
Datenbank, ja gar eines Datenbankservers, hinweg. Man kann sich das
wie einen Symlink unter *NIX, bzw. einer Verknüpfung unter Windows
vorstellen.</xhtml:p>
<xhtml:a id="ein-kleines-beispiel" name="ein-kleines-beispiel" />
<xhtml:h2>Ein kleines Beispiel</xhtml:h2>
<xhtml:p>Erstellen wir erst mal zwei kleine Testdatenbanken.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
CREATE DATABASE `fedtable_1` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE DATABASE `fedtable_2` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
</xhtml:pre></xhtml:div>
<xhtml:p>Anschliessend legen wir eine stinknormale Tabelle in der ersten
Datenbank an ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
CREATE TABLE `fedtable_1`.`normal` (
    `id` INT(3) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `firstname` VARCHAR(30) NOT NULL
)
ENGINE = MYISAM
</xhtml:pre></xhtml:div>
<xhtml:p>... und füllen sie mit ein paar Einträgen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
INSERT INTO `fedtable_1`.`normal` (`id`, `firstname`)
VALUES (NULL, 'entry1'),
       (NULL, 'entry2'),
       (NULL, 'entry3'),
       (NULL, 'entry4'),
       (NULL, 'entry5');
</xhtml:pre></xhtml:div>
<xhtml:p>Um jetzt eine Federated Table in der 2. Datenbank zu erstellen,
müssen wir lediglich die <xhtml:code>ENGINE</xhtml:code> auf
<xhtml:code>FEDERATED</xhtml:code> stellen und einen zusätzlichen
<xhtml:code>CONNECTION</xhtml:code> String mitgeben.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
CREATE TABLE `fedtable_2`.`federated` (
    `id` INT(3) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `firstname` VARCHAR(30) NOT NULL
)
ENGINE=FEDERATED
CONNECTION='mysql://root@127.0.0.1/fedtable_1/normal';
</xhtml:pre></xhtml:div>
<xhtml:p>Jetzt können wir in der Datenbank
<xhtml:code>fedtable<xhtml:em>2</xhtml:em></xhtml:code> <xhtml:em>mit der Tabelle
<xhtml:code>federated</xhtml:code> wie gewohnt arbeiten. In Wirklichkeit
greifen wir aber auf die Tabelle <xhtml:code>normal</xhtml:code> der Datenbank
<xhtml:code>fedtable</xhtml:code></xhtml:em><xhtml:code>1</xhtml:code> zu. Praktisch und
einfach.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
SELECT * FROM `fedtable_2`.`federated`;
</xhtml:pre></xhtml:div>
<xhtml:a id="folgendes-gilt-es-zu-beachten" name="folgendes-gilt-es-zu-beachten" />
<xhtml:h2>Folgendes gilt es zu beachten</xhtml:h2>
<xhtml:ul>
<xhtml:li>Die Struktur der <xhtml:strong>Federated Table muss</xhtml:strong> der
Strukut der <xhtml:strong>Quelltabelle entsprechen</xhtml:strong></xhtml:li>
<xhtml:li>Die <xhtml:strong>Indexe</xhtml:strong> sollten aus Performancegründen
stets <xhtml:strong>in beiden Tabellen</xhtml:strong> gesetzt werden</xhtml:li>
</xhtml:ul>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/24/2009-07-05/welcome-to-the-federated-tables-of-mysql</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[PHP und Multibyte Strings oder: Meine kleine String Klasse]]></title>
    <published>2009-07-04T15:59:31+02:00</published>
    <updated>2009-07-04T15:59:31+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/fw8HXU055Cs/php-und-multibyte-strings-oder-meine-kleine-string-klasse" />
    <id>http://bigwhoop.ch/artikel/26/2009-07-04/php-und-multibyte-strings-oder-meine-kleine-string-klasse</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Also ich vor einiger Zeit ein wenig mit Ruby rumspielte, kam ich
auf die Idee eine String-Klasse für PHP zu schreiben. Heute
stöberte ich im Blog von Benjamin Hofmann rum und fand dabei seinen
<xhtml:a href="http://ajaveeb.de/string-klasse-version-1-0-1-331" target="_blank">pragmatischen Ansatz für eine String Klasse</xhtml:a>. Dies
motivierte mich auch meinen Versuch zu präsentieren.</xhtml:p>
<xhtml:p>In PHP ist ein String eine Reihe von Bytes, wobei ein Byte einem
Zeichen entspricht. Das Problem ist, dass ein Byte nur 256
unterschiedliche Zustände haben kann. Ergo können nur 256
unterschiedliche Zeichen dargestellt werden. Bis PHP 6 dann gross
mit Unicode auftrumpfen wird, müssen sich alle nicht-amerikanischen
PHP Entwickler selber helfen.</xhtml:p>
<xhtml:a id="multibyte-strings-in-php" name="multibyte-strings-in-php" />
<xhtml:h2>Multibyte-Strings in PHP</xhtml:h2>
<xhtml:p>Schauen wir uns z.B. folgendes Code-Snippet in einer UTF-8 Datei
(womit wir ja hoffentlich alle arbeiten) an:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
echo strlen('ä');&lt;/pre&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Die Ausgabe ist nicht etwa <xhtml:code>1</xhtml:code>, sondern
<xhtml:code>2</xhtml:code>, da zur Speicherung das ä-Zeichens zwei Bytes
benötigt werden. Als Abhilfe stehen drei Möglichkeiten zur
Verfügung.</xhtml:p>
<xhtml:a id="mbstring-erweiterung" name="mbstring-erweiterung" />
<xhtml:h3>mbstring Erweiterung</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
echo mb_strlen('ä'); // 1
</xhtml:pre></xhtml:div>
<xhtml:p>Die <xhtml:code>mbstring</xhtml:code> Erweiterung wird direkt mit PHP
ausgeliefert und bietet Multibyte-Alternativen für viele native
String Funktionen. Die Portierbarkeit ist dadurch ziemlich gut,
allerdings werden nicht sehr viele Character Sets unterstützt. Mit
der Konfigurationsdirektive
<xhtml:code>mbstring.func<xhtml:em>overload</xhtml:em></xhtml:code> <xhtml:em>lassen sich
ausserdem die nativen String Funktionen durch alle vorhandenen
<xhtml:code>mbstring</xhtml:code>-Äquivalente "überladen" (an Stelle von
<xhtml:code>strpos()</xhtml:code> wird automatisch 
<xhtml:code>mb</xhtml:code></xhtml:em><xhtml:code>strpos()</xhtml:code> aufgerufen).
<xhtml:code>mbstring</xhtml:code> eignet sich dadurch sehr gut zum Arbeiten mit
Strings.</xhtml:p>
<xhtml:a id="iconv-erweiterung" name="iconv-erweiterung" />
<xhtml:h3>iconv Erweiterung</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
echo iconv_strlen('ä'); // 1
</xhtml:pre></xhtml:div>
<xhtml:p>Die <xhtml:code>iconv</xhtml:code> Erweiterung wird standardmässig nicht mit
PHP ausgeliefert und ist deshalb auch nicht auf allen Systemen
automatisch vorhanden. Ausserdem gibt es wenige Funktionen zum
Arbeiten mit Multibyte-Stringen. Weil die <xhtml:code>iconv</xhtml:code>
Erweiterung aber viele Character Sets unterstützt, eignet sie sich
hervorragend zum Konvertierten von einem Encoding ins andere.</xhtml:p>
<xhtml:a id="utf-8-dekodierung" name="utf-8-dekodierung" />
<xhtml:h3>UTF-8 Dekodierung</xhtml:h3>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
echo strlen(utf_decode('ä')); // 1
</xhtml:pre></xhtml:div>
<xhtml:p>Solange eine Seite - und damit meine ich sowohl Code als auch
Files, Datenbank, Formulardaten, etc. - in UTF-8 betrieben wird,
ist die Benutzung der nativen String Funktionen relativ sicher
möglich. Man sollte einfach schauen, dass die UTF-8 Strings zuerst
mit <xhtml:code>utf8_decode()</xhtml:code> in ISO-8859-1 Strings konvertiert
werden.</xhtml:p>
<xhtml:p>Auf der nächsten Seite geht es weiter mit meiner String
Implementierung ...</xhtml:p>
<xhtml:p>Mehr gibt es nach dem <xhtml:a href="http://bigwhoop.ch/artikel/26/2009-07-04/php-und-multibyte-strings-oder-meine-kleine-string-klasse">
Sprung</xhtml:a>! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/26/2009-07-04/php-und-multibyte-strings-oder-meine-kleine-string-klasse</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[count() in for-Schleifen]]></title>
    <published>2009-06-22T07:08:32+02:00</published>
    <updated>2009-06-22T07:08:32+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/qb4lM15EszQ/count-in-for-schleifen" />
    <id>http://bigwhoop.ch/artikel/21/2009-06-22/count-in-for-schleifen</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Als Appetizer etwas Code. ;-)</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = array('foo', 'bar', 'lala');
for ($i = 0; $i &lt; count($a); $i  ) {
    // ...
}
</xhtml:pre></xhtml:div>
<xhtml:p>Es kommt selten vor, dass ich sowas überhaupt brauche, da in
diesen Fällen foreach() viel einfacher ist. Dennoch kann es
vorkommen, dass eben diese Notation erwünscht ist.</xhtml:p>
<xhtml:p>Durch einen Kommentar auf <xhtml:a href="http://stackoverflow.com">StackOverflow</xhtml:a> bin ich auf folgenden
Ansatz gestossen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = array('foo', 'bar', 'lala');
for ($i = 0, $c = count($a); $i &lt; $c; $i  ) {
    // ...
}
</xhtml:pre></xhtml:div>
<xhtml:p>Ich kannte diese Notation nicht und habe deshalb bei grösseren
Arrays stehts die Grösse in einer separaten Zeile ausgelesen. Etwa
so ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
$a = array('foo', 'bar', 'lala');
$c = count($a);
for ($i = 0; $i &lt; $c; $i  ) {
    // ...
}
</xhtml:pre></xhtml:div>
<xhtml:p>Dies ist anzuraten, da count() ansonsten bei jeder Iteration
ausgeführt wird. Folgende kleine Benchmark zeigt die Differenz gut
auf.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
foreach (array(1, 100, 1000, 10000, 100000) as $l)
{
    echo '&lt;h1&gt;' . $l . '&lt;/h1&gt;';

    $a = range(1, $i);
    $t1 = microtime(true);
    for ($i = 0; $i &lt; count($a); $i  ) {}
    echo round((microtime(true) - $t1) * 1000, 2) . 'ms';

    echo '&lt;br /&gt;';

    $t1 = microtime(true);
    for ($i = 0, $c = count($a); $i &lt; $c; $i  ) {}
    echo round((microtime(true) - $t1) * 1000, 2) . 'ms';
}
</xhtml:pre></xhtml:div>
<xhtml:table class="DefaultTable" border="0">
<xhtml:tbody>
<xhtml:tr>
<xhtml:th>Grösse</xhtml:th>
<xhtml:th>Nicht optimiert</xhtml:th>
<xhtml:th>Optimiert</xhtml:th>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1</xhtml:td>
<xhtml:td>0.03ms</xhtml:td>
<xhtml:td>0.02ms</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>100</xhtml:td>
<xhtml:td>0.29ms</xhtml:td>
<xhtml:td>0.03ms</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1'000</xhtml:td>
<xhtml:td>3.43ms</xhtml:td>
<xhtml:td>0.27ms</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>10'000</xhtml:td>
<xhtml:td>27ms</xhtml:td>
<xhtml:td>2.41ms</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>100'000</xhtml:td>
<xhtml:td>272.16ms</xhtml:td>
<xhtml:td>22.88ms</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:p>Da diese Werte teils signifikante Unterschiede aufweisen werde
ich mir in Zukunft einfach angewöhnen, stehts die optimierte
Notation zu verwenden. So bin ich im Zweifelsfall auf der sicheren
Seite und spare sogar eine Zeile Code. ;-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/21/2009-06-22/count-in-for-schleifen</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Nichts ist wie es scheint]]></title>
    <published>2009-06-01T09:40:26+02:00</published>
    <updated>2009-06-01T09:40:26+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/UlpNrPKkpDw/nichts-ist-wie-es-scheint" />
    <id>http://bigwhoop.ch/artikel/16/2009-06-01/nichts-ist-wie-es-scheint</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:img src="http://bigwhoop.ch/img/articles/16/header.jpg" alt="Nichts ist wie es scheint ..." /></xhtml:p>
<xhtml:p>Besonders als Webdeveloper kommt man mit vielen verschiedenen
Dateitypen in Berührung. Den Typ einer Datei zu bestimmen ist aber
gar nicht so einfach wie es den Anschein macht. Den eine Dateendung
sagt rein gar nichts über eine Datei aus und kann so sogar zu
gefährlichen Sicherheitslücken führen.</xhtml:p>
<xhtml:p>Aber auch John Doe sollte sich ein wenig auskennen, wenn es um
Dateien im Internet geht. Denn auch für ihn gilt: Nichts ist wie es
scheint!</xhtml:p>
<xhtml:a id="dateien-unter-windows" name="dateien-unter-windows" />
<xhtml:h2>Dateien unter Windows</xhtml:h2>
<xhtml:p>Lasst uns erst mal erörtern, wie Microsoft Windows mit Dateien
umgeht. Unter Windows hat (fast) jede Datei eine Endung. Von
Bildern (<xhtml:em>.jpg</xhtml:em>, <xhtml:em>.gif</xhtml:em>, etc.) über Videos
(<xhtml:em>.avi</xhtml:em>, <xhtml:em>.mpg</xhtml:em>, ...) zu ausführbaren Dateien
(<xhtml:em>.exe</xhtml:em>, <xhtml:em>.bat</xhtml:em>, usw.). Doch wieso werden jetzt meine
MP3s mit meinem Lieblingsplayer geöffnet?</xhtml:p>
<xhtml:p>Die Antwort ist ganz einfach: Windows führt eine Liste mit
Assoziationen zwischen Dateiendungen und Programmen. Sobald eine
Datei geöffnet werden soll wird in dieser Liste nachgeschaut,
welches Programm dafür zuständig ist, und dieses anschliessend -
mit dem Pfad zur Datei als Parameter - aufgerufen. Wurde für die
Dateiendung kein Eintrag gefunden, öffnet sich ein Dialog, wo der
Benutzer auswählen kann, mit welchem Programm er die Datei öffnen
möchte.</xhtml:p>
<xhtml:div style="text-align: center;"><xhtml:img style="float: left; margin: 0 10px 10px 0;" src="http://bigwhoop.ch/img/articles/16/oeffnen_mit.png" alt="Öffnen mit-Dialog" /></xhtml:div>
<xhtml:p>Wenn wir also mal ein bisschen zu viel Freizeit hätten, könnten
wir all unsere MP3s mit der Endung <xhtml:em>.jpg</xhtml:em> abspeichern und
Windows so konfigurieren, dass JPEGs mit unserem Music Player
geöffnet werden. Wir hätten zwar ein grosses Chaos, würden aber
auch schnell merken, dass die Dateiendung nichts über eine Datei
aussagt. Also nutzen wir unsere Freizeit doch für Klügeres, aber
lesen dafür vorherigen Satz mindestens zehn Mal. Deal?</xhtml:p>
<xhtml:p>Obwohl du den Deal gebrochen hast, kehren wir zurück zum Thema
und schauen uns an, wie eine Datei im Internet überhaupt
lokalisiert und abgerufen werden kann.</xhtml:p>
<xhtml:a id="uri-url-wtf" name="uri-url-wtf" />
<xhtml:h2>URI, URL, wtf?</xhtml:h2>
<xhtml:p>Im Internet ist jede Datei über einen eindeutigen Identifikator
erreichbar. Dieser wird URI (Uniform Resource Identifier), oder -
im Zusammenhang mit dem HTTP- und FTP-Protokoll - auch URL (Uniform
Resource Locator), genannt.</xhtml:p>
<xhtml:a id="der-aufbau" name="der-aufbau" />
<xhtml:h3>Der Aufbau</xhtml:h3>
<xhtml:p>Eine URL besteht aus folgenden Teilen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
Schema://[Benutzer[:Passwort]@]Server[:Port][/Pfad][?Anfrage][#Fragmentbezeichner]
</xhtml:pre></xhtml:div>
<xhtml:p>Beispiele:</xhtml:p>
<xhtml:ul>
<xhtml:li>http://www.example.org</xhtml:li>
<xhtml:li>
ftp://pub:bup@ftp.example.org:21/google/pagerank-source.zip</xhtml:li>
<xhtml:li>http://test.example.org/index.html#top</xhtml:li>
<xhtml:li>http://www.example.org/search?q=phphil</xhtml:li>
<xhtml:li>etc.</xhtml:li>
</xhtml:ul>
<xhtml:a id="der-schwindel" name="der-schwindel" />
<xhtml:h2>Der Schwindel</xhtml:h2>
<xhtml:p>Ich habe da mal was vorbereitet ...</xhtml:p>
<xhtml:p>Schauen wir uns die Datei <xhtml:a href="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.jpg">http://pub.bigwhoop.ch/faked-pic/CaptainObvious.jpg</xhtml:a>
an.</xhtml:p>
<xhtml:div style="text-align: center;"><xhtml:img src="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.jpg" alt="CaptainObvious.jpg" /></xhtml:div>
<xhtml:p>Wie bereits durch die Dateiendung <xhtml:em>.jpg</xhtml:em> impliziert,
erscheint ein JPEG-Bild. Das liegt allerdings nur daran, dass der
Webserver (in unserem Fall ein Apache2 - merken für später!) bei
der Auslieferung den Content-Type <xhtml:em>image/jpeg</xhtml:em> mitgeschickt
und der Browser daraufhin die Daten als JPEG-Bild interpretiert
hat.</xhtml:p>
<xhtml:p>Schauen wir als nächstes <xhtml:a class="DefaultLink" href="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.mp3">http://pub.bigwhoop.ch/faked-pic/CaptainObvious.mp3</xhtml:a>
an. Na los, klick schon drauf! Na, erstaunt? Da kam nicht etwa eine
MP3-Datei, sondern das selbe JPEG-Bild wie vorher.</xhtml:p>
<xhtml:p>Schuld daran ist diese eine kleine Zeile innerhalb eines
<xhtml:em>.htaccess</xhtml:em>-Files auf dem Server:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
AddType image/jpeg .mp3
</xhtml:pre></xhtml:div>
<xhtml:p>Dadurch weist der Webserver alle Dateien mit der Endung
<xhtml:em>.mp3</xhtml:em> mit dem MIME-Type <xhtml:em>image/jpeg</xhtml:em> aus. Und da
haben wir auch schon das nächste Stichwort ...</xhtml:p>
<xhtml:a id="der-mime-type" name="der-mime-type" />
<xhtml:h2>Der MIME-Type</xhtml:h2>
<xhtml:p>Der MIME-Type, Internet Media Type oder auch Content Type
bestimmt den Typ einer Datei im Internet. Dies ist nötig, da z.B.
der Browser eben nicht wissen kann, welche Daten vom Server daher
kommen, wenn wir <xhtml:a href="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.mp3">http://pub.bigwhoop.ch/faked-pic/CaptainObvious.mp3</xhtml:a>
aufrufen. Auf die Dateiendung kann er sich ja, wie vorhin gelernt,
nicht verlassen.</xhtml:p>
<xhtml:p>Zum Aufbau: Der MIME-Type ist aufgeteilt in zwei Teile ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
&lt;Medientyp&gt;/&lt;Subtyp&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Der Medientyp kategorisiert die MIME-Types grob. Mögliche
Medientypen sind z.B. <xhtml:em>image</xhtml:em> (für Bilder), <xhtml:em>text</xhtml:em>
(für von Menschen lesbare Texte) oder <xhtml:em>audio</xhtml:em> (für
Musikdateien).</xhtml:p>
<xhtml:p>Der Subtyp spezifiziert die Untermenge des Medientyps. Beispiele
mit <xhtml:em>text</xhtml:em>: <xhtml:em>plain</xhtml:em> (für Klartext), <xhtml:em>html</xhtml:em>
(für HTML 4.01 kompatiblen HTML-Code) oder <xhtml:code>css</xhtml:code> (für
Cascading Style Sheets).</xhtml:p>
<xhtml:a id="eine-sache-der-konfiguration" name="eine-sache-der-konfiguration" />
<xhtml:h3>Eine Sache der Konfiguration</xhtml:h3>
<xhtml:p>Wie wir bemerkt haben, wird der Typ einer Datei nicht durch ihre
Endung, sondern durch ihren MIME-Type bestimmt. Damit der Webserver
(Apache2, remember!) den richtigen MIME-Type mitschicken kann,
unterhält er eine Liste von Assoziationen zwischen Dateiendungen
und MIME-Types. Also ähnlich wie Windows eine Liste zwischen
Endungen und Programmen besitzt. Bei einem Apache findet man diese
Definitionen übrigens in der Datei <xhtml:em>mime.types</xhtml:em>. Hier ein
Auszug ...</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
image/bmp            bmp
image/cgm            cgm
image/gif            gif
image/ief            ief
image/jpeg           jpeg jpg jpe
image/png            png
</xhtml:pre></xhtml:div>
<xhtml:p>Damit haben wir jetzt eigentlich auch schon den Wert einer
Dateiendung erörtert: Sie dient (lediglich) zur Herleitung von
Verknüpfungen.</xhtml:p>
<xhtml:a id="thesenerhaertung" name="thesenerhaertung" />
<xhtml:h2>Thesenerhärtung</xhtml:h2>
<xhtml:p>Kommen wir zurück auf das Bildbeispiel (<xhtml:a href="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.jpg">http://pub.bigwhoop.ch/faked-pic/CaptainObvious.mp3</xhtml:a>)
von vorhin. Anhand dessen will ich noch ein paar Beispiele
aufzeigen, die versinnbildlichen, dass die Dateiendung (und damit
übrigens auch der Dateipfad) keinen Aufschluss über den Typ einer
Datei geben können.</xhtml:p>
<xhtml:a id="der-programmierer-wars-" name="der-programmierer-wars-" />
<xhtml:h3>Der Programmierer war's ...</xhtml:h3>
<xhtml:p>Ein weiterer Weg um einen MIME-Type zu setzen ist die Verwendung
einer Server-seitigen Programmier-/Scriptsprache. Hier ein kleines
Beispiel in PHP.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
// CaptainObvious.php
header('content-type: image/jpeg');
echo file_get_contents('CaptainObvious.jpg');
</xhtml:pre></xhtml:div>
<xhtml:p>Dazu das Beispiel in der Praxis: <xhtml:a href="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.php">http://pub.bigwhoop.ch/faked-pic/CaptainObvious.php</xhtml:a>.</xhtml:p>
<xhtml:div style="text-align: center;"><xhtml:img src="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.php" alt="CaptainObvious.php" /></xhtml:div>
<xhtml:a id="url-rewritting" name="url-rewritting" />
<xhtml:h3>URL Rewritting</xhtml:h3>
<xhtml:p>Eigentlich jeder Webserver (meist durch Erweiterungen) bietet
die Möglichkeit, URLs on-the-fly umzuschreiben. Unter Apache heisst
das Ding z.B. <xhtml:a class="DefaultLink" href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html">mod_rewrite</xhtml:a>.</xhtml:p>
<xhtml:p>Am besten versteht man URL Rewritting anhand ein paar
Beispielen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
# Alle .html-Seiten nach .php umschreiben                                
# Aus http://example.org/test.html wird http://example.org/test.php
RewriteRule ^(. ).php$ $1.html

# Schöne Produktelinks                                  
# Aus http://example.org/produkt-12.html wird http://example.org/product.php?id=12
RewriteRule ^product-([0-9] ).html$ product.php?id=$1
</xhtml:pre></xhtml:div>
<xhtml:p>Zu beachten gilt, dass durch das Umschreiben der URL keine
HTTP-Redirect gemacht wird. Der Browser wird also nicht auf eine
andere Seite weitergeleitet. Dies zeigt sich auch dadurch, dass
sich die Adressezeile des Browser nicht verändert.<xhtml:br />
Okay, dies gilt natürlich nur, solange sich die Domain nicht
verändert. Wenn ich alle Anfragen von
<xhtml:code>http://example.org</xhtml:code> auf <xhtml:code>http://example.net</xhtml:code>
leite, muss der Browser gezwungenermassen eine neue Anfrage
machen.</xhtml:p>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h2>Fazit</xhtml:h2>
<xhtml:p>Folgende Erkenntnisse solltet ihr jetzt erlangt haben:</xhtml:p>
<xhtml:ul>
<xhtml:li>Eine Dateiendung hat keine Relevanz!</xhtml:li>
<xhtml:li>Besonders Programmierer dürfen sich nie auf die Dateiendung
verlassen!</xhtml:li>
<xhtml:li>Vertraut nie auf das, was in eures Browsers Adresszeile
steht!</xhtml:li>
<xhtml:li><xhtml:a href="http://pub.bigwhoop.ch/faked-pic/CaptainObvious.jpg">http://pub.bigwhoop.ch/faked-pic/CaptainObvious.mp3</xhtml:a>
wird zwar im Browser als Bild angezeigt, auf eurem System wird die
Datei aber nicht als Bild angesehen!</xhtml:li>
</xhtml:ul>
<xhtml:p>Danke fürs Lesen! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/16/2009-06-01/nichts-ist-wie-es-scheint</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[VLC Player goes Slapstick]]></title>
    <published>2009-05-28T18:41:37+02:00</published>
    <updated>2009-05-28T18:41:37+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/yvRGOKXRVdM/vlc-player-goes-slapstick" />
    <id>http://bigwhoop.ch/artikel/20/2009-05-28/vlc-player-goes-slapstick</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Wie man seinen Lieblingserien ein ganz anderes Leben
einhaucht.</xhtml:p>
<xhtml:a id="und-so-gehts-" name="und-so-gehts-" />
<xhtml:h2>Und so geht's ...</xhtml:h2>
<xhtml:ul>
<xhtml:li>Video nach Wunsch im VLC Player öffnen. Am besten eines, dass
ihr schon kennt. ;-)</xhtml:li>
<xhtml:li>CTRL E drücken um in die Erweiterten Einstellungen zu
gelangen.</xhtml:li>
<xhtml:li>Dort unter Videoeffekte / Farbspass / Farbextrahierung
<xhtml:em>FFFFFF</xhtml:em> eingeben.<xhtml:br />
<xhtml:img src="http://bigwhoop.ch/img/articles/20/vlc_color.png" title="VLC Player Farbeinstellung" alt="VLC Player Farbeinstellung" /></xhtml:li>
<xhtml:li>Auf der Tastatur die Plus-Taste (rechts bei den Zahlen :P)
drücken. Die Abspielgeschwindigkeit sollte jetzt auf 150%
sein.</xhtml:li>
<xhtml:li>Viel Spass! ^^</xhtml:li>
</xhtml:ul>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/20/2009-05-28/vlc-player-goes-slapstick</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA["WEEZER have just united the planet...!!"]]></title>
    <published>2009-04-27T18:21:00+02:00</published>
    <updated>2009-04-27T18:21:00+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/hcTyRzZ-gYI/weezer-have-just-united-the-planet" />
    <id>http://bigwhoop.ch/artikel/19/2009-04-27/weezer-have-just-united-the-planet</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Als ich heute Abend ein wenig in meiner musikalischen
Vergangenheit watete, entdeckte ich die guten, alten WEEZER-Songs
des Blue-Albums wieder. Über YouTubes "Related Videos" gelang ich
auf das Video von WEEZERs "Island in the Sun".</xhtml:p>
<xhtml:div style="text-align: center;"><xhtml:object width="425" height="344" data="http://www.youtube.com/v/hy4Y20dOlKs&amp;hl=de&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash"><xhtml:param name="allowFullScreen" value="true" />
<xhtml:param name="allowscriptaccess" value="always" />
<xhtml:param name="src" value="http://www.youtube.com/v/hy4Y20dOlKs&amp;hl=de&amp;fs=1&amp;rel=0" />
<xhtml:param name="allowfullscreen" value="true" /></xhtml:object></xhtml:div>
<xhtml:p>Das subtile "Hip, Hip" des Liedes schien dabei einen anderen
Zuschauer vor über sechs Monaten zu einem einfach Posting verleitet
zu haben:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Hip﻿ Hip from Romania</xhtml:p>
</xhtml:blockquote>
<xhtml:p>Und seit her haben es ihm geschätzte 2000 User, rund um den
Globus, gleich getan. Ob aus Peru, Kroation, Israel, dem Irak, aus
Frankreich, Kanada, Puerto Rico, der Tschechischen Republik oder
aus Brasilien, Deutschland, Slovenien, Rumänien, Finnland,
Singapur, Chile, etc., die WEEZER-Fans sind global vertreten und
erfreuen einander mit einem simplen "Hip, Hip"!</xhtml:p>
<xhtml:p>Einfach grossartig, wenn man merkt, wie die Welt zu diesem
globalen Dorf wird, wovon man so viel hört, es aber selten so zu
sehen bekommt!</xhtml:p>
<xhtml:p>In diesem Sinne: Hip, Hip! :-)</xhtml:p>
<xhtml:p>PS: Hier gehts zu den <xhtml:a href="http://www.youtube.com/comment_servlet?all_comments&amp;v=hy4Y20dOlKs">
Kommentaren</xhtml:a>!</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/19/2009-04-27/weezer-have-just-united-the-planet</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Custom times on NBA's League Pass Broadband]]></title>
    <published>2009-04-26T13:10:05+02:00</published>
    <updated>2009-04-26T13:10:05+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/CNCT0kOKbJM/custom-times-on-nbas-league-pass-broadband" />
    <id>http://bigwhoop.ch/artikel/18/2009-04-26/custom-times-on-nbas-league-pass-broadband</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>All you need is <xhtml:a class="DefaultLink" href="https://addons.mozilla.org/de/firefox/addon/748">Greasemonkey</xhtml:a>
(and Firefox) and <xhtml:a class="DefaultLink" href="../../../js/greasemonkey/nba_ilp_custom_times.user.js">this
script</xhtml:a>!</xhtml:p>
<xhtml:p>On your first visit on ilp.nba.com after installing the script
you'll be asked to enter your time zone by giving an UTC offset.
Your input will be stored in a cookie. So if your made a typo,
clear your cookies for the domain "ilp.nba.com" and try again.
;-)</xhtml:p>
<xhtml:a id="time-zones" name="time-zones" />
<xhtml:h2>Time zones</xhtml:h2>
<xhtml:p>Here some time zone offsets from UTC.</xhtml:p>
<xhtml:table class="DefaultTable" border="0">
<xhtml:tbody>
<xhtml:tr>
<xhtml:th>Time zone</xhtml:th>
<xhtml:th>UTC offset</xhtml:th>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Apia, Upolu, Samoa</xhtml:td>
<xhtml:td>-11:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Honolulu, Oahu, Hawaii, United States</xhtml:td>
<xhtml:td>-10:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Anchorage, Alaska, United States</xhtml:td>
<xhtml:td>-09:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Los Angeles, California, United States</xhtml:td>
<xhtml:td>-08:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Calgary, Alberta, Canada</xhtml:td>
<xhtml:td>-07:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Mexico City, Mexico</xhtml:td>
<xhtml:td>-06:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>New York City, United States</xhtml:td>
<xhtml:td>-05:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Santiago, Chile</xhtml:td>
<xhtml:td>-04:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>São Paulo, Brazil</xhtml:td>
<xhtml:td>-03:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Fernando de Noronha, Brazil</xhtml:td>
<xhtml:td>-02:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Praia, Cape Verde</xhtml:td>
<xhtml:td>-01:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>London, United Kingdom</xhtml:td>
<xhtml:td>+00:00 (= UTC)<xhtml:br /></xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Paris, France</xhtml:td>
<xhtml:td>+01:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Cairo, Egypt</xhtml:td>
<xhtml:td>+02:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Moscow, Russia</xhtml:td>
<xhtml:td>+03:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Dubai, United Arab Emirates</xhtml:td>
<xhtml:td>+04:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Karachi, Pakistan</xhtml:td>
<xhtml:td>+05:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Mumbai, India</xhtml:td>
<xhtml:td>+05:30</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Kathmandu, Nepal</xhtml:td>
<xhtml:td>+05:45</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Dhaka, Bangladesh</xhtml:td>
<xhtml:td>+06:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Rangoon, Myanmar</xhtml:td>
<xhtml:td>+06:30</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Jakarta, Indonesia</xhtml:td>
<xhtml:td>+07:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Hong Kong, China</xhtml:td>
<xhtml:td>+08:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Tokyo, Japan</xhtml:td>
<xhtml:td>+09:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Adelaide, South Australia, Australia</xhtml:td>
<xhtml:td>+09:30</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Sydney, New South Wales, Australia</xhtml:td>
<xhtml:td>+10:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Nouméa, New Caledonia, France</xhtml:td>
<xhtml:td>+11:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Auckland, New Zealand</xhtml:td>
<xhtml:td>+12:00</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Nukuʻalofa, Tonga</xhtml:td>
<xhtml:td>+13:00</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/18/2009-04-26/custom-times-on-nbas-league-pass-broadband</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[DynDNS Updates mit ddclient (Ubuntu)]]></title>
    <published>2009-04-19T17:06:24+02:00</published>
    <updated>2009-04-19T17:06:24+02:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/rqKUWFMTDvc/dyndns-updates-mit-ddclient-ubuntu" />
    <id>http://bigwhoop.ch/artikel/17/2009-04-19/dyndns-updates-mit-ddclient-ubuntu</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p><xhtml:em>ddclient</xhtml:em> ist ein kleiner, feiner Client zum Updaten von
DNS-Einträgen. Unter Anderem (jap, gross geschrieben!) lässt er
sich auch prima zum Erneuern von DynDNS-Adressen verwenden. Hier
eine Kurzanleitung.</xhtml:p>
<xhtml:a id="ddclient-installieren" name="ddclient-installieren" />
<xhtml:h2>ddclient installieren</xhtml:h2>
<xhtml:p>Mit aptitude geht die Installation ratzefatz!</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
sudo apt-cache update
sudo apt-get install ddclient
</xhtml:pre></xhtml:div>
<xhtml:a id="konfiguration-anpassen" name="konfiguration-anpassen" />
<xhtml:h2>Konfiguration anpassen</xhtml:h2>
<xhtml:p>Die ddclient-Konfiguration findet sich unter
<xhtml:code>/etc/ddclient.conf</xhtml:code>. Diese Datei also mit deinem Editor
nach Wahl (z.B. <xhtml:code>nano</xhtml:code>) öffnen und folgendermassen
anpassen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
pid=/var/run/ddclient.pid
protocol=dyndns2

use=web

server=members.dyndns.org
login=&lt;benutzername&gt;
password=&lt;passwort&gt;

&lt;shortdomain1&gt;.dyndns.org
&lt;shortdomain2&gt;.is-a-geek.org
&lt;shortdomain3&gt;.homelinux.org
#etc ...
</xhtml:pre></xhtml:div>
<xhtml:p><xhtml:code>use=web</xhtml:code> bewirkt, dass deine aktuelle IP-Adresse
über eine externe Website (z.B. http://checkip.dyndns.org/)
ermittelt wird.</xhtml:p>
<xhtml:a id="ddclient-als-dienst-daemon-einrichten" name="ddclient-als-dienst-daemon-einrichten" />
<xhtml:h2>ddclient als Dienst (Daemon) einrichten</xhtml:h2>
<xhtml:p>Mit einem Editor die Datei <xhtml:code>/etc/default/ddclient</xhtml:code>
öffnen und anpassen.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
run_daemon="true"
daemon_interval="300" #5 Minuten
</xhtml:pre></xhtml:div>
<xhtml:p>Die 300 definiert den Intervall in Sekunden, in dem ddclient auf
eine neue IP-Adresse überprüfen soll.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/17/2009-04-19/dyndns-updates-mit-ddclient-ubuntu</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Revision Hunting]]></title>
    <published>2009-03-26T15:05:26+01:00</published>
    <updated>2009-03-26T15:05:26+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/Go7-tFlnLDM/revision-hunting" />
    <id>http://bigwhoop.ch/artikel/14/2009-03-26/revision-hunting</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Mittlerweile sind wir bei der Entwicklung unserer firmeneigenen
Software bei Revision 5000 angekommen. Im Laufe der Zeit hat sich
dabei eine regelrechte Hetz nach den schönsten Revisionsnummern
ergeben.</xhtml:p>
<xhtml:a id="revisionen" name="revisionen" />
<xhtml:h2>Revisionen</xhtml:h2>
<xhtml:table class="DefaultTable" border="0">
<xhtml:tbody>
<xhtml:tr>
<xhtml:th>Revision</xhtml:th>
<xhtml:th>Committer</xhtml:th>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>100</xhtml:td>
<xhtml:td>Phil</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>500</xhtml:td>
<xhtml:td>Adrian</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>666</xhtml:td>
<xhtml:td>Adrian</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1000</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1111</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1337</xhtml:td>
<xhtml:td>Adrian</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>1500</xhtml:td>
<xhtml:td>Phil</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>2000</xhtml:td>
<xhtml:td>Jan</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>2222</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>2500</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>3000</xhtml:td>
<xhtml:td>Bob (Geschenk von Phil)</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>3333</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>3500</xhtml:td>
<xhtml:td>Phil</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>4000</xhtml:td>
<xhtml:td>Christian</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>4444</xhtml:td>
<xhtml:td>Phil</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>4500</xhtml:td>
<xhtml:td>Bob</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>5000</xhtml:td>
<xhtml:td>Phil</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:a id="rangliste" name="rangliste" />
<xhtml:h3>Rangliste</xhtml:h3>
<xhtml:ol>
<xhtml:li>Bob (8)</xhtml:li>
<xhtml:li>Phil (5)</xhtml:li>
<xhtml:li>Adrian (3)</xhtml:li>
<xhtml:li>Jan (1) Christian (1)</xhtml:li>
</xhtml:ol>
<xhtml:p>Die tollsten Revision hat aber mit <xhtml:em>666</xhtml:em> und
<xhtml:em>1337</xhtml:em> ganz klar Adrian erwischt. Gibt's tolle Revisionen
die ich vergessen habe?</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/14/2009-03-26/revision-hunting</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Twitter's "Rate limit exceeded. Clients may not make more than 100 requests per hour." aushebeln]]></title>
    <published>2009-03-22T16:13:26+01:00</published>
    <updated>2009-03-22T16:13:26+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/rgCDlQjmNKs/twitters-rate-limit-exceeded-clients-may-not-make-more-than-100-requests-per-hour-aushebeln" />
    <id>http://bigwhoop.ch/artikel/12/2009-03-22/twitters-rate-limit-exceeded-clients-may-not-make-more-than-100-requests-per-hour-aushebeln</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Als ich kürzlich begann mit der Twitter API rumzuspielen,
bemerkte ich ziemlich früh, dass Twitter die Anzahl der Anfragen
auf 100 pro Stunde limitiert. Der offizielle Weg um diese
Limitierung aufzuheben, ist, sich für die <xhtml:a href="http://twitter.com/help/request_whitelisting">Twitter-Whitelist</xhtml:a>
zu bewerben.</xhtml:p>
<xhtml:p>Dies war mir dann aber doch zu dumm und deshalb begann ich zu
rechnen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
60min * 60s   60 * 60s
----------- = -------- = 36s
100 * 1min      100    =====
</xhtml:pre></xhtml:div>
<xhtml:p>Meine Idee war nun, einfach sicherzustellen, dass maximal alle
36 Sekunden ein Request geschossen werden darf. Trotzdem mussten
die Daten stetig verfügbar sein.</xhtml:p>
<xhtml:p>Hier der Plan:</xhtml:p>
<xhtml:ul>
<xhtml:li>Überprüfen ob Daten gecachet wurden und ob sie jünger als 40
(*) Sekunden sind</xhtml:li>
<xhtml:li>Falls ja: Daten aus dem Cache lesen und zurückgeben</xhtml:li>
<xhtml:li>Falls nein: Gesamte Timeline von Twitter holen, wegcachen und
gewünschte Daten zurückgeben</xhtml:li>
</xhtml:ul>
<xhtml:p>* Mit 40 Sekunden bin ich auf der sicheren Seite, da ich so auf
"nur" 90 Requests pro Stunde komme.</xhtml:p>
<xhtml:a id="eine-beispielimplementierung-in-php" name="eine-beispielimplementierung-in-php" />
<xhtml:h2>Eine Beispielimplementierung in PHP</xhtml:h2>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
/**
 * Get recent posts from user timeline
 *
 * Twitter limits the requests to 100 per hour. That makes
 * one request every 36 seconds.
 * 
 * So we cache for about 40 seconds and then get the
 * timeline updated.
 *
 * @param int $count
 * @return array
 */
function getUserTimeline($count = 20)
{
    $cacheFilePath = '/path/to/the/cache/file';

    //if cache file doesn't exist or the file is older than 40 seconds, we may update
    if (!file_exists($cacheFilePath) || filemtime($cacheFilePath) &lt; time() - 40)
    {
        //add your functionality to get the user timeline
        //remember to retrieve all items you can get

        $timeline = array(); //this would be the items

        //cache the items
        file_put_contents($cacheFilePath, serialize($timeline));
    }
    else {
        //read the items from cache file
        $timeline = unserialize(file_get_contents($cacheFilePath));
    }

    return array_slice($timeline, 0, $count);
}   
</xhtml:pre></xhtml:div>
<xhtml:p>Auf der nächsten Seite gibt's noch eine Referenzimplementierung
von <xhtml:code>Zend_Service_Twitter</xhtml:code>.</xhtml:p>
<xhtml:p>Mehr gibt es nach dem <xhtml:a href="http://bigwhoop.ch/artikel/12/2009-03-22/twitters-rate-limit-exceeded-clients-may-not-make-more-than-100-requests-per-hour-aushebeln">
Sprung</xhtml:a>! :-)</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/12/2009-03-22/twitters-rate-limit-exceeded-clients-may-not-make-more-than-100-requests-per-hour-aushebeln</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Ein kleiner INI-File Writer/Reader in PHP]]></title>
    <published>2009-03-19T05:25:28+01:00</published>
    <updated>2009-03-19T05:25:28+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/2hqUKh3oqi0/ein-kleiner-ini-file-writerreader-in-php" />
    <id>http://bigwhoop.ch/artikel/11/2009-03-19/ein-kleiner-ini-file-writerreader-in-php</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Zwei kleine Funktionen mittels derer ein INI-File ausgelesen und
beschrieben werden kann. hF!</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
/**
 * Write data to an INI file
 * 
 * The data array has to be like this:
 * 
 *  Array
 *  (
 *      [Section1] =&gt; Array
 *          (
 *              [key1] =&gt; val1
 *              [key2] =&gt; val2
 *          )
 *      [Section2] =&gt; Array
 *          (
 *              [key3] =&gt; val3
 *              [key4] =&gt; val4
 *          )    
 *  )
 *
 * @param string $filePath
 * @param array $data
 */
function ini_write($filePath, array $data)
{
    $output = '';

    foreach ($data as $section =&gt; $values)
    {
        //values must be an array
        if (!is_array($values)) {
            continue;
        }

        //add section
        $output .= "[$section]rn";

        //add key/value pairs
        foreach ($values as $key =&gt; $val) {
            $output .= "$key=$valrn";
        }
        $output .= "rn";
    }

    //write data to file
    file_put_contents($filePath, trim($output));
}


/**
 * Read and parse data from an INI file
 * 
 * The data is returned as follows:
 * 
 *  Array
 *  (
 *      [Section1] =&gt; Array
 *          (
 *              [key1] =&gt; val1
 *              [key2] =&gt; val2
 *          )
 *      [Section2] =&gt; Array
 *          (
 *              [key3] =&gt; val3
 *              [key4] =&gt; val4
 *          )    
 *  )
 * 
 * @param string $filePath
 * @return array|false
 */
function ini_read($filePath)
{
    if (!file_exists($filePath)) {
        return false;
    }

    //read INI file linewise
    $lines = array_map('trim', file($filePath));
    $data  = array();

    $currentSection = null;
    foreach ($lines as $line)
    {
        if (substr($line, 0, 1) == '[') {
            $currentSection = substr($line, 1, -1);
            $data[$currentSection] = array();
        }
        else
        {
            //skip line feeds in INI file
            if (empty($line)) {
                continue;
            }

            //if no $currentsection is still null,
            //there was missing a "[&lt;sectionName&gt;]"
            //before the first key/value pair
            if (null === $currentSection) {
                return false;
            }

            //get key and value
            list($key, $val) = explode('=', $line);
            $data[$currentSection][$key] = $val;
        }
    }

    return $data;
}
</xhtml:pre></xhtml:div>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/11/2009-03-19/ein-kleiner-ini-file-writerreader-in-php</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[SI-Präfixe vs. IEC-Prefixe oder: Kilo bedeutet tausend!]]></title>
    <published>2009-03-11T17:23:20+01:00</published>
    <updated>2009-03-11T17:23:20+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/WbXPrGGNbCQ/si-praefixe-vs-iec-prefixe-oder-kilo-bedeutet-tausend" />
    <id>http://bigwhoop.ch/artikel/10/2009-03-11/si-praefixe-vs-iec-prefixe-oder-kilo-bedeutet-tausend</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:a id="die-korrekte-bezeichnung-fuer-kilobyte" name="die-korrekte-bezeichnung-fuer-kilobyte" />
<xhtml:h2>Die korrekte Bezeichnung für Kilobyte</xhtml:h2>
<xhtml:p>Die Masseinheit <xhtml:em>Kilobyte</xhtml:em> setzt sich zusammen aus
<xhtml:em>Kilo</xhtml:em> und <xhtml:em>Byte</xhtml:em>. Die genormten Symbole dafür sind
ein <xhtml:em>kleines K (k)</xhtml:em> für Kilo und ein <xhtml:em>grosses B (B)</xhtml:em>
für Byte. Somit ist das korrekte Symbol für Kilobyte
<xhtml:em>kB</xhtml:em>.</xhtml:p>
<xhtml:p>Folgende Symbole für Kilobyte sind somit falsch: <xhtml:em>kb</xhtml:em>,
<xhtml:em>KB</xhtml:em>, <xhtml:em>Kb</xhtml:em> und <xhtml:em>kbyte</xhtml:em>.</xhtml:p>
<xhtml:a id="kilo-tausend-10sup3sup" name="kilo-tausend-10sup3sup" />
<xhtml:h2>Kilo = Tausend = 10<xhtml:sup>3</xhtml:sup></xhtml:h2>
<xhtml:p>Jetzt wo dies geklärt ist, betrachten wir mal diese kleine
Gleichung:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
1 Kilobyte (kB) = 1024 Bytes (B)
</xhtml:pre></xhtml:div>
<xhtml:p>Historisch gesehen ist diese Gleichung korrekt. Mathematisch
gesehen aber nicht. Da es für das Binärsystem (Zweierpotenzen)
keine Einheitenprefixe gab, verwendete, bzw. missbrauchte, man
einfach das bestehende Dezimalsystem (Zehnerpotenzen). Hier eine
kleine Auflistung.</xhtml:p>
<xhtml:a id="si-praefixe-dezimalsystem-zehnerpotenzen" name="si-praefixe-dezimalsystem-zehnerpotenzen" />
<xhtml:h3>SI-Präfixe (Dezimalsystem, Zehnerpotenzen)</xhtml:h3>
<xhtml:table class="DefaultTable" border="0">
<xhtml:tbody>
<xhtml:tr>
<xhtml:th>Symbol</xhtml:th>
<xhtml:th>Name</xhtml:th>
<xhtml:th colspan="2">Wert</xhtml:th>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>T</xhtml:td>
<xhtml:td>Tera</xhtml:td>
<xhtml:td>10<xhtml:sup>12</xhtml:sup></xhtml:td>
<xhtml:td>1'000'000'000'000 (1 Billion)</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>G</xhtml:td>
<xhtml:td>Giga</xhtml:td>
<xhtml:td>10<xhtml:sup>9</xhtml:sup></xhtml:td>
<xhtml:td>1'000'000'000 (1 Milliarde)</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>M</xhtml:td>
<xhtml:td>Mega</xhtml:td>
<xhtml:td>10<xhtml:sup>6</xhtml:sup></xhtml:td>
<xhtml:td>1'000'000 (1 Million)</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>k</xhtml:td>
<xhtml:td>Kilo</xhtml:td>
<xhtml:td>10<xhtml:sup>3</xhtml:sup></xhtml:td>
<xhtml:td>1'000 (1 Tausend)</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:p>Wie wir aus den Tabellen entnehmen können, entspricht <xhtml:em>1 Kilo
(k)</xhtml:em> genau 10<xhtml:sup>3</xhtml:sup>, also <xhtml:em>1'000</xhtml:em> (1 Tausend).
Wieso um alles in der Welt sollte jetzt <xhtml:em>1 Kilo (k)</xhtml:em> in
Verwendung mit Bytes plötzlich <xhtml:em>1'024</xhtml:em> anstatt
<xhtml:em>1'000</xhtml:em> sein?<xhtml:br />
Genau diese Frage haben sich ein paar kluge Köpfe bereits 1996
gestellt und darauf die IEC-Präfixe (oder auch Binärprefixe)
ausgearbeitet. Da die IEC-Präfixe mit der Zweierpotenz arbeiten
sind sie hervorragend geeignet für die Informationstechnlogie, die
ja schliesslich auf dem Binärsystem "basiert".</xhtml:p>
<xhtml:a id="iec-praefixe-binaersystem-zweierpotenzen" name="iec-praefixe-binaersystem-zweierpotenzen" />
<xhtml:h3>IEC-Präfixe (Binärsystem, Zweierpotenzen)</xhtml:h3>
<xhtml:table class="DefaultTable" border="0">
<xhtml:thead>
<xhtml:tr>
<xhtml:th>Symbol</xhtml:th>
<xhtml:th>Name</xhtml:th>
<xhtml:th colspan="2">Wert</xhtml:th>
</xhtml:tr>
</xhtml:thead>
<xhtml:tbody>
<xhtml:tr>
<xhtml:td>Ti</xhtml:td>
<xhtml:td>tebi</xhtml:td>
<xhtml:td>2<xhtml:sup>40</xhtml:sup></xhtml:td>
<xhtml:td>1'099'511'127'776</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Gi</xhtml:td>
<xhtml:td>gibi</xhtml:td>
<xhtml:td>2<xhtml:sup>30</xhtml:sup></xhtml:td>
<xhtml:td>1'073'741'824</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Mi</xhtml:td>
<xhtml:td>mebi</xhtml:td>
<xhtml:td>2<xhtml:sup>20</xhtml:sup></xhtml:td>
<xhtml:td>1'048'576</xhtml:td>
</xhtml:tr>
<xhtml:tr>
<xhtml:td>Ki</xhtml:td>
<xhtml:td>kibi</xhtml:td>
<xhtml:td>2<xhtml:sup>10</xhtml:sup></xhtml:td>
<xhtml:td>1'024</xhtml:td>
</xhtml:tr>
</xhtml:tbody>
</xhtml:table>
<xhtml:a id="klingt-doch-ganz-toll" name="klingt-doch-ganz-toll" />
<xhtml:h2>Klingt doch ganz toll?</xhtml:h2>
<xhtml:p>Richtig, mein fragenstellender Freund. Doch leider haben sich
diese Binärprefixe bis jetzt nicht durchsetzen können und haben
gesellschaftlich eine sehr, sehr geringe Verbreitung. Sogar viele
gestandene Informatiker haben noch nie was davon gehört. Es wird
aber zunehmend wichtig, dass dieser "Fehler" beseitigt wird. So
sind heute normale Heimanwender-Festplatten bereits im
Terabyte-Bereich angekommen und damit lässt sich eine interessante
Feststellung machen:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
1 Terabyte (TB) = 10&lt;sup&gt;12&lt;/sup&gt; Bytes = 1'000'000'000'000 Bytes
1 Tebibyte (TiB) = 2&lt;sup&gt;40&lt;/sup&gt; Bytes = 1'099'511'627'776 Bytes&lt;/pre&gt;
</xhtml:pre></xhtml:div>
<xhtml:p>Betrachten wir nun die Differenz der beiden Gleichung:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
1'099'511'627'776 Bytes - 1'000'000'000'000 Bytes = 99'511'627'776 Bytes
                                                  = 92.677 Gebibytes (GiB)
                                                  = 99.512 Gigabytes (GB)
</xhtml:pre></xhtml:div>
<xhtml:p>Erstaunlich, nicht? Da eine <xhtml:em>1 Terabyte</xhtml:em> Festplatte
"korrekt" bezeichnet ist besitzt sie tatsächlich
<xhtml:em>1'000'000'000'000 Bytes</xhtml:em>, und nicht etwa
<xhtml:em>1'099'511'627'776 Bytes</xhtml:em>. Der Computer rechnet bei der
Verwendung dann aber im Binärsystem, wodurch bei der Umrechung aus
<xhtml:em>1'000'000'000'000 Bytes</xhtml:em> nur <xhtml:em>931.323 Gibibyte (= 1
Terabyte)</xhtml:em> entstehen. Das Hauptproblem ist jetzt aber, dass die
meisten Anwendungen die SI-Einheiten zur Darstellungen verwenden.
So ist zum Beispiel unsere <xhtml:em>1 Terabyte</xhtml:em> Festplatte im
Windows Arbeitsplatz als <xhtml:em>931 Gigabyte</xhtml:em> dargestellt, obwohl
es sich eigentlich um <xhtml:em>Gibibyte</xhtml:em> handeln würde.</xhtml:p>
<xhtml:p>Vollständigkeitshalber hier noch mal die Umrechung:</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
1 Terabyte (TB) = 1'000'000'000'000 Bytes (B) = 931.323 Gibibytes (GiB)
</xhtml:pre></xhtml:div>
<xhtml:a id="fazit" name="fazit" />
<xhtml:h2>Fazit</xhtml:h2>
<xhtml:p>So, und jetzt bist du gefragt. Arbeite an dir und ändere deinen
Sprachgebrauch. Sprich nur von SI-Prefixen im Zusammenhang mit
Zehnerpotenzen. Sobald es um Zweierpotenzen geht, solltest du auf
die IEC-Prefixe ausweichen.</xhtml:p>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/10/2009-03-11/si-praefixe-vs-iec-prefixe-oder-kilo-bedeutet-tausend</feedburner:origLink></entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Mittels PHP überprüfen ob ein Wikipedia Artikel existiert]]></title>
    <published>2009-02-15T06:43:32+01:00</published>
    <updated>2009-02-15T06:43:32+01:00</updated>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/phphil/~3/1YPPoBnP8dw/mittels-php-ueberpruefen-ob-ein-wikipedia-artikel-existiert" />
    <id>http://bigwhoop.ch/artikel/4/2009-02-15/mittels-php-ueberpruefen-ob-ein-wikipedia-artikel-existiert</id>
    <author>
      <name>Philippe Gerber</name>
      <email>philippe@bigwhoop.ch</email>
      <uri>http://bigwhoop.ch/philippe</uri>
    </author>
    <content type="xhtml">
      <xhtml:div><xhtml:p>Mit cURL lässt sich auf ziemlich einfache Art überprüfen, ob ein
Wikipedia Artikel existiert. Dies, weil Wikipedia korrekterweise
einen <xhtml:code>404</xhtml:code> Statuscode mitschickt, falls ein
angeforderter Artikel nicht existiert.</xhtml:p>
<xhtml:div class="php-code">
<xhtml:pre class="brush: php">
class WikipediaException extends Exception
{}

class Wikipedia
{
    /**
     * URL to Wikipedia
     *
     * @var string
     */
    public static $wikiUrl = 'http://de.wikipedia.org/wiki/';


    /**
     * Check whether a Wikipedia article
     * exists or not
     *
     * @param string $articleToken
     * @return bool
     */
    public static function isArticleAvailable($articleToken)
    {
        if (!extension_loaded('curl')) {
            throw new WikipediaException('Please install cURL');
        }

        //open connection
        $ch = curl_init(self::$wikiUrl . $articleToken);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);

        //get status code for the wikipedia article
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        //close connection
        curl_close($ch);

        return (404 != $statusCode);
    }
}

error_reporting(E_ALL);
var_dump(Wikipedia::isArticleAvailable('Zeit'));  //true
var_dump(Wikipedia::isArticleAvailable('Zeit2')); //false
</xhtml:pre></xhtml:div>
</xhtml:div>
    </content>
  <feedburner:origLink>http://bigwhoop.ch/artikel/4/2009-02-15/mittels-php-ueberpruefen-ob-ein-wikipedia-artikel-existiert</feedburner:origLink></entry>
</feed>

