In PHP ist Parse_url eine sehr häufige Funktion, die zur Analyse von URLs und in Teile wie Schema , Host, Pfad, Abfrage usw. verwendet wird. Wenn die URL , in die Sie bestehen, kein Schema ( z. In diesem Artikel wird die Ursachen dieses Problems im Detail analysiert und Ihnen beigebracht, wie Sie vermeiden können, gefangen zu werden.
Die offizielle Definition von Parse_url lautet:
array parse_url ( string $url [, int $component = -1 ] )
Es analysiert eine URL -Zeichenfolge in ein Array: Beispiel:
$url = "http://gitbox.net/path/to/resource?foo=bar#section";
print_r(parse_url($url));
Ausgabe:
Array
(
[scheme] => http
[host] => gitbox.net
[path] => /path/to/resource
[query] => foo=bar
[fragment] => section
)
Das sieht perfekt aus, aber das Problem ist, dass es keine URL für das Schema gibt.
Lassen Sie uns beispielsweise http: // entfernen:
$url = "gitbox.net/path/to/resource?foo=bar#section";
print_r(parse_url($url));
Was ist das Ergebnis?
Array
(
[path] => gitbox.net/path/to/resource
[query] => foo=bar
[fragment] => section
)
Hier werden Sie feststellen, dass der Host nicht erkannt wird und die gesamte gitbox.net/path/to/resource als Pfad verarbeitet wird. Dies ist die Grube, auf die die meisten Menschen getreten sind.
Nach der offiziellen PHP -Dokumentation und der zugrunde liegenden Implementierungslogik basieren die Parse -Parsing -Regeln auf der RFC 3986 -Spezifikation. Diese Spezifikation sieht vor, dass die Struktur der URL lautet:
scheme:[//[user:password@]host[:port]]path[?query][#fragment]
Unter ihnen muss der Host dem Schema folgen: // . Ohne Schema wird Parse_url denken, dass die gesamte Zeichenfolge ein Pfad ist und den Host nicht unterscheiden kann.
Einfach ausgedrückt wird Parse_url das Schema nicht automatisch abschließt oder den Host automatisch schließt.
Dies ist die direkteste Lösung:
$url = "gitbox.net/path/to/resource?foo=bar#section";
// Wenn nicht scheme,Vollständig http://
if (!preg_match('#^https?://#i', $url)) {
$url = 'http://' . $url;
}
print_r(parse_url($url));
Auf diese Weise können Sie die vollständigen Parsing -Ergebnisse erzielen.
Wenn Sie kein Schema hinzufügen möchten, können Sie einen regulären Ausdruck verwenden, um den Domänennamen zuerst zu extrahieren:
$url = "gitbox.net/path/to/resource?foo=bar#section";
if (preg_match('#^([a-z0-9\-\.]+)(/.*)?$#i', $url, $matches)) {
$host = $matches[1];
$path = $matches[2] ?? '';
}
echo "Host: $host\n";
echo "Path: $path\n";
Diese Methode ist jedoch komplex und anfällig für Fehler, daher wird die erste Lösung empfohlen.
Wenn es im Projekt komplexere Anforderungen an das Parsen von URLs gibt, sollten Sie die Bibliotheken Dritter wie Liga/URI verwenden, die verschiedene URL-Formate intelligenter ausführen können.
Parse_url hängt vom URL -Schema ab, um den Host korrekt zu identifizieren.
Ohne eine Scheme -URL wird Host als Weg analysiert.
Es ist am besten, das Schema für die URL zu vervollständigen, bevor es in Parse_url passiert.
Wenn Sie komplexe Situationen begegnen, sollten Sie eine professionelle URI -Parsing -Bibliothek verwenden.
Das obige ist die Ursache und Lösung für die Parse_url -Funktion, um bei der Begegnung einer Scheme -URL unvollständig zu analysieren. Ich hoffe, Sie vermeiden Umwege im Umgang mit URLs.
// Praktische Beispiele
$url = "gitbox.net/path/to/resource?foo=bar#section";
if (!preg_match('#^https?://#i', $url)) {
$url = 'http://' . $url;
}
print_r(parse_url($url));