PHP4 und PHP5 parallel auf dem Mac

Da die meisten Hoster (noch) kein PHP5 anbieten, entwickelt man die meisten PHP-Scripte in PHP4. Jedoch möchte man an mancher Stelle gerne „umswitchen“ zwischen den beiden Versionen – sei es, um sicherzugehen, dass das Script auch unter der neuen Version läuft, oder einfach nur weil man etwas ausprobieren möchte.

Xampp bietet zwar einen PHP-Switcher an, jedoch ist es 1. recht mühsam, wenn man entsprechende Pecl-Module einbinden möchte und 2. ein Problem, wenn man die aktuelle PHP-Version auch auf der Kommandozeile benötigt.

Ein weiterer Ansatz zur Lösung des Problems besteht darin, die PHP5-Scripte mit einer anderen Endung zu versehen und mit einem anderen PHP-Modul (meist dann als CGI installiert) zu parsen. Will man jedoch die Kompatibilität eines Systems testen, wird es schnell zu einer lästigen Aufgabe, ewig die Dateien umzubenennen.

[more]

Ich habe lange nach einer entsprechenden Lösung zu diesem Problem gesucht, bin jedoch leider nicht fündig geworden.
Auf meinem Mac habe ich es dann hinterher über den Umweg zweier PHP-Installationen in unterschiedlichen Ordnern gelöst. Hierfür habe ich die vorkompilierten Versionen von Entropy.ch genutzt. Dabei installiert sich PHP4 im Ordner /usr/local/php, PHP5 dagegen in /usr/local/php5. Die beiden Versionen kommen schon mit einigen vorkompilierten Erweiterungen und können mit phpize entsprechend nachträglich erweitert werden (z. B. Xdebug).

Die Installation der Module schreibt jeweils ein paar Zeilen in die /etc/httpd/httpd.conf, um das entsprechende Modul zu laden.
Um die jeweils andere Version auf dem Server verfügbar zu haben, muss man also nur noch die entsprechenden Zeilen des aktuellen Moduls in der httpd.conf kommentieren, oder man erstellt jeweils eine httpd4.conf und eine httpd5.conf und kopiert mit

sudo cp httpd(4/5).conf httpd.conf

die jeweils gewünschte Datei in die httpd.conf. Das hat jedoch den Nachteil, dass die beiden Dateien ständig untereinander abgeglichen werden müssen.
Eine weitaus bessere Lösung ist es, die jeweiligen Modulzeilen in eine andere Datei auszulagern und die entsprechende Datei dann mittels

Include pfad/zur/datei.conf

am Ende der httpd.conf einzubinden. Wer es noch einfacher mag, kann sich hierfür natürlich ein entsprechendes Shellscript basteln.

Da ja die aktuelle Serversion von PHP mit der lokalen übereinstimmen soll, kann man über das Terminal mit

sudo ln -sf /usr/local/php(5)/bin/php /usr/bin/php

Einen Symlink auf die aktuelle Version setzen. (Wer ein Shellscript geschrieben hat, kann diese Zeilen dann noch hinzufügen). Mann sollte jedoch aus Sicherheitsgründen /usr/bin/php vorher umbenennen und an einen anderen Ort kopieren.

Ein weiteres Problem besteht in den Include-Pfaden der verschiedenen php.ini – schießlich möchte man nicht auf die jeweils unter der anderen Version installierten Pakete verzichten. Bei mir habe ich dies mit dem Hinzufügen der anderen Pfade in der jeweiligen php.ini gelöst. Es gibt aber mit Sicherheit elegantere Methoden.

Zuletzt muss man noch den Apache einmal neu starten, damit alles funktioniert

sudo apachectl graceful

Das Ganze ewig „von Hand“ zu wiederholen ist recht mühsam, daher empfiehlt sich die Erstellung eines entsprechenden Shellscriptes (oder auch zwei, wenn man keine Bedingungen abfragen möchte).

Unter Linux sollte es eigentlich auch funktionieren, ist aber mit Sicherheit mehr Arbeit/Zeitaufwand, da man die beiden Versionen nicht einfach über apt-get oder als rpm installieren kann, sondern mit den jeweiligen Pfaden selbst kompilieren muss, was schon mal recht lange dauern kann.

Wenn jemand einen Tipp hat, wie man das Ganze noch vereinfachen kann, bin ich natürlich überaus dankbar ;)

PHP: Unit-Tests mit Simpletest

Bis vor kurzer Zeit habe ich für das Testen von PHP-Klassen PHPUnit genutzt und mich des Öfteren geärgert, dass es bei umfangreicheren Tests lange nicht an sein Vorbild JUnit heranreicht.
Der PHP5-Nachfolger PHPUnit2 erlaubt jetzt zwar auch das Testen mit Mock-Objects, ist aber in meinem Fall uninteressant, da ich ein Framework benötige, das mit beiden PHP-Versionen umgehen kann.

Nun ärgere ich mich nur noch darüber, nicht schon viel eher den Sprung zu Simpletest gemacht zu haben. Das Framework funktioniert einwandfrei mit beiden PHP-Versionen und unterscheidet sich in der Nutzung kaum von PHPUnit, kann aber deutlich mehr.

Simpletest bietet dabei nicht nur die Möglichkeit, mit Mock-Objects und Server Stubs zu testen, sondern bringt auch gleich nocht einen „Web Tester“ mit, mit dem man das erzeugte Html inklusive der Funktion von Formularen testen kann.
In diesem Zusammenhang finde ich besonders die Möglichkeit, Formulare testen zu können, sehr hilfreich.
In Verbindung mit Fakemail können sogar Email-Formulare auch ohne vorhandenen „echten“ Mailserver getestet werden (die Dokumentation von Simpletest hält hierfür ein ganzes Kapitel bereit).

Die Anzahl der assert-Funktionen ist ein wenig geringer als bei PHPUnit, jedoch trotzdem so ausgelegt, dass man sämtliche Bedingungen testen kann.
Die Dokumentation ist erstaunlich ausführlich und bietet zahlreiche gut erklärte Beispiele zu verschiedenen Einsatzgebieten und Funktionen.

Wer für seine Scripte entsprechende Testcases schreibt und sich Simpletest bisher noch nicht angesehen hat, sollte das unbedingt nachholen.

Codeschnipsel: Array-Helper für PHP

Einige Arrayfunktionen benötigt man in der Webentwicklung immer wieder - z. B. das Suchen eines regulären Ausdruckes innerhalb eines Arrays, oder eine Suche, die Gross und Kleinschreibung ignoriert.
Aus diesem Grund habe ich mir im Laufe der Zeit eine Art “Bibliothek” mit entsprechenden Funktionen zusammengebastelt, die ich dann nur immer wieder in das aktuelle Projekt einfüge.

Nach Regex suchen

function arraySearchRegex($regex, $array)) {
    foreach ($array as $k => $v) {
        if (ereg($regex, $v) {
            return $k;
        }
    }
    return false;
}

in_array unabhängig von Gross-/Kleinschreibung

//geht natürlich auch als array_search
function inArrayIgnoreCase($needle, $haystack) {
    foreach($haystack as $item) {
        if (strtolower($needle) == (strtolower($item))
            return true;
    }
    return false;
}

Das Errorhandling ist bei diesen Funktionen jedoch nicht implementiert (z. B. int statt Array übergeben), da diese Funktionen in der Regel von Methoden/Funktionen aufgerufen werden, die dies überprüfen.

Abgerundet wird meine “Bibliothek” durch einige Funktionen, die mittels array_walk oder array_walk_recursive das Array mit Funktionen “behandeln” (z. B. addslashes, trim, oder stripslashes).

Die oben genannten Funktionen sollen natürlich nur eine Basis darstellen, die jeder selbst erweitern kann.

PHP - wo willst du hin?

Ich entwickle nun seit Jahren in PHP und finde es nach wie vor für die Webentwicklung am besten geeignet. (Python hat kaum Möglichkeiten zum Session-Handling und Ruby on Rails ist kaum verfügbar)
Mit PHP 5 wurde nun einiges im Bezug auf Objektorientierte Programmierung hinzugefügt, welches der Entwicklergemeinde sicherlich sehr entgegenkam. Auch die Möglichkeit, mit Interfaces, privaten Methoden, oder Exceptions arbeiten zu können, ist sicherlich eine Bereicherugn.
Aber musste man auch direkt das Kopier/Referenz-Verhalten ändern? Natürlich kann man das Verhalten von PHP in dieser Hinsicht in der php.ini festlegen, aber wer keinen Zugriff darauf hat und “ältere“ Scripte laufen lassen will, der wird wohl um ein ini_set() nicht herumkommen (wenn erlaubt). Viele Webhoster machen allein aus Gründen der Kompatilibität kein Upgrade – viele der Kundenseiten würden einfach nicht mehr funktionieren!
Auch sind einige neue Funktionen unvollständig. Es ist ja nett, dass man nun in Methoden für einen Parameter eine erwartete Klasse festlegen kann, aber warum dann nicht auch andere Typen (Array, String, etc.) – man könnte ja für Parameter, deren Typ man nicht kennt einen speziellen Typ (ähnlich des „id“ in Objective-C) festlegen.

Ich bin auf jeden Fall gespannt, was PHP 6 (an dem ja laut aktuellen Meldungen gerade gearbeitet wird) noch für Überraschungen mit sich bringen wird.

Web SQL-Designer

wwwsql

Auf der Suche nach einem guten grafischen SQL-Editor bin ich heute zufällig auf WWW SQL Designer gestoßen.
Vielleicht optisch nicht gerade eine Augenweide, aber zur Planung des Datenbankdesigns einfach super.

Der WWW SQL Designer läßt sich schnell und einfach lokal installieren. Wer mag, kann die entsprechende MySQL-Tabelle installieren, damit die Entwürfe gespeichert werden können.

Export ist im SQL- und XML-Format möglich.

Eine(r) für alle...

Eclipse

Vielen Java-Entwicklern sollte eclipse (eine Open-Source IDE) mittlerweile bekannt sein.
Die wenigsten wissen jedoch, dass man mit Eclipse auch prima Websites entwickeln kann. Dabei ist die IDE vollkommen Betriebssystem-unabhängig, da in Java geschrieben und durch viele Plugins erweiterbar.

Mit den erforderlichen Plugins, auf die ich gleich noch zu sprechen – äh, schreiben – komme, ist eclipse ideal für die PHP- und Html-Entwicklung und kommt mit vielen Pluspunkten daher, die so mancher Editor vermissen lässt:

  • Projektverwaltung
  • integrierter CVS-Client
  • Syntax-Highlighting
  • Code-Vervollständigung
  • integrierter Debugger
  • HTML-Tidy (über Webdav)
  • eigener Browser, der das, was man programmiert hat, auch direkt darstellt
  • verschiedene „Workspaces“ – nützlich, wenn man z. B. für Java und PHP verschiedene Verzeichnisse nutzen möchte

[more]
Wer es mal mit eclipse probieren möchte, der kann sich die IDE Hier herunterladen.
Nachdem die Installation beendet ist und man eclipse das erste mal startet, kann man den Arbeitsbereich oder „Workspace“ angeben – keine Angst, der kann später noch geändert werden.
Wer möchte, kann sich erst mal die angebotetenen Tutorials anschauen.
Um PHP oder Html-Unterstützung zu haben, muss man jedoch erst noch PHP-eclipse und die Web Tools installieren..
Dies geht entweder per Download von den angegebenen Seiten, oder über das Menü „Help -> Software Updates -> Find and install“.

Eclipse neue Plugins installieren

Dann installiert man die Webtools

Eclipse-webdav

Zuletzt sollte man noch php-eclipse installieren und schon kann es mit der Programmierung losgehen.