Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
 
 
 

PHP urlencode(): Sonderzeichen in URLs richtig kodieren

Sie befinden sich: Home > Php Tutorial > PHP urlencode(): Sonderzeic...

PHP urlencode(): Sonderzeichen in URLs richtig kodieren
Eintrag am:
07.08.2026
Hits / Besucher:
11
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Die Suche funktioniert, solange jemand ein einzelnes Wort eingibt. Sobald zwei Woerter kommen oder ein Kaufmanns-Und im Text steht, bricht der Link ab und die Hälfte des Suchbegriffs verschwindet. Das liegt nicht an deinem Formular, sondern daran, dass bestimmte Zeichen in einer URL eine eigene Bedeutung haben. PHP urlencode nimmt ihnen diese Bedeutung.

Illustration zum Tutorial: PHP urlencode(): Sonderzeichen in URLs richtig kodieren

Am schnellsten wird das an einem kaputten Link deutlich.

Das Problem: ein Link, der beim Leerzeichen abbricht

<?php

$suche = 'blaue Schuhe & Taschen';

/* Ohne Kodierung: der Link bricht am Leerzeichen und am & */
echo '/suche.php?q=' . $suche;
/* /suche.php?q=blaue Schuhe & Taschen */

/* Mit Kodierung: alles bleibt ein einziger Parameter */
echo '/suche.php?q=' . urlencode($suche);
/* /suche.php?q=blaue+Schuhe+%26+Taschen */

In der ersten Variante liest der Browser bis zum Leerzeichen und hört dort auf. Selbst wenn er den Link noch akzeptiert, zerlegt das Kaufmanns-Und den Rest in einen zweiten Parameter namens Taschen. In der zweiten Variante steht der komplette Suchbegriff als ein Wert im Parameter q, und $_GET['q'] liefert ihn vollständig zurück.

Was PHP urlencode genau macht

Eine URL ist kein beliebiger Text, sondern eine Struktur mit festen Trennzeichen. Das Fragezeichen trennt Pfad und Abfrageteil, das Kaufmanns-Und trennt Parameter voneinander, das Gleichheitszeichen trennt Name und Wert, das Rautezeichen leitet das Fragment ein, und der Schrägstrich trennt Pfadsegmente. Steht eines dieser Zeichen mitten in einem Wert, kann der Empfänger nicht mehr unterscheiden, ob es zur Struktur oder zum Inhalt gehört.

Die Lösung heisst Prozentkodierung. Jedes problematische Byte wird durch ein Prozentzeichen und zwei Hexadezimalziffern ersetzt. Aus dem Kaufmanns-Und wird %26, aus dem Fragezeichen %3F, aus dem Schrägstrich %2F. Der Empfänger dreht das beim Auslesen wieder zurück und bekommt den ursprünglichen Wert.

Buchstaben, Ziffern sowie Bindestrich, Unterstrich und Punkt bleiben unverändert. Alles andere wird kodiert. Diese sechs Zeichen richten ohne Kodierung den meisten Schaden an:

Zeichen Kodiert Bedeutung in der URL, wenn nicht kodiert
& %26 beginnt einen neuen Parameter, der Rest des Wertes geht verloren
? %3F leitet den Abfrageteil ein, ein zweites Fragezeichen verwirrt manche Server
= %3D trennt Name und Wert, der Wert wird an der falschen Stelle geteilt
# %23 beginnt das Fragment, alles danach erreicht den Server gar nicht erst
/ %2F trennt Pfadsegmente, im Pfad entsteht daraus eine falsche Route
Leerzeichen + oder %20 beendet die URL, alles danach wird abgeschnitten

Das Rautezeichen ist dabei besonders tückisch. Es erzeugt keinen sichtbaren Fehler, sondern der abgeschnittene Teil kommt einfach nie beim Server an. Im Browser sieht die Adresse vollständig aus, im Serverlog fehlt die Hälfte.

PHP urlencode oder rawurlencode?

Neben PHP urlencode gibt es eine zweite Funktion, die fast dasselbe tut. Der Unterschied betrifft genau zwei Zeichen, hat aber praktische Folgen.

<?php

$wert = 'a b~c/d';

echo urlencode($wert); /* a+b%7Ec%2Fd */
echo rawurlencode($wert); /* a%20b~c%2Fd */
  urlencode() rawurlencode()
Leerzeichen wird zu + wird zu %20
Tilde wird zu %7E bleibt ~
Folgt der alten Formularkodierung RFC 3986
Richtig für Werte im Abfrageteil Pfadsegmente, Fremd-APIs, HTTP-Header

Die Faustregel ist kurz: im Abfrageteil funktionieren beide, in einem Pfadsegment nur rawurlencode(). Ein Pluszeichen im Pfad bleibt nämlich ein Pluszeichen und wird nicht als Leerzeichen gelesen.

<?php

$ordner = 'Meine Bilder';

/* Falsch: das Pluszeichen bleibt im Pfad ein Pluszeichen */
echo '/galerie/' . urlencode($ordner) . '/index.html';
/* /galerie/Meine+Bilder/index.html */

/* Richtig: */
echo '/galerie/' . rawurlencode($ordner) . '/index.html';
/* /galerie/Meine%20Bilder/index.html */

Auch bei Fremd-APIs lohnt rawurlencode(). Manche Anbieter prüfen Signaturen über die exakte Zeichenfolge der Anfrage, und ein + statt %20 reicht dann für eine Ablehnung.

Query-Strings bauen mit http_build_query()

Sobald mehr als ein Parameter im Spiel ist, wird das Zusammensetzen von Hand fehleranfällig. Irgendwann fehlt bei einem Wert der Aufruf von PHP urlencode, und der Fehler zeigt sich erst bei einer bestimmten Eingabe.

<?php

$parameter = [
'q' => 'blaue Schuhe & Taschen',
'seite' => 2,
'sort' => 'preis_asc',
'farben' => ['blau', 'gruen'],
];

echo '/suche.php?' . http_build_query($parameter);
/* /suche.php?q=blaue+Schuhe+%26+Taschen&seite=2&sort=preis_asc
&farben%5B0%5D=blau&farben%5B1%5D=gruen */

/* Mit %20 statt + fuer RFC-3986-konforme Ausgabe: */
echo http_build_query($parameter, '', '&', PHP_QUERY_RFC3986);

Die Funktion kodiert jeden Wert selbst, setzt die Trennzeichen und löst verschachtelte Arrays in die Klammernotation auf. Der vierte Parameter schaltet zwischen den beiden Kodierarten um, die du oben schon kennst. In neuem Code ist http_build_query() fast immer die bessere Wahl als eine Kette aus Punktverkettungen.

Dekodieren: wann nötig und wann schädlich

Hier passiert der häufigste unnötige Fehler im Umgang mit PHP urlencode. PHP dekodiert die Werte in $_GET und $_POST bereits beim Einlesen. Ein zusätzlicher Aufruf von urldecode() dekodiert also ein zweites Mal und zerstört dabei Werte, die ein echtes Pluszeichen enthalten.

<?php

/* Aufruf: /suche.php?q=C%2B%2B+Kurs */

echo $_GET['q']; /* C++ Kurs, PHP hat schon dekodiert */
echo urldecode($_GET['q']); /* C Kurs, die Pluszeichen sind weg */

Das Dekodieren gehört nur dorthin, wo du selbst einen String aus einer URL geschnitten hast, etwa nach einem parse_url(). Und selbst dann ist parse_str() meist die bessere Wahl, weil es den Abfrageteil gleich in ein Array zerlegt.

<?php

$abfrage = parse_url('/s.php?q=C%2B%2B&seite=2', PHP_URL_QUERY);
parse_str($abfrage, $werte);

echo $werte['q']; /* C++ */
echo $werte['seite']; /* 2 */

Umlaute und andere Mehrbyte-Zeichen

Bei Umlauten fällt auf, dass ein einzelnes Zeichen mehrere Prozentgruppen ergibt. Das ist korrekt und kein Zeichen dafür, dass etwas schiefgelaufen ist.

<?php

/* In UTF-8 belegt ein Umlaut zwei Bytes, jedes wird einzeln kodiert */
echo rawurlencode('München'); /* M%C3%BCnchen */
echo rawurlencode('Größe'); /* Gr%C3%B6%C3%9Fe */

Die Kodierung arbeitet auf Bytes, nicht auf Zeichen. Ein Umlaut besteht in UTF-8 aus zwei Bytes und ergibt deshalb zwei Gruppen, ein kyrillisches oder ostasiatisches Zeichen aus drei Bytes entsprechend drei. Voraussetzung ist, dass deine Quelldaten wirklich UTF-8 sind. Kommen sie aus einer alten Datenbank in Latin-1, entstehen andere Bytefolgen, und der Empfänger bekommt Zeichensalat.

Der folgende Ablauf zeigt, welche Funktion an welche Stelle gehört.

flowchart TD
    A[Wert soll in die URL] --> B{Wohin genau?}
    B -->|Query-Parameter| C{Mehrere Werte?}
    C -->|Ja| D[http_build_query nutzen]
    C -->|Nein| E[urlencode nutzen]
    B -->|Pfadsegment| F[rawurlencode nutzen]
    D --> G{Landet im HTML?}
    E --> G
    F --> G
    G -->|Ja| H[zusaetzlich htmlspecialchars]
    G -->|Nein| I[fertig]

Eine URL als Parameter übergeben

Weiterleitungen und Tracking-Links hängen oft eine vollständige URL als Wert an eine andere URL. Ohne Kodierung landen die Parameter der inneren URL in der äusseren und zerlegen den Aufruf.

<?php

$ziel = 'https://example.org/shop?artikel=42&farbe=blau';

$link = '/weiter.php?url=' . urlencode($ziel);
echo $link;
/* /weiter.php?url=https%3A%2F%2Fexample.org%2Fshop%3Fartikel%3D42
%26farbe%3Dblau */

/* In weiter.php ist der Wert bereits wieder vollstaendig: */
$ziel = $_GET['url']; /* https://example.org/shop?artikel=42&farbe=blau */

Kodiert wird genau einmal, und PHP dekodiert genau einmal. Wer hier vorsichtshalber ein zweites urldecode() einbaut, bekommt genau das Problem, das er vermeiden wollte.

Ein verwandter Fall betrifft Base64-Werte. Deren Alphabet enthält Pluszeichen und Schrägstriche, und beide brauchen in einer URL eine Kodierung. Das Tutorial zu PHP base64_encode() und _decode() geht darauf im Detail ein.

PHP urlencode ist kein XSS-Schutz

Diese Verwechslung taucht in Codereviews regelmässig auf: ein Wert wird kodiert und dann ungeschuetzt in ein HTML-Attribut geschrieben. Beide Funktionen haben aber verschiedene Zuständigkeiten.

<?php

$wert = '"><script>alert(1)</script>';

/* Falsch: kodiert fuer die URL, aber im HTML-Kontext ungeschuetzt */
echo '<a href="/s.php?q=' . urlencode($wert) . '">Suche</a>';

/* Richtig: erst fuer die URL kodieren, dann fuers HTML escapen */
$url = '/s.php?q=' . urlencode($wert);
echo '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">Suche</a>';

PHP urlencode schützt die Struktur der URL. htmlspecialchars() schützt das umgebende HTML-Dokument. Ein Wert, der beide Ebenen durchläuft, braucht beide Funktionen nacheinander, und zwar in dieser Reihenfolge.

Zum Schluss noch eine Abgrenzung, die oft untergeht: für sprechende URLs ist Kodierung der falsche Weg. Ein Produktname wird für die Adresszeile nicht kodiert, sondern in einen Slug umgeschrieben, also transliteriert und auf Kleinbuchstaben und Bindestriche reduziert. Eine Prozentkette ist technisch korrekt, aber niemand kann sie vorlesen. Wie Werte grundsätzlich per URL übergeben und ausgelesen werden, steht im Tutorial zu Variablen per URL mit $_GET übergeben.

Fazit

PHP urlencode macht aus einem beliebigen Wert eine Zeichenfolge, die in einer URL keinen Schaden anrichtet. Das Lösen des ursprünglichen Problems dauert eine Zeile.

Drei Dinge lohnen sich zu merken. Im Pfad gehört rawurlencode() hin, nicht urlencode(). Bei mehreren Parametern nimmt dir http_build_query() die gesamte Handarbeit ab. Und Werte aus $_GET sind bereits dekodiert, ein zweiter Aufruf von urldecode() schadet nur. Wer diese drei Punkte beachtet, baut Links, die auch mit Umlauten, Leerzeichen und Kaufmanns-Und funktionieren.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.