Ubuntu LAMP-Server mit PHP und MySQL einrichten

Nicht nur als Testsystem für zu Hause eignet sich die Ubuntu-Server-Installation hervorragend. Das Betriebsystem ist kostenlos und jederzeit aktuell über die Ubuntu-Webseite per Download zu beziehen und das System ist schnell installiert und konfiguriert. Die wichtigsten Schritte zum eigenen Ubuntu-Server möchte ich hier aufführen.

Zu aller erst wird das ISO-Image des aktuelle Ubuntu Server aus den Netz gezogen. Je nach Verwendung und Hardwaregegebenheiten ist eine CD zu brennen; oder man kann sich mit  dem ISO-Image begnügen. Die Installation ist simpel. Starten, Fragen beantworten, fertig.

Ganz so simpel ist die Installation nun doch nicht, doch nur wenige Schritte sind zu beachten. Neben Sprache, Rechnername, diversen Update-Fragen ist die erste Aufmerksamkeit auf die Frage nach der gewünschten Installationsroutine von Bedeutung. Wir möchten den LAMP-Server (Linux, Apache, MySQL, PHP) installieren. Zudem wählen wir „OpenSSH“ und „Samba“ aus. Wer dies nicht benötigt, kann dies selbstverständlich weglassen. Alle weiteren Fragen beantworten. Die Installation von MySQL fragt nach, ob der Root-User ein Passwort erhalten soll. Dies ist aus Sicht von MySQL nicht notwendig; aus Sicherheitsgründen jedoch ist die Eingabe eines Passwortes hier zwingend!

Wenn Ubuntu meldet, dass die CD entfernt werden sollte, ist die Installation beendet. Nach einem Neustart sollte der Server bereits im Netz via http://gewählter-rechnername sowie über Putty erreichbar sein, da LAMP einen Apache-Webserver installiert und konfiguriert und wir auch OpenSSH bei der Installation mit angegeben haben.

Wer den OpenSSH-Server vergessen hat, kann diesen nach einem Server-Neustart mit dem untenstehenden Kommando nachinstallieren:
sudo apt-get install openssh-server

Je nach (veralteter) Version sollte auf jeden Fall die untenstehenden Befehle nacheinander ausgeführt werden.
sudo aptitude update
sudo aptitude upgrade

Es gilt nun den Linux-Kernel zu aktualisieren:
sudo aptitude install linux-headers-`uname -r` build-essential
sudo apt-get install linux-headers-`uname -r` build-essential xinetd

Nach diesen wenigen Schritten haben wir in der Regel einen vernünftigen Linux-Server, den wir jedoch noch einmal neu Starten sollen (vor allem, wenn wir aus der Windows-Welt kommen):
sudo shutdown -r now

Die folgenden Befehle und Schritte sind optional, ich empfehle sie jedoch:

  1. Wir vergeben ein Root-Passwort mit „sudo passwd root“ (über diesen Schritt können sich Linux-Freaks bis ins Mark streiten; zumindest in einem lokalen Netz bin ich ein Freund vom Root-User).
  2. Wer mit MySQL und PHP arbeiten möchte, will vielleicht per “phpmyadmin“ die MySQL-Verwaltung übernehmen. Der folgenden Befehl installiert phpmyadmin:
    sudo apt-get install phpmyadmin
  3. Nach erfolgreicher Installation sollte phpmyadmin via http://servername/phpmyadmin erreichbar sein

Für einen Testserver waren dies bereits die erforderlichen Schritte.

Kurzbeschreibung der Schritte:

  1. Ubuntu Server installieren
  2. Bei Auswahl Server „LAMP“, „OpenSSH“ und „Samba“ wählen
  3. Die Installation abschließen
  4. Per Putty einloggen:
    sudo apt-get install openssh-server
    sudo aptitude update
    sudo aptitude upgrade
    sudo aptitude install linux-headers-`uname -r` build-essential
    sudo apt-get install linux-headers-`uname -r` build-essential xinetd
    sudo shutdown -r now
    sudo passwd root
    sudo apt-get install phpmyadmin

 

Batch Dateien: Pfad-Angaben mit Leerzeichen

Ich bleibe dabei: Die immer wieder todgeglaubte Batch-Datei ist nach wie vor elementarer Bestandteil vieler Computersysteme. Vergleichbar mit der altbekannten ini-Datei, die ihre Daseinsberechtigung nach wie vor gegen die Registry erkämpft, sind selbst heute noch kleine und große Batch-Files bei Produkten von Microsoft oder namhaften Fremdherstellern elementares Werkzeug.

Ein weiteres beliebtes Mittel ist die Batch-Datei bei einer Ablaufsteuerung von mehreren Jobs. Wenn diese zwingend hintereinander ausgeführt werden sollen, aber zeitlich nicht genau bestimmbar ist, wann ein Job endet, ist eine Lösung über den Task-Manager nur zweite Wahl. Es kann programmtechnisch sichergestellt werden, dass zwei Jobs nicht gleichzeitig ablaufen, doch der Aufwand ist wesentlich größer als eine separate Batch-Datei, die die Steuerung übernimmt.

Basis einer solchen Steuerung ist der Batch-Befehl „start /wait [Pfadangabe]“. Ein Batch-Programm, das einen Job mit dem Parameter „/wait“ startet, wartet an der Stelle mit der weiteren Ausführung, bis das auszuführende Programm geschlossen, also beendet wird.

Nachprüfen kann man das unter Windwos schnell wie folgt. Legen Sie eine Textdatei an und geben Sie die folgenden Befehle ein:

@echo off

echo Start des ersten Programmes ...
start /wait notepad.exe

echo Start des zweiten Programmes ...
start /wait notepad.exe

pause

Speichern Sie die Datei unter beliebigen Namen und ändern Sie die Dateiendung in „.bat“ oder „.cmd“. Wenn Sie das Programm mit Doppelklick ausführen, wird sich eine Commandbox mit dem Hinweis „Start des ersten Programmes …“ öffnen. Gleichzeitig öffnet sich Notepad. Wenn wir Notepad nun schließen, erscheint in der Command-Box „Start des zweiten Programmes  …“ und Notepad erscheint durch den zweiten Aufruf erneut. Wir sehen also, dass die Command auf das Ende des gestarteten Programmes wartet.
Durch diesen Aufbau ist nun eine Jobliste möglich, die hintereinander abgearbeitet werden muss. Die Command selbst kann durch Doppelklick, durch den Autostart-Ordner oder durch einen Aufruf in der Scheduled-Task-Liste gestartet werden.

Problemfall Datei-Aufruf: Pfad-Angabe mit Leerzeichen
Bei den folgenden Beispiele werden Sie auf den Problemfall Leerstelle in Pfadangaben stoßen. Ein beliebter Ordner ist der „Dokumente und Einstellungen“ –  Ordner, der bedingt durch zwei Leerstellen sofort zu Probleme führt:

@echo off

REM klappt
start /wait c:ordner1datei.bat

REM klappt auch
start /wait C:ordner1ordner2datei.bat

REM klappt nicht
start /wait C:ordner mit leerstelledatei.bat

REM klappt auch nicht
start /wait "C:ordner mit leerstelledatei.bat"

REM klappt auch nicht
start /wait 'C:ordner mit leerstelledatei.bat'

Wie also mit Pfadangaben umgehen, in denen Leerzeichen enthalten sind? Die Pfadangabe muss in einer Variablen zwischengespeichert werden, dann funktioniert auch der Aufruf, wie das folgende Beispiel demonstriert:

@echo off

%str%="C:Dokumente und Einstellungendatei.bat"
start /wait %str%

pause

MySQL Volltextsuche: Such-Wort Mindestlänge festlegen (ft_min_word_len=3)

Die MySQL-Volltextsuche ist bei MyISAM-Tabellen eine wirklich tolle Sache. Der spezielle Index „FULLTEXT“ ermöglicht es, mittels einfacher SQL-Abfrage textbezogene Ergebnisinhalte zu generieren, die mit einer LIKE-Abfrage nicht oder nur schwer zu erreichen wären.

MySQL-Fulltext Volltextsuche Beispiel
Nehmen wir einmal eine Suche in einem Shop an. Der Hersteller BIG stellt bekanntlich das Bobby Car. Eine Suche nach den Keywords „big“, „bobby“ und „car“ würde mit dem Link-SQL-Befehl folgendermaßen lauten:

SELECT * FROM produkte WHERE produktname LIKE ‚%BIG%‘ OR produktname LIKE ‚%bobby%‘ OR produktname LIKE ‚%car%‘

Die Abfrage ist sicherlich noch zu verbessern. Zeigt aber eines: Es werden auch Produkte in der Ergebnismenge auftauchen, die nicht im entferntesten  etwas mit unserem Spielzeug „Bobby Car“ zu tun haben.

Die MySQL Volltextsuche schafft da ein wenig „Linderung“. Durch die Abfrage MATCH AGAINST und dem Index FULLTEXT wird die Ergebnismenge durch eine interne Relevanzbewertung wesentlich verfeinert.

SELECT * FROM produkte
WHERE MATCH (produktname) AGAINST (‚big‘,’bobby‘,’car‘)

MySQL-Volltextsuche: Minimale Wortlänge von vier Zeichen
Jedoch werden wir durch das oben gewählte Beispiel auch dank der Volltextsuche keine optimalen Ergebnisse erhalten. MySQL nimmt per Standard nur Worte in den Index, die eine Wortlänge von mindestens vier Zeichen aufweisen. Bei unserer Abfrage nach ‚big‘,’bobby‘ und ‚car‘ wird letztendlich nu rein Wort, nämlich “bobby” als Suchbegriff gewählt. Die Begriffe „Big“ und „Car“ werden aufgrund der Wortlänge unterdrückt.

MySQL-Volltextsuche: ft_min_word_len=3
Aus Gründen der Performance betrachtet MySQL bei einer Volltextsuche nur Begriffe ab einer Wortlänge von vier Zeichen. Überprüfen kann man dies mit folgender SQL-Abfrage:

SHOW VARIABLES LIKE ‚ft_min_word_len‘

Per Default ist hier der Wert “4” vorgegeben. Leider ist es aber oftmals unumgänglich, dass auch 3stellige Begriffe betrachtet werden. Dies ist nicht nur mit der deutschen Sprache ein Problem: Auch im Englischen sind (hauptsächlich) Abkürzungen relevante Suchbegriffe. So ist der Wunsch, auch 3-stellige Wörter mit in den Suchindex aufzunehmen, oftmals eine Bedingung für eine optimierte SQL-Abfrage.

HowTo: MySQL Volltext-Suche Min-Word ändern

  1. Vergewissern Sie sich mittels der Abfrage „SHOW VARIABLES LIKE ‚ft_min_word_len’“, dass die Wortlänge nicht Ihren Wünschen entspricht.
  2. Öffnen Sie die Datei „my.cnf“. Diese ist, abhängig von Ihrer Installation, beispielsweise im Ordner „/etc/mysql/“ zu finden.
  3. Navigieren Sie in den Abschnitt „[mysqld]“. Suchen Sie dort den Eintrag „ft_min_word_len“. Ändern Sie diesen auf „ft_min_word_len=3“, wenn Sie die minimale Wortlänge auf „3“ einstellen möchten (von einem geringeren Wert rate ich ab!). Wenn dieser Eintrag nicht vorhanden ist, tragen Sie diesen dort ein. Ist er mit einem Gatter „#“ versehen, entfernen Sie das Gatter. Speichern Sie die Datei.
  4. Damit die Änderung greift, muss der MySQL-Server neu gestartet werden.
  5. Im nächsten Schritt muss der Index neu aufgebaut werden, da der bisherige Index mit einer nicht mehr relevanten Wortlänge erstellt wurde. Am Einfachsten können Sie via phpmyadmin (sofern vorhanden) den Index löschen und neu erstellen. Der sicherlich bessere Weg geht über die MySQL-Konsole.
  6. Loggen Sie sich in die Konsole ein.  Geben Sie danach folgenden Befehl (tbl_name anpassen) ein: REPAIR TABLE tbl_name QUICK;
  7. Nachdem der Index neu aufgebaut wurde, sollte unsere Volltext-Abfrage nach nach ‚big‘,’bobby‘ und ‚car‘ neuere und vor allem treffsichere Werte anzeigen. Kontrollieren können Sie die minimale Wortlänge erneut über die Abfrage SHOW VARIABLES LIKE ‚ft_min_word_len‘

 

MySQL-Datenbanken und Tabellen über MySQL-Konsole verwalten

Die PHP-Anwendung phpmyadmin ist heute bei fast jedem Web inklusive und bietet uns eine einfache Möglichkeit, MySQL-Datenbanken zu administrieren. Doch nicht immer ist phpmyadmin verfügbar und nicht alles ist über diese PHP-Skriptsammlung änderbar. Und natürlich: Richtige SQL-Freaks möchten es „nativ“ machen ….
Die folgende Beschreibung ist für MySQL-Datenbanken unter Linux geschrieben. Sollten Sie einen MySQL-Datenbankserver unter Windows betreiben, können einzelne Schritte anweichen. Grundlegend ist jedoch die Bedienung gleich.

MySQL Konsolen-Verbindung aufbauen
Sie verfügen bereits über eine Konsolenverbindung (beispielsweise über putty) zu Ihrem Server. Nun müssen Sie eine Verbindung zu Ihrem MySQL-Server aufbauen. Dies geschieht einfach über den Befehl „mysql“ sowie der Angabe einiger Parameter:

[root@srv-mysql ~]$ mysql --user=BENUTZERNAME --password=MEIN_PASSWORT

Nach Eingabe des korrekten Benutzers und Passwortes sollte Sie die MySQL-Konsole mit einem freundlichen „srv-mysql>“ empfangen. Die Konsole wartet nun auf weitere Befehle.

Verbindung beenden
Mit dem Befehl „quit“ beenden Sie die Sitzung:

srv-mysql> QUIT
Bye

MySQL Datenbank erstellen
Nun erstellen wir eine Datenbank mit den Namen „db_name“:

srv-mysql> CREATE DATABASE db_name;

Anzeige der vorhandenen Datenbanken
Um alle Datenbanken aufzulisten, geben Sie einfachd en Befehl “SHOW DATABASES” ein:

srv-mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_name            |
| mysql              |
+--------------------+
3 rows in set (0.00 sec)

Tabellen einer Datenbank auflisten
Wenn Sie die Tabellen einer Datenbank auflisten möchten, geben Sie einfach folgenden Befehl ein:

srv-mysql> SHOW TABLES FROM db_name;
+-------------------+
| Tables_in_db_name |
+-------------------+
| tbl_name          |
+-------------------+
1 row in set (0.00 sec)

Datenbank auswählen
Um mit einer Datenbank zu arbeiten, müssen Sie diese auswählen (eine Ausnahme ist die Anzeige der Tabellen im obigen Beispiel). Mit dem Befehl „use“ spezifizieren Sie eine Datenbank für die weitere Verwendung:

srv-mysql> USE db_name;
Database changed

Datenbank löschen
Das Löschen einer Datenbank geht schnell von der Hand. Seien Sie also mit folgendem Befehl sehr vorsichtig!

srv-mysql> DROP DATABASE db_name;
Query OK, 1 row affected (0.03 sec)

Tabelle in einer MySQL-Datenbank erstellen
Um eine Tabelle in einer Datenbank zu erstellen, geben Sie den Befehl „CREATE TABLE“ ein. Sie leiten die Eingabe mit „CREATE TABLE tbl_name (“ [RETURN] ein. Danach geben Sie den Spaltennamen gefolgt von Parametern sowie den Datentyp der Spalte ein. Das folgende Beispiel zeigt die Anlage eine Tabelle mit drei Spalten:

srv-mysql> CREATE TABLE tbl_name (
    -> id int NOT NULL,
    -> spalte1 varchar(255),
    -> spalte2 tinyint()
    -> );
Query OK, 0 rows affected (0.01 sec)

MySQL-Tabelle löschen
Mittels „DROP TABLE“ können Sie schnell eine ganze Tabelle löschen. Auch hier gilt: Vorsicht!

srv-mysql> DROP TABLE tbl_name;
Query OK, 0 rows affected (0.00 sec)

Tabellen der aktiven Datenbank anzeigen
Wenn Sie die Datenbank mit „use“ bereits spezifiziert haben, können Sie die Tabellen der Datenbank einfach mit „SHOW TABLE“ anzeigen:

srv-mysql> SHOW TABLES;
+-------------------+
| Tables_in_db_name |
+-------------------+
| tbl_name          |
+-------------------+
1 row in set (0.00 sec)

Struktur der MySQL-Datenbank-Tabelle anzeigen
Um die Struktur der Tabelle anzuzeigen, wählen Sie den Befehl „SHOW FIELDS“ wie im folgenden Beispiel:

srv-mysql> SHOW FIELDS FROM tbl_name;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(11)     | NO   |     | NULL    |       |
| spalte1 | varchar(255)     | YES  |     | NULL    |       |
| spalte2 | tinyint() | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

Spalte in eine bestehende Tabelle einfügen
Mittels „ALTER TABLE“ und „ADD COLUMN“ können Sie eine Spalte in eine bestehende MySQL-Tabelle einfügen:

srv-mysql> ALTER TABLE tbl_name ADD COLUMN (spalte3 varchar(10));
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

Datentyp einer Spalte ändern
Wir haben im obigen Beispiel die „spalte3“ mit dem Datentyp „varchar(10)“ angelegt. Dies können wir natürlich wieder ändern:

srv-mysql> ALTER TABLE tbl_name MODIFY spalte3 varchar(25);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

Spalte in einer MySQL-Tabelle löschen
Um eine Spalte in einer Tabelle zu löschen, wählen Sie den Befehl „DROP COLUMN“.

srv-mysql> ALTER TABLE tbl_name DROP COLUMN spalte3;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

GZip: Webseite beschleunigen (Page Speed) durch Kompression

Im Artikel „WordPress mit Cache beschleunigen: Plugin Quick Cache“ haben wir uns mit Caching-Möglichkeiten, im Artikel „Quick Cache – Page Speed nachgemessen“ mit den tatsächlichen Geschwindigkeiten beschäftigt. Es wurde gezeigt, dass dank eines Caches der sogenannte Page Speed, also die Geschwindigkeit, die zwischen Seitenaufruf und der tatsächlichen Anzeige im Browser vergeht, durchaus mit akzeptablen Mitteln gesteigert werden kann.
Heute möchten wir eine weitere Möglichkeit untersuchen, die den Page Speed noch weiter beschleunigen soll, die Kompression der Webseiten mittels GZip.

Wie funktioniert die Kompression mittels GZip?
Im Normalfall überträgt der Server eine Webseite und alle Elemente unkomprimiert. Der Browser empfängt die Daten und zeigt diese an. Allerdings können heute fast alle Browser auch mit komprimierten Dateien umgehen. Wenn der Server die Daten mittels GZip-Kompression an den Browser übermittelt, werden die Daten, die übertragen werden, durchschnittlich um 70 bis 80 Prozent (!) kleiner. Somit sparen wir Übertragungszeit ein. Gerade die Übertragungszeit ist oftmals der Flaschenhals beim Aufbau der Seite (Page Speed), denn nicht jeder Surfer kann auf eine nicht ausgelastete Breitbandanbindung zurückgreifen.
Erkauft wird sich die Erhöhung des Page-Speed jedoch durch einen Mehraufwand am Server und im Browser des Lesers. Denn der Server muss die Daten komprimieren, der Browser des Besuchers muss die Daten wieder entpacken. Mit Blick auf die Zeitersparnis sind dies jedoch akzeptable Nachteile.

Können alle Browser mit einer GZip-Kompression umgehen?
Nein. Im Netz kursieren Zahlen, dass über 90 Prozent der Browser GZip „verstehen“. Ich selbst habe viele Browser getestet. Keiner hatte Probleme mit der Kompression. Auch mobile Browser wie ein HTC Desire oder ein iPhone kommen mit den Kompression erstaunlich gut zurecht.

Wie kann ich die GZip-Kompression einschalten?
Für die Nutzung der GZip-Kompression gibt es mehrere Möglichkeiten

GZip Kompression mittels .htaccess
Die einfachste Möglichkeit, die GZip-Kompression zu nutzen, ist ein einfacher Eintrag in der .htaccess oder vhost-Datei. Diese Möglichkeit funktioniert bei allen Webseiten (auch WordPress), wenn auf dem Server das Apache-Modul „mod_deflate“ installiert bzw. aktiviert ist.

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/xml text/css text/plain
AddOutputFilterByType DEFLATE image/svg+xml application/xhtml+xml application/xml
AddOutputFilterByType DEFLATE application/rdf+xml application/rss+xml application/atom+xml
AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
AddOutputFilterByType DEFLATE application/x-font-ttf application/x-font-otf
AddOutputFilterByType DEFLATE font/truetype font/opentype
</IfModule>

Diesen Code einfach in die vhost oder .htaccess-Datei übernehmen. Der Code prüft automatisch, ob das Modul „mod_deflate“ vorhanden ist. Wenn ja, werden alle html, css, rss, Javascript und XML-Dateien GZip-komprimiert übertragen.
Ob der Code funktioniert bzw. ob die Daten komprimiert übertragen werden, prüft man einfach durch einen Aufruf über die Seite ismyblogworking.com. Die Seite gibt unter anderem Auskunft über die Komprimierung.
Wenn die Komprimierung nicht funktioniert, kann es sein, dass das Apache-Modul nicht installiert oder eher nicht aktiviert ist (siehe „Apache-Modul „mod_deflate“ aktivieren (auch unter Plesk)“

GZip-Kompression per PHP
Wenn GZip in der PHP.ini aktiviert ist, kann eine GZip-Kompression mittels PHP von jedem Skript aus wie folgt erfolgen:

<?php
ob_start("ob_gzhandler");
?>

Nicht zu verschweigen möchte ich an dieser Stelle, dass dies nur Sinn für einzelne Dateien macht. Denn in jeder PHP-Datei muss der Header so manipuliert werden. Wenn man also nur ein paar PHP-Dateien komprimiert senden möchte, ist dies ein gangbarer Weg. Ansonsten ist die .htaccess-Lösung vorzuziehen.

WordPress-Plugin
Auch unter WordPress ist GZip eine gute Lösung. Prinzipiell benötigt man kein Plugin. Der Code aus dem Abschnitt „GZip Kompression mittels .htaccess“ kann auch bei einer WordPress-Installation aktiviert werden. Die Lösung funktioniert auch bei Seiten  mit Cache.
Wenn (und nur wenn!) der WordPress-Blog auf einem Server oder Host läuft, auf dem das Apache-Modul „mod_deflate“ nicht aktiviert bzw. installiert wurde und man keine administrativen Zugriff hat, kann die GZip-Kompression mittels Plugin aktiviert werden. Auf diese Lösung sollte jedoch nur im zwingenden Ausnahmefall zurückgegriffen werden, da Plugin-intern ebenfalls auf die PHP-Kompression zurückgegriffen wird. Als WordPress-Plugin empfehle ich wpCompressor, dessen Dokumentation auch in deutscher Sprache erhältlich ist.

Apache-Modul „mod_deflate“ aktivieren (auch unter Plesk)
Um das Modul „mod_deflate“ nutzen zu können, muss das Modul installiert und aktiviert sein. Die Installation ist bei den meisten Servern bereits per default erfolgt. Die Aktivierung (so auch bei vielen meiner Ubuntu/Plesk-Konfigurationen) nicht.

Aktivierung von „mod_deflate“ über die Shell (Putty):
a2enmod deflate

Danach ist ein Restart des Apache notwendig mit:
/etc/init.d/apache2 restart

Plesk: Ich empfehle den Restart über die Oberfläche (da sich mein Plesk schon verabschiedet hat, als ich den Apachen über die Shell restartet habe)

Kalender-Daten von google nach hotmail migrieren

Die seit Tagen bestehenden Probleme mit dem Google-Kalender zwingen viele Nutzer von Android-Smartphones zum Umstieg nach Microsofts Hotmail. Es ist unverständlich, dass Google die seit über eine Woche bestehenden Probleme bei der Synchronisation des Web-Kalenders zu mobilen Android-Geräten nicht behoben hat. Und so mehren sich bei mir die Anfragen, nun doch dem Suchmaschinen-Riesen den Rücken zu kehren und die Kalenderdaten beim Erzrivalen Microsoft zu hosten.
Der Wunsch ist aufgrund der „verschwundenen Kalender-Einträge“ auf dem Smartphone verständlich, auch wenn sich jeder Android-Nutzer bewusst sein muss, dass man sich mit diesem Android, dem Smartphone-Betriebsystem, letztlich Google verschrieben hat. Doch auch wenn ein Googlemail-Konto Voraussetzung für die Nutzung von Android ist, wirklich nutzen muss man die Google-Cloud nicht. Die Nutzung der Microsoft-Cloud ist ebenfalls kostenfrei und schnell erledigt.

Umzug der Kalenderdaten von Google zu Hotmail
Natürlich macht der Umzug der Daten nur Sinn, wenn er schnell und sicher möglich ist. Kalenderdaten abzutippen macht weder Spaß, noch kann dies eine wirkliche gangbare Lösung sein.

So gehen Sie vor:

  1. Öffnen Sie Ihren Google-Kalender über einen beliebigen Browser. Klicken Sie im linken Bereich Ihres Google-Kalenders auf „Einstellungen“
  2. Im mittleren Bereich der Google Kalendereinstellungen gibt es neben dem Button „Neuen Kalender einrichten“ den Punkt „Kalender importieren“ und „Kalender exportieren“. Klicken Sie auf „Kalender exportieren“.
  3. Speichern Sie die Datei an einem beliebigen Ort. Öffnen Sie den Speicherort mit dem Windows-Explorer. Google speichert die Kalenderdaten als ICal-Datei. Dieses Format verstehen die meisten anderen Kalender wie auch Hotmail. Die Datei wird jedoch als Zip-Datei übertragen, welches man nicht direkt verwenden kann. Daher entpacken Sie die Zip-Datei mit einem beliebigen Unzipper wie beispielsweise 7-Zip.
  4. Öffnen Sie nun über Ihren Browser den Hotmail-Kalender.
  5. Nun importieren Sie die Daten in den Hotmail-Kalender. Klicken Sie hierfür den irreführenden Link „Abonnieren“ an.
  6. Wählen Sie nun den Radio-Button „Aus einer ICS-Datei importieren“ aus. Klicken Sie auf den Button „Durchsuchen“ und wählen Sie die entzipte (!) Version Ihrer Google-ICal-Sicherung aus. Achten Sie auf das DropDown-Feld „Kalender auswählen“, so dass der Import in den richtigen Kalender stattfindet. Um Duplikate beim Import zu vermeiden, können Sie zwischen zwei Optionen wählen. Nachdem Sie alle Eingaben gemacht haben, klicken Sie auf den Button „Kalender importieren“.
  7. Sie sollten nun eine Meldung erhalten, dass der Kalender-Import erfolgreich abgeschlossen wurde. Es macht eventuell Sinn, sich im Kalender einige Termine anzuschauen und eventuelle Duplikate manuell zu löschen (sofern vorhanden).

Kalender-Einträge von Hotmail zu Google-Mail importieren
Der oben beschrieben Weg von Google-Mail zu Hotmail ist natürlich auch umgekehrt, also von Hotmail zu Google-Mail möglich. Hierzu müssen Sie einfach Ihre Kalenderdaten von Hotmail exportieren (Speichern) und bei Google-Mail importieren.

Kalender-Einträge speichern oder sichern (Datensicherung)
Die oben beschriebenen Punkte 1-3 eignen sich auch als Weg zur Datensicherung der Kalendereinträge bei Google-Mail. Auch wenn bisher noch keine Kalendereinträge bei Google verschwunden sind, ist es nie verkehrt, ab und zu eine Datensicherung seiner Daten vorzunehmen. So genügt es meistens, die Daten aus Googlemail über den oben beschriebenen Weg auf dem lokalen PC zu sichern.

C# Befehlszeilen-Argumente (Command Parameter) auslesen

Befehlszeilenargumente sind Parameter, die einer Anwendung beim Start mitgegeben werden. Unter Windows können jedem Programm Parameter beim Start mitgegeben werden. Ob die Anwendung diese Parameter beachtet, liegt am Programm selbst. So liegt es letztlich am Programmierer, wie er mit den Argumenten umgeht.

So können Sie beispielsweise den Standard-Texteditor Notepad unter Windows mit „notepad.exe“ aufrufen. Rufen Sie Notepad mit „notepad.exe c:datei.txt“ auf, versucht Notepad mit dem Start die Datei „C:datei.txt“ zu öffnen.

Dieses Verhalten von Windows können Sie vielfältig auch für eigene Anwendungen nutzen. Wenn Sie Dateien zur Automatisierung schreiben, die je nach Aufruf nur Teilbereiche erledigen sollen oder bestimmte (standardisierte) Benutzereingaben benötigen, können Sie diese über die „CommandLineArgs“ abfragen. Nehmen wir einmal an, ein Programm soll jeden Tag einen Teilbereich von Daten abarbeiten, so können Sie natürlich im Programm den Wochentag abfragen und hardcodiert den Teilbereich festlegen. Wenn Sie jedoch den Bereich nachträglich ändern möchten, müssen Sie Ihr Programm wieder anfassen, ändern, erstellen und veröffentlichen. Eine bessere Lösung ist, den Bereich über die CommandLine beim Start zu definieren. So kann beispielsweise

C:meine-anwendung.exe –start_id:1 –end_id:500000

Der Aufruf für den ersten Tag (beispielsweise montags) und

C:meine-anwendung.exe –start_id:5000000 –end_id:1000000

der Aufruf für den zweiten Tag (beispielweise dienstags) sein. So sind Sie sehr flexibel, was die Anpassung angeht.
Je nach Anwendung ist es natürlich auch möglich, die Werte in einer ini-Datei oder aus der Registry auszulesen. Ini-Dateien waren lange Zeit die einzige Möglichkeit, mehrere Parameter dauerhaft zu speichern. Dank der Registry oder auch Datenbanken konnten diese Wege beschritten werden. Ini-Dateien waren dann plötzlich sogar „verpönt“. Ich persönlich bin nach wie vor ein Fan von ini-Dateien, wenn es darum geht, einige wenige Parameter einem Programm mitzugeben bzw. auch aus der Anwendung heraus zu speichern (letzteres geht mit den CommandLineArgs nicht!). Im Gegensatz zu Registry-Einträgen oder einer Datenbank kann die Anwendung mitsamt der ini-Datei problemlos auf einen anderen Rechner übertragen werden.

Startparameter unter C# auslesen (Command Line)
Unter C# stehen die Aufrufparameter in den CommandLineArgs zur Verfügung:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication1 
{ 
class Program 
{ 
static void Main(string[] args) 
{ 


//Befehlszeilenargumente auslesen 
string[] CommandLineArgs = Environment.GetCommandLineArgs(); 

//CommandLineArgs[0]: Immer der Dateipfad 
if (CommandLineArgs.Length > 1) 
{ 
Console.WriteLine(CommandLineArgs[1].ToString()); 
} 


//Warte 
Console.ReadLine(); 

} 
}

Dieses Beispiel zeigt Ihnen der Zugriff auf den ersten Command-Line Parameter. Sie können das Programm auch im Debug-Modus testen, wenn Sie „Befehlszeilen-Argumente“ innerhalb Visual Studio eingeben. Klicken Sie hierfür auf „Projekt“, „PROGRAMMNAME-Eigenschaften“. Dann den Reiter „Debuggen“ auswählen. Dort können Sie unter „Befehlszeilenargumente“ die Übergabeparameter eingeben. Diese stehen Ihnen dann auch im Debug-Modus zur Verfügung.

Die Parameter stehen Ihnen bei einer Windows-Forms und bei einer Konsolen.Anwendung als Array vom Typ String zur Verfügung. Zu beachten ist, dass der erste Parameter „[0]“  immer der Pfad und Name des eigenen Programmes ist.

PHP-Funktion mysql_real_escape_string in C# umsetzen

Da C# leider die wichtige PHP-Funktion mysql_real_escape_string nicht anbietet, sind wir auf der Suche nach einer Lösung in C#. Im Artikel „C# Hochkomma maskieren für SQL-Statements (SQL-Escape)“ haben wir bereits einige Möglichkeiten untersucht, doch so richtig begeistert sind wir von keiner Lösung. Unser Ziel ist nach wie vor eine direkte Umsetzung von mysql_real_escape_string nach C#, wobei es unerheblich ist, ob der Ziel-SQL Server MySQL oder M$-SQL spricht. Möglich ist dies durch eine Regular-Expression.

So können wir mittels einem Regex.Replace einfache und doppelte Hochkommas, den Backslash sowie die Steuerzeichen r, n, x00, x1a einfach und sicher maskieren:

Regex.Replace(sValue, @"[rnx00x1a\'""]", @"$0");

Die unten beschriebene Funktion SQLEscape liefert den SQL-konformen und maskierten Wert zurück, so dass es beim Absetzen des SQL-Statements zu keinen Fehlern mehr kommen sollte.
Wichtig für die Nutzung ist die Einbindung der Regex-Klasse per „using System.Text.RegularExpressions;”

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            string sBuffer = "";

            sBuffer = "SELECT bla FROM table WHERE name ='O'Henry'";
            Console.WriteLine(SQLEscape(sBuffer));

            sBuffer = "SELECT bla FROM table WHERE name ='O''Henry'";
            Console.WriteLine(SQLEscape(sBuffer));

            //Warte
            Console.ReadLine();

        }

        public static string SQLEscape(string sValue)
        {
            // SQL Encoding: r, n, x00, x1a, Backslash, einfache und doppelte Hochkommas
            if (sValue == null) return null;
            else return Regex.Replace(sValue, @"[rnx00x1a\'""]", @"$0");
        }
    }
}

C# mit MySQL: MySQL Query Escape
Die folgende Möglichkeit ist noch einfacher, meines Erachtens noch sicherer und funktioniert nur mit MySQL. Microsoft-SQL-Nutzer bleiben bei dieser Lösung leider außen vor.
Wenn man unter .NET eine MySQL-Datenbank ansprechen möchte, benötigt man einen enstprechenden MySQL-Connector. So ist es möglich, unter .NET sogenannte „Query-Parameter“ zu nutzen. Der folgende Code ist für C#-Benutzer sicherlich selbsterklärend. Es sei hinzugefügt, dass durch die Nutzung der Query Parameters keine Maskierung von Hochkommas mehr notwendig ist.

// Problematische Benutzer-Eingabe: Hochkomma
string sBenutzername = "Meine Usereingabe: O'Henry";

// eine oder mehrere Parameter hinzufügen
sql.command.Parameters.AddWithValue("?Username", sBenutzername);

sql.command.CommandText= "SELECT id, pw FROM ‘users’ WHERE ‘username’=?UserName Limit 1";

Über diesen Weg können auch Stored Procedures angesprochen werden. Eine gute Zusammenfassung der Parameter gibt es auf der devart.com-Seite.

C# Hochkomma maskieren für SQL-Statements (SQL-Escape)

Ein häufiges Problem im Umgang mit Strings oder SQL-Statements sind Hochkommas. Diese unscheinbaren Zeichen (’ oder „) bereiten immer wieder Probleme. Manchmal auch an Stellen, die man die erwartet hätte.
Gerade beim Zugriff auf SQL-Datenbanken kann sich ein solches Problem zur Laufzeit einschleichen. Dann nämlich, wenn in einem SQL-Statement beispielsweise Benutzer-Eingaben verarbeitet werden. Aber nicht nur der Benutzer, der in ein Textfeld Hochkommas platziert, auch in der Datenverarbeitung stößt man auf dieses Problem. Spätestens, wenn der erste Datensatz mit dem Namen „O’Henry“ auftaucht. Und in jeder Stadt gibt es ein Irish-Pub-Besitzer, der so heißt …

Warum Hochkommas ein Problem sind
In einer Stringzuweisung bereitet das folgende Beispiel kein Problem:

string sHochkommaTest = „Mein Name ist O’Henry“;

Doch dieses Beispiel wird sofort zu Problemen führen:

string sHochkommaTest = „Bitte drücken Sie die „OK“-Taste“;

Was hier hilft ist eine Maskierung des Hochkommas. In C# behilft man sich dem Backslash („“). So ist das folgende Beispiel valider Code:

string sHochkommaTest = „Bitte drücken Sie die „OK“-Taste“;

Hochkommas in jeder Ausprägung werden dann zum Problem, wenn das Hochkomma selbst in einem Statement eine bestimmte Funktion erfüllen. So das doppelte Hochkomma („) bei einer Stringzuweisung, oder das einfache Hochkomma (‚) in einem SQL-Statement.

Hochkomma in einem SQL-Statement maskieren
Hier kann es sehr schnell gefährlich werden. Nehmen wir an, sie nehmen eine Benutzereingabe entgegen wie beispielsweise den Benutzername des Users, den sie in einer Datenbank gespeichert haben und nun prüfen möchten, ob der Benutzer dem System bekannt ist. So könnte das folgende Beispiel aussehen:

SELECT id, name, vorname, pw FROM benutzer WHERE name=’$benutzereingabe’;

In der Variable „$benutzereingabe“ ist der eingegeben Benutzer gespeichert. Und nun kommt unser Herr O’Henry, gibt seinen Namen ein und erzeugt einen Fehler (was das kleinste Problem ist). Er macht nämlich aus unserem SELECT folgendes:

SELECT id, name, vorname, pw FROM benutzer WHERE name=’O’Henry’;

Jeder SQL-Parser wird hier einen Fehler melden. Damit nicht genüg: Solche Fehler sind ein Einfallstor für Hacker in eine Anwendung. Wenn Benutzereingaben gegen eine Datenbank nicht von der Anwendung schon geprüft und maskiert werden, kann dies eine böse Sicherheitslücke ergeben.

Also muss unsere Benutzereingabe geprüft und gegebenenfalls maskiert werden. Man wünscht sich in C# eine Funktion wie in PHP die Funktion mysql_real_escape_string, die dafür sorgt, dass alle Sonderzeigen in der übergebenen Variable auf Sonderzeigen geprüft und ordentlich maskiert werden. Doch meines Wissens gibt es in C# so etwas (einfaches und sicheres) nicht. Weder String-Literale noch LINQ bringen wirkliche Verbesserung.
Während das String-Literal („@“) doppelte Hochkommas filtert (und einige nette weitere Erleichterungen bereithält), löst er jedoch nicht das Problem des einfachen Hochkommas:

string x = @"Joe said ""Hello"" to me";   // Joe said "Hello" to me
string y = @"Joe said ''Hello'' to me";
Console.WriteLine(x);
Console.WriteLine(y);
Console.ReadLine();

So sind beide Zeilen gültiger C#-Code, doch zwei hintereinander folgende einzelne Hochkommas bleiben erhalten. Zumal diese Idee ein „WHERE name =’O’Henry’“ auch nicht lösen würde.

Maskierung für SQL-Statements
Eine ganz einfache Hilfe ist die untenstehende Funktion, über die jede Variable, die in ein SQL-Statement eingebaut werden soll, geschickt werden muss. Diese Funktion macht nichts anderes, als ein einfaches Hochkomma in zwei Hochkommas zu maskieren. Der SQL-Parser wird dieses Ergebnis ohne Fehler verarbeiten.

private static string maskiere(string sValue)
{
    return sValue.Replace("'", "''");
}

Problem der Maskierung
Diese Lösung wird vielleicht folgendes Problem erzeugen: Wenn Sie ein SQL-Ergebnis haben, das Sie bereits durch diese Funktion geschickt haben, das Ergebnis also zwei Hochkommas hintereinander hat, und Sie speichern diesen Code erneut (mit dieser Funktion), werden aus zwei Hochkommas hintereinander (“) vier Hochkommas (““). Und dies wird Ihnen der SQL-Parser sehr übelnehmen.

Die SQL-Lösung zur Maskierung eines SQL-Statements
Wir haben nun viele Möglichkeiten beleuchtet, haben aber noch nicht die wirklich allumfassende perfekte Lösung für C# gefunden. Aber keine Sorge, es gibt sie. Einfach im Artikel „PHP-Funktion mysql_real_escape_string in C# umsetzen“ weiterlesen …

C# String-Literale (Stringliteral)

Eine Möglichkeit der Problematik von zwei doppelten Hochkommas hintereinander („“) zu begegnen oder um den Backslash bei Pfadangaben zu ermöglichen, ist der String-Literal. Sicherlich ist Ihnen in fremden Programmen schon mal aufgefallen, dass vor manchen String-Zuweisungen das AT („@“) steht.

So erzeugt folgende C#-Zeile einen Fehler:
string sLiteral = „Bitte drücken Sie die „OK“-Taste“;

Sie können dieses Problem so umgehen:
string sLiteral = „Bitte drücken Sie die „OK“-Taste“;

Oder noch besser mit dem String-Literal („@“):
string sLiteral = @“Bitte drücken Sie die „“OK““-Taste“;
Durch das AT (@)-Zeichen weisen Sie den C#-Interpreter an, er möge bitte zwei Hochkommas hintereinander als eines betrachten. Der String wird so valide.
So werden aber auch Steuerzeichen durch ein Literal nicht umgesetzt, was meistens wünschenswert ist. Nehmen wir als Beispiel dem Tabulator und den Klassiker „Hello world“:

string Literal1 ="Hello t world";               // Hello     world
string Literal2 = @"Hello t world";               // Hello t world

Besonders beliebt und sinnvoll die der String-Literal in Pfadangaben.
So wird C# die folgende Zeile mit „Nicht erkannte Escapesequenz“ anmäckern:

string sMeinPfad = „c:mein-ordnermeine-datei.txt“;

Mit zwei Backslash wird der String valide:
string sMeinPfad = „c:\mein-ordner\meine-datei.txt“;

Als Literal schreiben Sie folgendes:
string sMeinPfad = @“c:mein-ordnermeine-datei.txt“;

Um Server oder Dateien via UNC-Pfad anzusprechen, benötigt man den doppelten Backslash (\). So kann ich aus zwei Slashs vier schreiben, um mein Ergebnis zu erreichen:

string Con = „\\server\freigabe\file.txt“;   // \serverfreigabefile.txt

Oder

string Con = @“\serverfreigabefile.txt“;      // \serverfreigabefile.txt

Einen wirklichen Mehrwert bieten das C#-String-Literal allerdings durch seine Multi-Line-Fähigkeit. Wenn wir gezwungen sind, einen String über mehrere Zeilen zu schreiben, werden die meisten Programmierer dies in etwa so erledigen:

string sLangerString = "Dies ist der Beispielcode für einen langen, " +
"sehr langen String. Dadurch, dass ich als herrschender Programmierer " +
"den String über mehrere Zeilen ziehen möchte, muss ich die einzelnen " +
"Teile mit einem Plus verknüpfen";

Stattdessen kann man unter Zuhilfenahme des AT (@) wie folgt schreiben:

string sLangerString = @"Dies ist der Beispielcode für einen langen,
sehr langen String. Nun verknüpfen wir den Code nicht mit einem
Plus, sondern nutzen den Vorteil eines String-Literals der es
ermöglicht, den Zeilenumbruch zu ignorieren";

Auch bei SQL-Statements, die ja bekanntlich meist aus längeren Zeichenfolgen bestehen, leisten die String-Literale gute dienste. Wie man zusätzlich noch Hochkommas maskiert, beschreibe ich im Artikel „C# Hochkomma maskieren für SQL-Statements (SQL-Escape)„.