Verwenden von htaccess-Dateien für hübsche URLs
() translation by (you can also view the original English article)
Während wir unsere Überprüfung der htaccess-Dateien fortsetzen, untersuchen wir heute, wie man mit mod_rewrite hübsche URLs erstellt.
Vorteile von formatierten URLs
Während einige behaupten, dass hübsche URLs bei Suchmaschinen-Rankings helfen, ist die Debatte hier heftig, wir können uns alle darauf einigen, dass hübsche URLs unseren Nutzern die Arbeit erleichtern und jeder Web-Anwendung ein gewisses Maß an Professionalität und Perfektion verleihen. Ich könnte alle theoretischen Gründe dafür durchgehen, aber ich mag Beispiele aus der Praxis besser. Wie es oder hassen es, müssen wir alle zugeben, dass Twitter ist eine sehr beliebte Web-Anwendung und ein Teil der Grund dafür ist sicherlich, wie es URLs formatiert. Ich kann jedem erzählen, dass mein Twitter-Benutzername noahhendrix ist, und sie wissen, dass mein Profil auf twitter.com/noahhendrix leicht zu finden ist. Dieses scheinbar einfache Konzept hat große Auswirkungen auf die Popularität Ihrer Anwendung.



Um die Dinge ins rechte Licht zu rücken, können wir uns eine andere beliebte Social-Networking-Website, Facebook, anschauen. Seit der Einführung der Website im Jahr 2004 ist das Profilsystem gewachsen und weiterentwickelt worden, um es besser an die Benutzer anzupassen, aber ein eklatantes Loch war die URL zu einem Profil. Seit ich mich bei Facebook registriert habe, war mein Profil unter der URL http://www.facebook.com/profile.php?id=1304880680. Das ist ziemlich voll, und erst kürzlich hat Facebook das erkannt und Facebook-Vanity-URLs eingeführt. Jetzt kann ich mein Facebook-Profil teilen, indem ich Leuten sage, dass mein Facebook-Benutzername "noahhendrix" ist, von dem sie wissen, dass sie bei facebook.com/noahhendrix gefunden werden können. Während die Chancen stehen, dass wir keine Anwendung wie Facebook so beliebt haben, können wir noch ein paar Seiten aus ihrem Buch ausleihen.



Schneller Überblick
Bevor wir uns dem Code zuwenden, werden wir uns in der heutigen Einführung einen kurzen Überblick über zwei leicht unterschiedliche Methoden zum Erstellen schöner URLs mit HTACCESS verschaffen. Der Unterschied zwischen den Methoden besteht darin, ob Apache oder PHP die Schwerarbeit machen, um die URL für das Parsing auseinander zu brechen. Ich möchte darauf hinweisen, dass mod_rewrite Tutorials fast so alt sind wie das Internet selbst und das ist nicht das erste. Am Ende werde ich eine der Methoden verwenden, um eine einfache Anwendung zu erstellen, um zu zeigen, wie diese Lösungen in einer Real-Live-Website aussehen würden (nicht zu 100% Produktionsqualität). Der Service, den wir erstellen, ist ein URL-Shortener, der die Funktionalität solcher Sites wie bit.ly, TinyURL oder su.pr spiegeln kann. Also ohne mehr Flaum lassen Sie uns den Code anschauen.
Apache verwenden
Zuerst können wir unseren gesamten Code in Apache .htaccess-Dateien ablegen. Das könnte etwa so aussehen:
1 |
|
2 |
Options +FollowSymLinks |
3 |
RewriteEngine On |
4 |
|
5 |
RewriteCond %{SCRIPT_FILENAME} !-d |
6 |
RewriteCond %{SCRIPT_FILENAME} !-f |
7 |
|
8 |
RewriteRule ^users/(\d+)*$ ./profile.php?id=$1 |
9 |
RewriteRule ^threads/(\d+)*$ ./thread.php?id=$1 |
10 |
|
11 |
RewriteRule ^search/(.*)$ ./search.php?query=$1 |
Fangen wir oben an und arbeiten uns nach unten, um besser zu verstehen, was hier vor sich geht. In der ersten Zeile wird die Umgebung so eingerichtet, dass sie symbolischen Verknüpfungen mit der Option-Direktive folgt. Dies kann notwendig sein oder auch nicht, aber einige Webhosts benutzen Symlinks (ähnlich dem Alias in MacOSX oder Shortcuts ist Windows) für häufige HTTP-Request-Fehler und das sind normalerweise symbolische Dateien, oder zumindest verstehe ich die Argumentation. Als nächstes sagen wir Apache, dass wir die Rewrite Engine verwenden werden. Die nächsten zwei Zeilen sind sehr, sehr wichtig, es beschränkt das Umschreiben von URLs nur auf Pfade, die eigentlich nicht existieren. Dies verhindert, dass die unten stehenden Regeln zum Beispiel mit example.com/images/logo.png übereinstimmen. Der erste verhindert vorhandene Verzeichnisse mit dem !-d-Flag und der zweite mit! -f ignoriert vorhandene Dateien.
Die nächsten drei Zeilen sind die eigentlichen URL-Rewriting-Befehle. Jede Zeile erstellt eine Regel, die versucht, ein Muster für reguläre Ausdrücke mit der eingehenden URL abzugleichen. Reguläre Ausdrücke, zumindest für mich, sind harte Regeln, an die man sich erinnern muss, aber ich finde es immer hilfreich, dieses Tutorial von Nettuts eigenem Jeffery Way und dem von ihm empfohlenen Werkzeug zu verwenden. Ich fand es einfach, Beispiel-URLs einzugeben, die wir abgleichen möchten, und versuchen dann, das Muster zu hacken.



Das erste Argument ist das Muster zwischen dem Caret und dem Dollarzeichen. Wir sagen Apache, dass wir URLs wollen, die nach dem Benutzerverzeichnis fragen (ein künstliches Verzeichnis, muss nicht wirklich existieren), gefolgt von einem / und einer beliebigen Länge von Zahlen. Die Klammern erzeugen eine Erfassungsgruppe, die Sie beliebig oft verwenden können. Sie dienen als Variablen, die wir dann in unsere Neuschreibung übernehmen können. Das Sternchen bedeutet, dass der Benutzer eingeben kann, was immer sie wollen, und es hat keinen Einfluss auf das Neuschreiben. Dies ist in erster Linie für einen abschließenden Schrägstrich gedacht. example.com/users/123 ist dasselbe wie example.com/users/123/ wie Benutzer erwarten würden.
Das zweite Argument ist der Pfad, den wir eigentlich nennen möchten, im Gegensatz zu dem ersten muss eine echte Datei sein. Wir weisen Apache an, im aktuellen Verzeichnis nach einer Datei namens profile.php zu suchen und den Parameter id=$1 mitzusenden. Erinnerst du dich an die Fanggruppe früher? Dort erhalten wir die Variable $1, Capture-Gruppen beginnen bei eins. Dies erstellt eine URL auf dem Server wie example.com/profile.php?id=123.
Diese Methode eignet sich hervorragend für Legacy-Webanwendungen mit vorhandenen URL-Strukturen, die verhindern, dass das Back-End einfach neu geschrieben wird, um ein neues URL-Schema zu verstehen, da die URL für den Server gleich aussieht, für den Benutzer jedoch viel schöner aussieht.
Mit PHP
Diese nächste Methode ist ideal für diejenigen, die nicht zu viel Logik an Apache verteilen und sich in PHP (oder ähnlichen Skriptsprachen) wohler fühlen möchten. Das Konzept besteht darin, jede URL, die der Server empfängt, zu erfassen und auf eine PHP-Controller-Seite zu übertragen. Dies bringt den zusätzlichen Vorteil der Kontrolle, aber gleichzeitig eine größere Komplexität mit sich. Ihre HTACCESS-Datei könnte etwa so aussehen:
1 |
|
2 |
Options +FollowSymLinks |
3 |
RewriteEngine On |
4 |
|
5 |
RewriteCond %{SCRIPT_FILENAME} !-d |
6 |
RewriteCond %{SCRIPT_FILENAME} !-f |
7 |
|
8 |
RewriteRule ^.*$ ./index.php |
Alles ist wie oben, außer der letzten Zeile, also werden wir darauf zu springen. Anstatt eine Capture-Gruppe zu erstellen, teilen wir Apache einfach mit, jede URL zu erfassen und sie an index.php umzuleiten. Das bedeutet, dass wir unsere gesamte URL-Verarbeitung in PHP durchführen können, ohne sich zu sehr auf stringente URL-Pfade in HTACCESS zu verlassen. Das können wir oben in unserer index.php-Datei tun, um die URL zu analysieren:
1 |
|
2 |
<?php
|
3 |
#remove the directory path we don't want
|
4 |
$request = str_replace("/envato/pretty/php/", "", $_SERVER['REQUEST_URI']); |
5 |
|
6 |
#split the path by '/'
|
7 |
$params = split("/", $request); |
8 |
?>
|
Die erste Zeile ist nicht notwendig, es sei denn, Ihre Anwendung lebt nicht im Stammverzeichnis, wie meine Demos. Ich entferne den Nonsense-Teil der URL, über den ich mich nicht kümmern soll. $ _SERVER ['REQUEST_URI'] ist eine globale Servervariable, die PHP bereitstellt und die Anforderungs-URL speichert. Sie sieht im Allgemeinen wie folgt aus:
1 |
|
2 |
/envato/pretty/php/users/query |
Wie Sie sehen können, ist es im Grunde alles nach dem Domain-Namen. Als nächstes teilen wir den verbleibenden Teil des virtuellen Pfades auf und teilen ihn durch das Zeichen / auf, was uns erlaubt, einzelne Variablen zu erfassen. In meinem Beispiel habe ich einfach das $params-Array im Körper ausgedruckt, natürlich möchten Sie etwas Nützlicheres tun.



Eine Sache, die Sie tun können, ist, das erste Element des Arrays $params zu nehmen und eine Datei mit dem gleichen Namen einzufügen, und innerhalb der Datei können Sie das zweite Element im Array verwenden, um Code auszuführen. Das könnte etwa so aussehen:
1 |
|
2 |
<?php
|
3 |
#keeps users from requesting any file they want
|
4 |
$safe_pages = array("users", "search", "thread"); |
5 |
|
6 |
if(in_array($params[0], $safe_pages)) { |
7 |
include($params[0].".php"); |
8 |
} else { |
9 |
include("404.php"); |
10 |
}
|
11 |
?>
|
ACHTUNG: Der erste Teil dieses Codes ist unglaublich wichtig! Sie müssen unbedingt einschränken, welche Seiten ein Benutzer erhalten kann, so dass er nicht die Möglichkeit hat, eine beliebige Seite auszudrucken, indem er auf Dateinamen wie eine Datenbankkonfigurationsdatei rät.
Jetzt, wo wir die Seifenkiste aus dem Weg haben, gehen wir weiter. Als nächstes prüfen wir, ob die angeforderte Datei im $safe_pages-Array enthalten ist, und wenn dies der Fall ist, schließen wir eine Seite 404 nicht gefunden ein. Auf der mitgelieferten Seite sehen Sie, dass Sie Zugriff auf das Array $params haben und Sie können alle Daten, die in Ihrer Anwendung benötigt werden, abrufen.
Dies ist ideal für diejenigen, die ein wenig mehr Kontrolle und Flexibilität wollen. Es erfordert offensichtlich viel zusätzlichen Code, also wahrscheinlich besser für neue Projekte, die nicht viel Code benötigen, um auf die neuen URL-Formate angepasst zu werden.
Ein einfacher URL-Kürzler
Dieser letzte Teil des Tutorials wird uns erlauben, den Code zu verwenden, den wir oben besprochen haben, und ist mehr oder weniger ein "reales" Beispiel. Wir werden einen Service namens shrtr erstellen, den ich so gemacht habe, dass alle anderen Produkte mit diesem Namen nicht mit dem Code, den ich unten posten, verbunden sind. Hinweis: Ich weiß, dass dies bei weitem kein originelles Konzept ist und nur zur Demonstration von mod_rewrite gedacht ist. Sehen wir uns zuerst die Datenbank an:



Wie Sie sehen können, ist dies sehr einfach, wir haben nur 4 Spalten:
- ID: eindeutiger Bezeichner zum Verweis auf bestimmte Zeilen
- short: Eine eindeutige Zeichenkette, die an das Ende unserer URL angehängt wird, um zu bestimmen, wohin umgeleitet werden soll
- URL: Die URL, zu der die kurze URL verweist
- created_at: ein einfacher Zeitstempel, damit wir wissen, wann diese URL erstellt wurde
Die Grundlagen
Als nächstes gehen wir auf die sechs Dateien ein, die wir für diese Anwendung erstellen müssen:



- .htaccess: Leitet alle kurzen URLs in die Datei serve.php um
- create.php: validiert URL, erstellt Shortcode, speichert in DB
- css/style.css: enthält einige grundlegende Styling-Informationen
- db_config.php: Speichern Sie Variablen für Datenbankverbindungen
- index.php: Das Gesicht unserer Bewerbung mit Formular zur Eingabe der URL
- serve.php: Sucht eine kurze URL und leitet sie zur tatsächlichen URL um
Das ist alles, was wir für unser grundlegendes Beispiel brauchen. Ich werde index.php oder css/style.css nicht sehr detailliert behandeln, da sie kein PHP haben und statische Dateien sind.
1 |
|
2 |
# index.php |
3 |
---- |
4 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
5 |
<html>
|
6 |
<head>
|
7 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
8 |
<title>Makes URLs Shrtr</title> |
9 |
<link type="text/css" rel="stylesheet" href="./css/style.css" /> |
10 |
</head>
|
11 |
<body>
|
12 |
<div id="pagewrap"> |
13 |
<h1>shrt<span class="r">r</span>.me</h1> |
14 |
|
15 |
<div class="body"> |
16 |
<form action="./create.php" method="post"> |
17 |
|
18 |
<span class="instructions">Type your URL here</span> |
19 |
<input name="url" type="text" /> |
20 |
<input type="submit" value="shrtr" /> |
21 |
|
22 |
</form>
|
23 |
</div>
|
24 |
|
25 |
</div>
|
26 |
</body>
|
27 |
</html>
|
Das einzige wirklich Interessante hier ist, dass wir das Formular mit einem Feld namens URL an create.php senden.
1 |
|
2 |
# css/style.css |
3 |
----
|
4 |
/* reset */
|
5 |
* { |
6 |
font-family: Helvetica, sans-serif; |
7 |
margin: 0; |
8 |
padding: 0; |
9 |
}
|
10 |
|
11 |
/* site */
|
12 |
html, body { background-color: #008AB8; } |
13 |
a { color: darkblue; text-decoration: none;} |
14 |
|
15 |
#pagewrap { |
16 |
margin: 0 auto; |
17 |
width: 405px; |
18 |
}
|
19 |
|
20 |
h1 { |
21 |
color: white; |
22 |
margin: 0; |
23 |
text-align: center; |
24 |
font-size: 100px; |
25 |
}
|
26 |
h1 .r { color: darkblue; } |
27 |
|
28 |
.body { |
29 |
-moz-border-radius: 10px; |
30 |
-webkit-border-radius: 10px; |
31 |
background-color: white; |
32 |
text-align: center; |
33 |
padding: 50px; |
34 |
height: 80px; |
35 |
position: relative; |
36 |
}
|
37 |
|
38 |
.body .instructions { |
39 |
display: block; |
40 |
margin-bottom: 10px; |
41 |
}
|
42 |
.body .back { |
43 |
right: 15px; |
44 |
top: 10px; |
45 |
position: absolute; |
46 |
}
|
47 |
|
48 |
.body input[type=text] { |
49 |
display: block; |
50 |
font-size: 20px; |
51 |
margin-bottom: 5px; |
52 |
text-align: center; |
53 |
padding: 5px; |
54 |
height: 20px; |
55 |
width: 300px; |
56 |
}
|
Das ist alles sehr allgemein, macht aber unsere Anwendung ein wenig vorzeigbar.



Die letzte grundlegende Datei, die wir betrachten müssen, ist unsere db_config.php, die ich erstellt habe, um einige der Datenbankverbindungsinformationen zu abstrahieren.
1 |
|
2 |
# db_config.php |
3 |
---- |
4 |
<?php
|
5 |
|
6 |
$database = "DATABASE_NAME"; |
7 |
$username = "USERNAME"; |
8 |
$password = "PASSWORD"; |
9 |
$host = "localhost"; |
10 |
|
11 |
?>
|
Sie müssen die Werte mit dem ersetzen, was in Ihrer Datenbank funktioniert, und der Host ist wahrscheinlich localhost, aber Sie müssen sich bei Ihrem Hosting-Provider erkundigen, ob das möglich ist. Hier ist der SQL-Dump der Tabelle url_redirects, der alle Informationen enthält, die wir oben gezeigt haben:
1 |
|
2 |
--
|
3 |
-- Table structure for table `url_redirects` |
4 |
--
|
5 |
|
6 |
CREATE TABLE IF NOT EXISTS `url_redirects` ( |
7 |
`id` int(11) NOT NULL auto_increment, |
8 |
`short` varchar(10) NOT NULL, |
9 |
`url` varchar(255) NOT NULL, |
10 |
`created_at` timestamp NOT NULL default CURRENT_TIMESTAMP, |
11 |
PRIMARY KEY (`id`), |
12 |
KEY `short` (`short`) |
13 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
Erstellen der kurzen URL
Als nächstes sehen wir uns den Code an, der zum Erstellen unserer kurzen URL erforderlich ist.
1 |
|
2 |
# create.php |
3 |
---- |
4 |
<?php
|
5 |
require("./db_config.php"); |
6 |
|
7 |
$url = $_REQUEST['url']; |
8 |
|
9 |
if(!preg_match("/^[a-zA-Z]+[:\/\/]+[A-Za-z0-9\-_]+\\.+[A-Za-z0-9\.\/%&=\?\-_]+$/i", $url)) { |
10 |
$html = "Error: invalid URL"; |
11 |
} else { |
12 |
|
13 |
$db = mysql_connect($host, $username, $password); |
14 |
|
15 |
$short = substr(md5(time().$url), 0, 5); |
16 |
|
17 |
if(mysql_query("INSERT INTO `".$database."`.`url_redirects` (`short`, `url`) VALUES ('".$short."', '".$url."');", $db)) { |
18 |
$html = "Your short URL is<br />shrtr.me/".$short; |
19 |
} else { |
20 |
$html = "Error: cannot find database"; |
21 |
}
|
22 |
|
23 |
mysql_close($db); |
24 |
}
|
25 |
?>
|
26 |
|
27 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
28 |
<html>
|
29 |
<head>
|
30 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
31 |
<title>Makes URLs Shrtr</title> |
32 |
<link type="text/css" rel="stylesheet" href="./css/style.css" /> |
33 |
</head>
|
34 |
<body>
|
35 |
<div id="pagewrap"> |
36 |
<h1>shrt<span class="r">r</span>.me</h1> |
37 |
|
38 |
<div class="body"> |
39 |
<?= $html ?> |
40 |
<br /><br /> |
41 |
<span class="back"><a href="./">X</a></span> |
42 |
</div>
|
43 |
|
44 |
</div>
|
45 |
</body>
|
46 |
</html>
|
Jetzt werden wir ein bisschen komplexer! Zuerst müssen wir die Datenbankverbindungsvariablen einschließen, die wir zuvor erstellt haben, und dann speichern wir den URL-Parameter, der uns von dem Erstellungsformular in einer Variablen namens $url gesendet wurde. Als nächstes führen wir einige reguläre Ausdrücke durch, um zu prüfen, ob sie tatsächlich eine URL gesendet haben, wenn wir nicht einen Fehler speichern. Wenn der Benutzer eine gültige URL eingegeben hat, erstellen wir eine Verbindung zur Datenbank mithilfe der Verbindungsvariablen, die wir am Anfang der Seite einfügen. Als nächstes erzeugen wir eine zufällige 5-stellige Zeichenkette, die mit der Funktion substr in der Datenbank gespeichert wird. Die Zeichenfolge, die wir aufteilen, ist der md5-Hash der aktuellen time() und $url zusammen verkettet. Dann fügen wir diesen Wert zusammen mit der tatsächlichen URL in die Tabelle url_redirects ein und speichern eine Zeichenfolge, die dem Benutzer angezeigt wird. Wenn die Daten nicht eingefügt werden, speichern wir einen Fehler. Wenn Sie nach unten in den HTML-Teil der Seite gehen, drucken wir nur den Wert von $html, sei es Fehler oder Erfolg. Dies ist natürlich nicht die eleganteste Lösung, aber es funktioniert!



Die kurze URL bereitstellen
Also haben wir die URL in der Datenbank, lass uns an der serve.php arbeiten, so dass wir den Funktionscode tatsächlich in eine Weiterleitung übersetzen können.
1 |
|
2 |
<?php
|
3 |
require("./db_config.php"); |
4 |
|
5 |
$short = $_REQUEST['short']; |
6 |
|
7 |
$db = mysql_connect($host, $username, $password); |
8 |
$query = mysql_query("SELECT * FROM `".$database."`.`url_redirects` WHERE `short`='".mysql_escape_string($short)."' LIMIT 1", $db); |
9 |
$row = mysql_fetch_row($query); |
10 |
|
11 |
if(!empty($row)) { |
12 |
Header("HTTP/1.1 301 Moved Permanently"); |
13 |
header("Location: ".$row[2].""); |
14 |
} else { |
15 |
$html = "Error: cannot find short URL"; |
16 |
}
|
17 |
|
18 |
mysql_close($db); |
19 |
?>
|
20 |
|
21 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
22 |
<html>
|
23 |
<head>
|
24 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
25 |
<title>Makes URLs Shrtr</title> |
26 |
<link type="text/css" rel="stylesheet" href="./css/style.css" /> |
27 |
</head>
|
28 |
<body>
|
29 |
<div id="pagewrap"> |
30 |
<h1>shrt<span class="r">r</span>.me</h1> |
31 |
|
32 |
<div class="body"> |
33 |
<?= $html ?> |
34 |
<br /><br /> |
35 |
<span class="back"><a href="./">X</a></span> |
36 |
</div>
|
37 |
|
38 |
</div>
|
39 |
</body>
|
40 |
</html>
|
Dieser ist der create.php sehr ähnlich. Wir fügen die Datenbankinformationen ein und speichern den uns zugesandten Funktionscode in einer Variablen namens $short. Als nächstes fragen wir die Datenbank nach der URL dieses Funktionscodes ab. Wenn wir ein Ergebnis bekommen, leiten wir auf die URL um, wenn nicht wie vorher ein Fehler ausgegeben wird.
Soweit PHP geht das ist alles, was wir tun müssen, aber im Moment eine kurze URL teilen Benutzer müssen dies eingeben, http://shrtr.me/server.php?short=SHORT_CODE nicht sehr hübsch ist es? Mal sehen, ob wir etwas mod_rewrite-Code einbauen können, um das schöner zu machen.
Pretty-ify mit HTACCESS
Von den beiden Methoden, über die ich zu Beginn des Tutorials geschrieben habe, werden wir den Apache verwenden, da diese Anwendung bereits ohne Berücksichtigung von URL-Parsing erstellt wurde. Der Code sieht ungefähr so aus:
1 |
|
2 |
Options +FollowSymLinks |
3 |
RewriteEngine On |
4 |
|
5 |
RewriteCond %{SCRIPT_FILENAME} !-d |
6 |
RewriteCond %{SCRIPT_FILENAME} !-f |
7 |
|
8 |
|
9 |
RewriteRule ^(\w+)$ ./serve.php?short=$1 |
Wenn wir auf die RewriteRule überspringen, leiten wir jeden Datenverkehr, der noch keine reale Datei oder ein Verzeichnis enthält, an die Datei serve.php und setzen die Erweiterung in die Variable GET kurz. Nicht zu schlecht, nein, probieren Sie es selbst aus!
Fazit
Heute haben wir ein paar verschiedene Methoden kennengelernt, um mod_rewrite in unserer Anwendung zu verwenden, um unsere URLs schön zu machen. Wie immer werde ich über die Kommentare wachen, wenn jemand Probleme hat, oder Sie können mich auf Twitter kontaktieren. Danke fürs Lesen!
- Folgen Sie uns auf Twitter, oder abonnieren Sie den NETTUTS RSS-Feed für mehr tägliche Web-Entwicklungstuts und -artikel.