Apr 03

Bildbearbeitungen unter PHP sind mit der bekannten GD-Lib schon lange möglich. Auch die Bibliothek ImageMagick ist eigentlich ein alter Zopf. Trotzdem war es (für mich) nicht ganz einfach auf meiner lokalen XAMPP-Entwicklungsumgebung unter Windows Vista diese schöne PHP-Extension zum Laufen zu bringen.

Wenn man so was nicht regelmäßig macht, dann steht meiner einer erst mal vor einigen Fragezeichen. Welche Version von welchen DLLs gehören wo hin? Wie aktiviere ich das in meiner PHP-Version? Welche PHP-Version muss es sein?

Folgendes Vorgehen führte bei mir letztlich zum Ziel:

  1. Frische XAMPP-Version (1.7.4) installieren. Wichtig war hier, dass mindestens PHP Version 5.3.x oder besser enthalten ist. Unter Windows Vista ist noch wichtig, XAMPP nicht in den üblichen Programme-Ordner (z.B. C:\Program Files) zu installieren. Das kann zu Problemen mit der Vista Rechtesteuerung führen. Ein gute Alternative ist C:\xampp.
    (Man kann übrigens auch mehrere XAMPP-Installationen parallel auf dem Rechner haben solange man die Komponenten (Apache, MySQL-Server etc.) nicht als Dienste betreibt).
  2. Die eigentliche XAMPP-Bibliothek als DLL-Datei für Windows (Binary Release) von http://www.imagemagick.org/script/binary-releases.php#windows herunterladen. WICHTIG: die “dynamic at 16 bits-per-pixel”-Version nehmen. Ob Win32 oder Win64 hängt dann von der Windows-Version ab.
    Auch hier sollte man die Installation NICHT in das vom Installer vorgeschlagene Windows-Programme-Standardverzeichnis vornehmen. C:\ImageMagick ist prima :-)
    Beim Installieren die Option zum Anlegen der Pfade unbedingt aktiv lassen – sonst kann die PHP-Extension später nix finden. Windows sollte man nach der Installation einmal neu starten.
  3. PHP Startup Error with IMagickJetzt braucht man noch die richtige DLL-Datei, die die imagick-PHP-Extension enthält. Denn nur diese kann mit der ImageMagick-DLL sprechen. Auch hier ist man als “Laie” zunächst überfordert. Gibt es doch von offizieller Seite leider kein konkretes vorgehen für Windows.
    Man muss sich Quellen wie dieser bedienen: http://www.sk89q.com/2010/03/vc6-windows-binaries-for-imagick-2-3-0/. Hier findet sich eine passende DLL, die in das Verzeichnis \ext\ der PHP-Installation (die bei XAMPP wiederum in \php\ zu finden ist) legen. Bei mir war das dann der Pfad C:\xampp2\php\ext\.
    Hinweis: Die meisten Quellen verweisen auf die Kompilate von valokuva.org. Diese DLLs sind aber nicht kompatibel zu der XAMPP-PHP-Kompilierung für Windows. Beim Start von XAMPP kommt dann die nebenstehende Fehlermeldung. Offensichtlich ist VC6 was anderes als VC9. Mehr habe ich auch nicht verstanden :-(
  4. Als letzten Schritt muss man noch die neue PHP-Extension in der php.ini aktiviert werden. Die php.ini liegt im \php\-Ordner von XAMPP und sollte natürlich nur mit einem Texteditor wie Notepad++ bearbeitet werden.
    Jetzt gibt es zwei Möglichkeiten. Entweder die Extension ist schon als Zeile vorhanden, aber auskommentiert oder sie fehlt komplett. Einfach mal nach “php_imagick” suchen. Findet sich eine Zeile der Art
    ;extension=php_imagick.dll
    dann muss nur das Semikolon am Zeilenanfang entfernt werden um die Extension zu aktivieren. Fehlt diese Zeile komplett, dann muss diese (ohne Semikolon) ergänzt werden (am besten unter dem Block wo sich auch schon die ganzen anderen extension=… Eintragungen befinden.
  5. Als letztes XAMPP starten und testen. Hier noch ein kleines Testscript, dass als Ausgabe ein kleines Bild generiert:
    <?php
     /* How wide is our image */
     $image_width = 200;
     /* Give zero for autocalculating the height */
     $image_height = 200;
     /* Specify the text */
     $text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
     Mauris lectus mi, mattis non, euismod vel, sagittis nec, ipsum.";
     /* Instanciate imagick */
     $im = new Imagick();
     /* Create new image using caption: pseudo format */
     $im->newPseudoImage( $image_width, $image_height, "caption:" . $text );
     /* Put 1px border around the image */
     $im->borderImage( 'black', 1, 1 );
     /* PNG format */
     $im->setImageFormat( "png") ;
     /* Output */
     header( "Content-Type: image/png" );
     echo $im;
     ?>
Oct 20

Möchte man SSL-Zertifikate mit Zwischenzertifikaten einsetzen (um höhere Sicherheit zu gewährleisten werden fast ausschließlich Zwischenzertifikate verwendet), so müssen diese in Apache, Dovecot bzw. Postfix zusätzlich zur üblichen SSL-Konfiguration hinterlegt werden.

Apache:

In der Datei “/etc/apache2/httpd.conf” muss folgende Zeile eingefügt werden:

SSLCACertificateFile /etc/ssl/certs/SSL123_CA_Bundle.pem

Dovecot:

In der Datei “/etc/dovecot/dovecot.conf” muss folgende Zeile eingefügt werden:

ssl_ca_file = /etc/ssl/certs/SSL123_CA_Bundle.pem

Postfix:

In der Datei “/etc/postfix/main.cf” muss folgende Zeile eingefügt werden:

smtpd_tls_CAfile=/etc/ssl/certs/SSL123_CA_Bundle.pem

Feb 02

Statische Dateien (z.B. CSS, JS, Bilder) verfügen in der Standardkonfiguration von diversen Webservern über keine Expires-Header. Dies führt dazu, dass Dateien i.d.R. vom Browser nicht im Cache zwischengespeichert werden und stets eine Anfrage an den Server gesendet wird. Neben einer größeren Belastung für den Server führt es außerdem zu langsameren Ladezeiten der Webseite. Mit dem Apache-Modul mod_exprires – bei Debian z.B. standardmäßig mit Apache installiert – kann der Expires-Header gesetzt und dem Browser mitgeteilt werden, wie lange sich dieses Element nicht ändern wird. Hierfür fügt man der .htaccess-Datei folgende Zeilen hinzu:

<IfModule mod_expires.c>
	ExpiresActive On
	#ExpiresDefault "access plus 7 days"
	ExpiresByType image/bmp "access plus 7 days"
	ExpiresByType image/gif "access plus 7 days"
	ExpiresByType image/jpeg "access plus 7 days"
	ExpiresByType image/jpg "access plus 7 days"
	ExpiresByType image/png "access plus 7 days"
	ExpiresByType image/x-icon "access plus 7 days"
	ExpiresByType text/css "access plus 7 days"
	ExpiresByType text/javascript "access plus 7 days"
	ExpiresByType text/x-js "access plus 7 days"
	ExpiresByType application/javascript "access plus 7 days"
	ExpiresByType application/x-javascript "access plus 7 days"
</IfModule>

Die Verwendung von ExpiresDefault (hier nicht aktiviert) würde dazu führen, dass für jede ausgelieferte Datei ein Expires-Header gesetzt werden würde. Dies sollte bei dynamisch generierten Webseiten vermieden, da diese aus dem Browser-Cache und nicht vom Server geladen werden und somit nicht den aktuellen Stand widerspiegeln würden. Header für JPG-Bilder und JavaScript werden in diesem Beispiel mehrfach gesetzt, damit unterschiedliche Mime-Types aufgrund verschiedener Konfigurationen von Servern und Ausgaben von Skripts abgedeckt sind.

Alternativ ist es auch möglich, den Expires-Header anhand der Dateiendung zu setzen:

<FilesMatch "\.(bmp|gif|jpg|jpeg|png|ico|css|js)">
	<IfModule mod_expires.c>
		ExpiresActive On
		ExpiresDefault "access plus 7 days"
	</IfModule>
</FilesMatch>

Diese Methode zeigt allerdings nur bei statischen Dateien Wirkung, weshalb bei z.B. dynamisch generierten Bildern die Mime-Type-Lösung gewählt werden muss.

Nov 06

Im Head-Tag jeder Webseite kann man das Charset/Zeichensatz festlegen, mit dem die Datei gespeichert wurde. Der korrekte Zeichensatz kommt dann zum Tragen, wenn es um Umlaute geht. ISO-8859-1 benötigt genau 1 Byte um alle enthaltenen Zeichen darzustellen, UTF-8 hat eine variable Länge bis zu 4 Byte. Daran lässt sich erkennen, dass UTF-8 mehr Zeichen darstellen kann, diese aber zum Teil auch eine andere Bytes- bzw. Bitkombination aufweisen als das selbe Zeichen in ISO-8859-1.

Neben der Übermittlung des verwendeten Zeichensatzes im Head-Tag, besteht auch die Möglichkeit den Zeichensatz im Header, der im Browser nicht angezeigt wird, sondern nur für die Kommunikation erforderlich ist, zu übermitteln.

Werden der verwendete Zeichensatz sowohl im Head-Tag als auch im Header übermittelt, so vertraut der Browser üblicherweise auf den im Header. Dieser muss allerdings nicht immer korrekt sein, schließlich ist sehr häufig ein Standardwert eingestellt, der nicht unbedingt mit dem tatsächlich verwendeten Zeichensatz übereinstimmt. Das Ergebnis sind dann Fragezeichen oder Quadrate anstelle von Umlauten.

Nun folgt noch, wie man die Charset-Einstellungen auf verschiedene Arten und Weisen setzen kann:

Im Head-Tag:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Header mit PHP-Skript setzen:

header("Content-Type: text/html; charset=utf-8");

In der php.ini:

default_charset = "utf-8"

In der Apache-Konfiguration oder in einer .htaccess-Datei (“AllowOverride FileInfo” muss hierfür erlaubt sein):

AddDefaultCharset Off
Um den Zeichensatz je nach Dateiendung festzulegen kann man in der Apache-Konfiguration oder in einer .htaccess-Datei folgende Einstellung treffen:
AddCharset UTF-8 .html
Nov 05

Wichtige Daten (z.B. Benutzername und Passwort, Daten der Bankverbindung,…) sollten immer über eine gesicherte SSL-Verbindung übertragen werden. Um eine verschlüsselte Verbindung zu erhalten, können mehrere Wege eingeschlagen werden. Ich möchte hier den Weg per PHP und den per .htaccess aufzeigen. Diese beiden Beispiele funktionieren im Gegensatz zu vielen anderen im Internet auch mit anderen als dem Standard-Port 993 für SSL.

SSL-Verschlüsselung mit PHP erzwingen

if (!isset($_SERVER['HTTPS']))
{
	header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']);
}

Wenn ein anderer Port als der Standard-Port verwendet wird, muss dieser noch eingefügt werden – z.B. “$_SERVER['HTTP_HOST'] . ‘:123′ . $_SERVER['REQUEST_URI']“, wobei “123″ mit dem gewünschten Port ersetzt werden muss.

SSL-Verschlüsselung mit .htaccess erzwingen

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Auch hier muss noch der Port eingefügt werden, sollte dieser nicht Standard sein – z.B. “https://%{HTTP_HOST}:123%{REQUEST_URI}”, wobei auch hier “123″ mit dem gewünschten Port ersetzt werden muss.