Archiv der Kategorie: Tutorial

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…

Java MySQL Tutorial

In Sachen Java und Datenbank bin ich ein totaler Neuling. Allerdings hält man sich ja gern fit in solchen Sachen und da wir hier firmenintern ein neues Desktop-Tool brauchen, bot sich Java an. Für mich die einzige Schwierigkeit: Die Verbindung von Java zur MySQL-Datenbank.

Lange habe ich gesucht, lange herumprobiert und getippt und gelesen und wieder getippt. Am Ende habe ich es dann geschafft, mit ganz einfachen Mitteln eine Verbindung herzustellen.

Die Anforderungen waren:

  • Connect zur MySQL Datenbank
  • Ausführen eines SELECT´s
  • Auswerten der Antwort
  • Schließen der Datenbank

Das ganze aber ohne Frameworks wie Hibernate oder sowas, sondern nur mit Bordmitteln, die Java mitliefert. Betrachtet man das Ergebnis, ist es doch sehr einfach, aber man muss es ja auch erstmal wissen. Ich will es euch nicht vorenthalten. Dazu habe ich mal eine Beispiel – Konsolen Anwendung mit NetBeans erstellt, der Code läßt sich aber problemlos in große Projekte übernehmen.

Schritt 0: Benötigte imports

Folgendes import wird benötigt

import java.sql.*;

Vor den ganzen Code setzt man noch folgende Merker:

Statement stmt;       
ResultSet rs;

Die Funktion von ResultSet und Statement erkläre ich später.

Schritt 1: Treiber einbinden

(Alles ab hier sollte in einen try…catch Block)
Den Treiber für MySQL muss man mit 2 Schritten einbinden, in Netbeans geht das ziemlich einfach.
a) Rechtsklick auf das Projekt, Properties, dann Libraries, dann bei „Compile“ und „Run“ die „MySQL JDBC Driver“ mit „Add Library“ auswählen und bestätigen.
b) Den Code

Class.forName("com.mysql.jdbc.Driver");

hinzufügen.

Schritt 2: Verbindung zur MySQL-Datenbank herstellen

Die Verbindung zur Datenbank wird wie folgt hergestellt


String url     = "jdbc:mysql://localhost:3306/meinDatenbankSchema";
Connection con = DriverManager.getConnection(url,"benutzername", "benutzerpasswort");
stmt = con.createStatement();

Zeile 1 definiert das Datenbankziel, Zeile 2 stellt die eigentliche Verbindung her. Nicht vergessen, die Daten für „meinDatenbankSchema„, „benutzername“ und „benutzerpasswort“ anzupassen.
Zeile 3 erzeugt ein sogenanntes „Statement“ Objekt, mit welchem wir Anfragen an die Datenbank stellen können (Querys).

Schritt 3: Querys zur Datenbank senden

SQL-Querys sendet man mit Hilfe des Statement-Objektes zur Datenbank und wertet das ganze mit dem ResultSet-Objekt wieder aus.
SELECT-Beispiel, absenden des SQL, return-typ ist ResultSet:

rs = stmt.executeQuery("SELECT vorname, nachname FROM users");

UPDATE-Beipiel, absenden des SQL, return-typ ist integer:

int anzahlZeilen = stmt.executeQuery("UPDATE users SET vorname = 'Harry' WHERE vorname='Larry' ");
Schritt 4: Auswerten eines SELECT Ergebnisses

Bei einer SELECT Anfrage bekommt man ein ResultSet Objekt zurück, dieses kann man wie folgt auswerten:

while (rs.next())       
{
    String  vorname = rs.getString("vorname");
    String  nachname = rs.getString("nachname");
    System.out.println("Vorname: "+vorname+" | Nachname: "+nachname);
}
Schritt 5: Auswerten eines UPDATE Ergebnisses

Einfach den integer auswerten, er gibt die Anzahl der sogenannten „betroffenen Zeilen“ an.

Schritt 6: Verbindung zur MySQL-Datenbank schließen

Geht ganz einfach und sollte in jedem Fall gemacht werden (im Gegensatz zu PHP, wo das leider noch ein kann ist, ist es bei Java ein muss).

con.close();

So, ich hoffe, ihr könnt damit was anfangen – im wahrsten Sinne des Wortes. Mir jedenfalls wird es sehr helfen, meine ersten Datenbankabhängigen Servlets, JSP’s oder Java-Anwendungen zu schreiben.