Archiv für den Monat: April 2013

XDebug Logo

XDebug und Zend Server CE für Unit Tests und Code Coverage Reports

Wer Unit Testing betreibt, der will auch Code Coverage, ganz klare Sache. Für Code Coverage benötigt man in Verbindung mit phpUnit XDebug. In der Regel kein Problem.

Wer allerdings den ZendServer benutzt der war bisher angeschmiert, den XDebug im ZendServer zu konfigurieren kann nervig sein und eine falsch eingetragene Zeile kann den Betrieb des ZendServers sogar komplett lahmlegen.

Aber natürlich gibt es einen Weg, XDebug, ZendServer inkl. ZendDebugger laufen zu lassen, du bekommst also den ZendDebugger zum debuggen und XDebug zum Unit Testen deiner Anwendung, das beste aus beiden Welten – unter Windows 😉

Bereit? Los geht’s:

  1. ZendServer stoppen, entweder per Dienstkonsole oder mit „Apache Service Monitor“
  2. Lade dir die fehlende XDebug dll bei XDebug.org runter.
    Welche ist die passende?
    Zunächst erstmal die PHP Version deines ZendServers, dann den Link OHNE „TS“ und den mit 32-Bit, der sollte passen – war bisher bei allen meinen ZendServer-Installationen so.
    Beispiel mit PHP 5.4: „PHP 5.4 VC9 (32 bit)“
  3. Die .dll legst du nun im Verzeichnis
    /ZendServer/lib/phpext

    deines ZendServers ab.

  4. Nun ab in die php.ini
    Dort trägst du ziemlich weit unten aber ÜBER diesem Eintrag:

    zend_extension="C:\zend\ZendServer\lib\ZendExtensionManager.dll"

    (Pfad ist bei dir zumindest ähnlich)
    das hier ein:

    zend_extension="C:\zend\ZendServer\lib\phpext\php_xdebug-2.2.2-5.4-vc9-nts.dll"

    Natürlich ersetzt du den konkreten Namen durch deinen, bei mir ist das der ZendServer mit PHP 5.4 in der zum Veröffentlichungszeitpunkt aktuellsten Version von XDebug.

  5. Spaß mit Code Coverage!
    Ja, genau, schon fertig.

Ab nun kannst du Code Coverage Reports bekommen.

Was nicht geht: Du kannst mit XDebug (höchstwahrscheinlich) nicht wirklich debuggen – aber du hast ja den Zend Debugger, der zumindest mit dem Zend Studio wesentlich besser funktioniert.

Ich selbst habe bisher keine verlässlich funktionierende Konfiguration gefunden, mit dem ich via XDebug im Zend Server debuggen und profilieren konnte; mir reicht XDebug zum erzeugen der Code Coverages.

Vielen Dank geht an „Limespacer“ für diesen Beitrag, der mir dabei sehr geholfen hat:
http://www.limespace.de/2009/07/15/zend-server-ce-mit-xdebug/

P.S. Bei mir geht es auch mit aktiviertem Zend Debugger, falls das bei dir nicht der Fall sein sollte, dann schalte diesen wie im verlinkten Beitrag gezeigt einfach ab.

Windows Developer System – Virtual Hosts (03)

Nachdem wir die Basis unseres Systems nun installiert haben kommen wir nun zu einem Punkt, der ein wenig Erklärung bedarf, bevor wir zur Umsetzung kommen können: den Virtual Hosts.

Virtual Hosts sind, wie der Name schon sagt, virtuelle Maschinen, die es nicht wirklich gibt, dessen rein virtuelle Existenz wir uns zunutze machen, um eine echte Maschine zu simulieren. Aber von vorn:

Jeder kennt DNS, man gibt www.example.com ein, der Browser lädt und gibt uns entweder eine Webseite oder eine Fehlermeldung aus. Mal ganz stark vereinfacht rufen wir aber gar nicht die Domain mit Namen auf, weil es die gar nicht gibt, sondern wir rufen einen bestimmten Verzeichnisinhalt einer bestimmten IP auf. Da sich aber kein Mensch eine URL a la

http://192.168.178.254/~fritzdiewurst/whatever

merken könnte, erfand man DNS. DNS „matched“ einen Namen auf eine bestimmte IP.

Dieser Name ist in 2, meist in 3, Teile geteilt, damit die Auflösung schneller geht (das System ist recht alt, heute würde man dies nicht mehr mit Schnelligkeit begründen, damals war das aber echt so) und zwar der „First Level Domain“ (oder „Top Level Domain“ TLD), das ist meist das Länderkennzeichen am Ende, in unserem Fall das „com“, die „Second Level Domain“, das ist der eigentliche Name, bei uns also „example“ und die „Third Level Domain“, besser bekannt als „Subdomain“, bei uns das „www“. Top- und Second Level werden per DNS aufgelöst, Third ist Sache des Domaininhabers, aber das sind nur Details, wichtig also, dass dieser Name nun in eine bestimmte IP aufgelöst wird und der Request dann beim Webserver dieser IP weitergeht. Der Webserver bekommt nun ebenfalls den gesamten Request und kann dieser weiter auflösen auf bestimmte Verzeichnisse, so dass ein Webserver viele Domain mit unterschiedlichen Inhalten beinhalten kann.

Damit das alles funktioniert gibt es auf der ganzen Welt sogenannte DNS-Server die diese Auflösungsarbeit erledigen. Diese Synchronisieren sich alle untereinander, damit alle die gleiche Antwort auf die selbe Frage geben. Wie gesagt, stark vereinfacht, aber im Prinzip funktioniert das so.

Und warum erzähle ich das? Ganz einfach. Jedes Betriebssystem hat eine Steuerdatei die es dem lokalen System erlaubt, seine eigenen DNS-Richtlinien zu hinterlegen. Man kann also angeben, dass man gern bei der Eingabe von example.com auf eine bestimmte IP gelangen möchte. Dies ist die sogenannte „hosts“ Datei.

Und wofür brauchen wir als Entwickler so eine „hosts“ Datei?
Okay, zum Kern des „sagen-wollen’s“. Du betreust bei deiner Arbeit meist ein Projekt, das unter einer bestimmten URL zu erreichen ist, nehmen wir dieses Blog, da ist die URL

https://www.codemercenary.de

Wenn ich nun was an meinem Blog umprogrammiere, dann mache ich das nicht Live auf dem Server (sog. „hot coding“), sondern lokal auf meinem Entwicklungsrechner zuhause. Da habe ich meinen Webserver und meinen Datenbankserver.

Normalerweise legst du deine Daten auf deinem lokalen Webserver in das sogenannte „Document Root“ ab, dass ist in unserem Beispiel des Zend Servers das Verzeichnis „C:\zend\Apache2\htdocs“. Alles, was du da ablegst, kannst du mit der Eingabe von

http://127.0.0.1

abrufen, legst du also eine „phpinfo.php“ direkt in „htdocs“ rein, dann tippst du in deinem Browser

http://127.0.0.1/phpinfo.php

ein und du erhälst die Antwort, die das Script liefert. Easy, oder?

Das kannst du nun für alle deine Projekte machen, am besten jedes Projekt in ein neues Verzeichnis unterhalb von „htdocs“. So könnte ich z.B. mein Blog unter

http://127.0.0.1/codemercenary

aufrufen und alles wäre gut … oder nicht?

Eigentlich nicht, denn bald wirst du feststellen, dass sich manche Skripte sehr seltsam verhalten, wenn die nicht der „Platzhirsch“ auf der URL sind. Kurz: Manches lässt sich besser testen, wenn du es möglichst Live auf dem Server haben würdest. Willst du aber nicht, weil das „bad style“ bzw. „hot coding“ wäre und das gewöhnst du dir besser erst gar nicht an.

Es wäre doch super, wenn ich einfach

https://www.codemercenary.de

eintippe und der Browser ruft die Daten direkt von meinem lokalen Webserver ab. Ne, auch nicht gut, weil du dich dann gar nicht mehr per FTP verbinden könntest, falls dein FTP-Hostname der gleiche wäre. Doof, und nun?

Simpel: So gut wie alle Skripte die ich kenne (und das sind ne Menge, vor allem im Legacy Bereich) reagieren nur auf die TLD und die SLD, so gut wie nie auf die Subdomain und das nutzen wir nun aus. Wir definieren uns nun fest in den Kopf, dass es bei jedem Projekt nur 2 URLs gibt: eine mit www, die ist Live und eine mit einer Subdomain, die uns anzeigt, dass es sich um das Entwicklersystem handelt, also unser lokales System. Ich benutze dafür die Subdomain „dev“, so dass mein Aufruf

http://dev.codemercenary.de

lautet, wenn ich mal meine lokale Version testen oder debuggen will.

Damit nun der Aufruf nicht ins Internet geht sondern bei mir lokal verarbeitet wird muss ich meine „hosts“ anpassen. Die „hosts“ Datei findest du unter Windows immer an diesem Platz:

\Windows\System32\drivers\etc\hosts

Du musst zum bearbeiten übrigens Admin-Rechte haben.

Die Einträge machst du – vereinfacht gesagt – im Format IP<Leerzeichen>Name, in meinem Fall trage ich dort also

127.0.0.1 dev.codemercenary.de

ein. Damit wird der Aufruf

http://dev.codemercenary.de

schon mal auf die IP 127.0.0.1 umgeleitet und das ist bei jedem System die lokale Adresse!

Leider weiß nun unser Zend Server noch nix davon. Falls du nun schon mit gestartetem Server diese URL eingebt kommst du zwar auf dein lokales System, aber der Server führt dich in das globale Document Root, also direkt in „htdocs“. Da willst du aber nicht hin, sondern in das Unterverzeichnis deines Projektes.

Zur Info: Falls du schon <VirtualHost> Einträge hast, von denen aber keiner auf den ServerName matched, dann benutzt der Apache deinen ersten <VirtualHost> Eintrag in der .conf.

Nun gäbe es zwei Möglichkeiten. Du glücklicher, der du nur ein Projekt zu betreuen hast, kannst nun das Document Root des ganzen Servers auf das entsprechende VZ legen oder gleich alles in „htdocs“ speichern, du hast eh nur ein Projekt, da ist der Rest egal.

Die meisten von uns haben aber mehr wie nur ein Projekt und da heißt es nun, dass wir unserem Zend Server – genauer gesagt dem Apache Webserver – beibringen wollen, dass er beim Aufruf von

http://dev.exampleA.com

ins Unterverzeichnis „A“ gehen soll und bei

http://dev.exampleB.net

ins Verzeichnis „B“.

Für diese „Magie“ brauchen wir nun die Virtual Hosts, wir teilen unseren einen physikalischen Webserver nun in viele Virtuelle Webserver auf und können damit für unsere Projekte „echtes“ Internet simulieren.

Auch hierfür, für die Bearbeitung der Virtual Hosts, gibt es viele Wege. Keiner davon ist falsch, keiner der einzig richtige. Ich zeige dir einen Weg, mit dem ich nun seit 3 Jahren erfolgreich Beruflich arbeite. Es muss nicht der beste sein, aber er funktioniert und ist recht einfach zu bedienen und darüberhinaus ist dieser Weg der Updatesichere Weg, sobald du deinen Server updatet. Ich versuche an geeigneter Stelle auch alternative Wege zu zeigen, so wie mir diese bekannt sind.

An alle Linux-SysAdmins: Nicht böse sein, aber niemand weiß alles und ich bin gern bereit, dazu zu lernen. Die Kommentarfunktion bietet für Aufklärung Platz 😉

Also, Editor auf, folgende Datei laden:

\zend\Apache2\conf\zend.conf

Die Datei fängt meist so oder ähnlich an:

<Location /server-info>
    SetHandler server-info
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Location>

Kleiner Tip am Rande: Lass alles stehen, was in der Datei steht, zumindest so lange, bis du weißt, was die einzelnen Einträge zu bedeuten haben. Für’s erste brauchst du das alles nicht.

Zuallererst brauchst du in deiner „zend.conf“ einen Eintrag „NameVirtualHost“, sonst weiß der Apache gar nicht, was er machen soll. Dazu steht als erste Zeile der Datei:

NameVirtualHost 127.0.0.1:80

Um nun einen Aufruf des Browsers Namensabhängig zu verarbeiten habe ich diesen Eintrag:

<VirtualHost 127.0.0.1>
 ServerName dev.codemercenary.de
 DocumentRoot "C:\zend\Apache2\htdocs\codemercenary"
 RewriteEngine On
 ErrorLog "logs/codemercenary.log"
 CustomLog "logs/codemercenary.log" common
 <Directory "C:\zend\Apache2\htdocs\codemercenary">
  AllowOverride All
  Allow from all
  Options Indexes FollowSymLinks
 </Directory>
</VirtualHost>

Was bedeutet das nun alles? Die wichtigen Stellen sind diese:

  • ServerName: Dort steht der Name, so wie du ihn im Browser eingibst
  • DocumentRoot: Dort sucht der Server nach Inhalten
  • RewriteEngine On: Die mod_rewrite Engine wird benutzt
  • ErrorLog/CustomLog: Die Logfiles werden getrennt von den anderen geschrieben, sehr nützlich zur Fehlersuche
  • Directory-Eintrag: Ohne den läuft nix 😉 Hier nochmal das DR des Projektes angeben

Hast du mehrere Projekte, dann kannst du diese hintereinander dort eingeben, also mehrere <VirtualHost> Knoten. Die VirtualHosts für einen bestimmten Port müssen direkt nach der „NameVirtualHost“ Direktive eingetragen werden, die diesen Port bezeichnet und vor einer Direktive, die andere Port behandelt.

Hast du ein Projekt, dass mehrere Domains mit einem Script behandelt (Multi-Domain-Shops als Beispiel), dann gibst du einfach mehrfach untereinander die „ServerName“ Direktive ein, jeweils eine Domain pro „ServerName“ … zumindest funktioniert das bei mir so 😉

Hast du ein Projekt für andere Ports als Port 80 siehst du etwas weiter unten ein Beispiel für Port 10081, den Admin-Zugang des Zend Servers. Analog dazu lässt sich auch jeder andere Port ansprechen, es sei denn, er ist anderweitig belegt (21 für FTP als Beispiel).

Die Ports musst du übrigens NICHT in der „hosts“ Datei angeben, die ist Portunabhängig.

Wichtig ist nun, dass du deinen Server neu startest, denn sonst kennt der deine neuen Regeln für die VirtualHosts nicht. Bei den Einträgen der „hosts“ ist es zumindest beim Firefox so, dass du den einmal komplett zu und wieder auf machen musst, damit der die „hosts“ neu einliest, der Chrome und der IE (bei mir 10) machen das bei jedem Aufruf.

So, und da nun einige nach der versprochenen Alternative schreien: Ja, es geht auch anders. Du kannst anstelle einfach alle VirtualHosts in eine große Datei zu schreiben auch eine Datei für jeden VirtualHost anlegen, falls du das möchtet oder braucht (ließe sich zum Beispiel in deine Versionskontrolle integrieren). Der Zend Server ist standardmäßig so konfiguriert, dass er alle .conf Dateien im Verzeichnis

\zend\ZendServer\etc\sites.d\http\__default__\0

einliest und verarbeitet.

Du kannst also den <VirtualHost> Eintrag dort als Datei

codemercenary.conf

hinterlegen, dann noch eine „exampleA.conf“ mit der <VirtualHost> für exampleA.com usw.

Dieser Weg ist näher am „normalen“ Apache Server, funktioniert aber genauso.

Abschließend noch der Vorteil dieser gesamten Aktion: In deinem Projekt kannst du nun recht simpel prüfen, ob du lokal oder produktiv bist und dann entsprechend verschiedene Konfigurationen laden, z.B. für die Datenbankverbindung.

Einfach ein

if ('dev.codemercenary.de' == $_SERVER['HTTP_HOST']) {
  // lade lokale configuration
} else {
  // lade produktive configuration
}

und schon hast du auch in deiner Versionskontrolle keine verschiedenen Dateien mehr für lokal oder produktiv und kannst gefahrlos deployen.

Im nächsten Teil geht es dann weiter mit der Konfiguration deines Systems für PEAR, als Vorbereitung auf QA-Tools wie phpcs, pdepend, phpmd und natürlich auch phpunit. Bis dann…

Welche Dateien werden grade benutzt?

Besonders bei Legacy-Anwendungen stößt du häufig an den Punkt, dass eine bestimmte Funktion mehrfach deklariert wurde. In meinem extremsten Falle war das sogar in bis zu 12 Dateien – die gleiche Funktion, in 12 Dateien, zwölf!

Na gut, das ist echt die Ausnahme, Legacy Anwendungen tendieren zu einem Durchschnitt von 2-3 redundaten Funktionsdeklarationen, aber selbst das ist zuviel.

Nun möchtest du natürlich wissen, welche Funktion in deinem Fall nun konkret aufgerufen wird, damit du dem Kunden schnell und verlässlich die lang erwartete neue Funktion einbauen und vorführen kannst. Mit einer IDE geht es recht schnell, STRG+Linksklick beherrschen seit dem Visual Studio so gut wie alle IDEs – wobei es auch hier schon oft vorgekommen ist, dass selbst die IDE es nicht wusste und alle 3 vorkommen vorschlug. Ja Herrschaftzeiten, woher soll ICH denn bitteschön wissen, welche der drei Dateien denn nun aufgerufen wird?

Ganz einfach, mit get_included_files() bekommst du es heraus.

$included_files = get_included_files();
var_dump($included_files);

Und nun dürfte es etwas leichter fallen, die Wunschfunktion des Kunden einzubauen. Aber nur etwas 😉

Windows Developer System – Der Webserver (02)

Kommen wir in der Reihe des Windows Developer Systems nun zum Kern eures Entwickler-Systems, dem Webserver. Es gibt verschiedene Möglichkeiten, welchen Webserver man als Entwickler benutzt. Die Haupt Zielplattform wird sicherlich immer noch der gute, alte Apache Webserver sein. Da wir als Windows-ianer aber etwas verwöhnt sind, was Installation und Konfiguration von Software angeht benutzen wir für diesen Teil den Zend Server. Der hat den Vorteil, dass er komplett fertig als „One-Click-Installer“ reinkommt und nichts kostet außer ein paar Minuten Zeit.

Zuerst begibt man sich auf die aktuelle ZendServer Downloadseite und wählt die für sich passende Installation aus. Aktuell gibt es dort den ZS für PHP 5.3 und PHP 5.4 zur Auswahl.

Die Downloadseite des Zend Servers

Es wird zum Download AFAIK kein Account benötigt, falls doch ist dieser kostenfrei und auf jeden Fall die Mühe wert.

Nachdem ihr den Server runtergeladen habt, könnt ihr die Installation wie gewohnt starten. Der Server ist wirklich einfach zu installieren. Beim Zielverzeichnis können wir der Einfachheit halber Den Pfad “C:\” wählen, der Server wird dann unter “C:\zend” installiert. Die kurzen Dateipfade werden uns später die Arbeit etwas leichter machen, wenn es darum geht, Virtuelle Hosts aufzusetzen – dazu später mehr.

Das wirklich schöne am Setup des Zend Servers ist, dass im Schritt “Custom Setup” ganz unten die Option “MySQL Server” angewählt werden kann und damit nicht nur ein MySQL Server runtergeladen wird, sondern das Ganze auch fix und fertig serviert und konfiguriert wird. Wirklich praktisch!

Custom Setup des Zend Servers

Die restlichen Optionen müsst ihr nach euren Anforderungen setzen, ich belasse meist alles so wie es ist und füge nur die Option des MySQL Server hinzu, dann habe ich schon ein funktionierendes System.

Die Installation dauert je nach Optionen, Downloadgeschwindigkeit und CPU ein paar Minuten. Zeit für einen Kaffee 😉

Nach der Installation _kann_ es sein, dass manche Rechner neu starten müssen, andere jedoch nicht. Tut wie euch geheißen und ihr bekommt anschließend den kompletten Zend Server als Trial-Verison für 30 Tage. Keine Angst, nach Ablauf der 30-Tage verwandelt sich die “echte” Zend Server in die “Free”-Version, die genauso als Entwickler-Basis verwendbar ist – nur ein paar Profi-Features fehlen, das wirklich wichtige bleibt aber erhalten.

Je nach Präferenz könnt ihr in den Diensten von Windows nun auch den automatischen Start von “Apache” und “MySQL Server” auf “Automatisch” belassen oder auf “Manuell” setzen. Ich setze den Apache meist auf Manuell und starte diesen bei Bedarf, der MySQL Server läuft dagegen ständig, da ich öfters mal Datenbankabfragen aus meiner IDE starte, während ich programmiere. Aber auch hier: Eure Bier, macht’s, wie’s euch beliebt.

In eurer System-Tray (neben der Uhr) habt ihr nun auch ein schickes neues Icon, ein Klick drauf und ihr könnt den Server starten, stoppen oder restarten wie es euch gefällt. Ein Doppelklick führt zu einer netten Übersicht, die in der Praxis aber kaum Bedeutung hat.

Ob ihr nun glaubt oder nicht, euer Webserver mitsamt MySQL-Server ist nun installiert und einsatzbereit. Yes, it’s that easy!

Wenn der Apache gestartet ist erreicht ihr die Konfigurationsseite des ZendServers unter der URL

http://localhost:10081/ZendServer/

Beim ersten Aufruf (oder nach einem Update) müsst ihr den Üblichen EULA’s zustimmen und angeben, ob ihr den Server als “Development” Server benutzt oder als “Production”, dann ein Password für den Admin-Zugang eintragen und fertig ist der Server!

Zend Server Dashboard direkt nach Installation

Im Punkt “Configurations” könnt ihr einzelne Komponenten (de-)aktivieren und auch alle Teile der php.ini bearbeiten, inkl. Erklärungen. Grade für Neulinge im Bereich Webserver sehr praktisch. Der Server kann nach allen Änderungen die Ihr braucht per Klick neu gestartet werden.

Der größte Teil unter dem Mneüpunkt “Applications” fällt übrigens nach dem Ende der Trial-Phase weg und betrifft eh nur Cloud-“Zeug”, was erstmal nicht von belang sein soll. Wir wollen ja unser lokales System aufbauen und die Grundlage dafür ist nun vorhanden.

Schaut euch also nun in Ruhe euren neuen lokalen Webserver an. Im nächsten Teil geht es weiter mit der Konfiguration der Virtuellen Hosts und was man damit schönes machen kann.