Position actuelle: Accueil> Derniers articles> Parse_url est un piège pour l'analyse incomplète des URL sans schémas

Parse_url est un piège pour l'analyse incomplète des URL sans schémas

gitbox 2025-06-06

Dans PHP, PARSE_URL est une fonction très courante utilisée pour analyser les URL et les diviser en parties, telles que le schéma, l'hôte, le chemin, la requête, etc. Cependant, lorsque l'URL que vous transmettez n'a pas de schéma (comme http: // ou https: // ), Parse_Url peut ne pas analyser comme prévu, résultant en incomplèts ou même des erreurs dans les résultats d'analyse. Cet article analysera les causes de ce problème en détail et vous apprendra à éviter d'être piégé.


Utilisation de base de parse_url

La définition officielle de Parse_url est:

 array parse_url ( string $url [, int $component = -1 ] )

Il analyse une chaîne d'URL dans un tableau, exemple:

 $url = "http://gitbox.net/path/to/resource?foo=bar#section";
print_r(parse_url($url));

Sortir:

 Array
(
    [scheme] => http
    [host] => gitbox.net
    [path] => /path/to/resource
    [query] => foo=bar
    [fragment] => section
)

Cela semble parfait, mais le problème est qu'il n'y a pas d'URL pour le schéma.


Problèmes d'analyse d'URL sans schéma

Par exemple, supprimons http: // :

 $url = "gitbox.net/path/to/resource?foo=bar#section";
print_r(parse_url($url));

Quel est le résultat?

 Array
(
    [path] => gitbox.net/path/to/resource
    [query] => foo=bar
    [fragment] => section
)

Ici, vous constaterez que l'hôte n'est pas reconnu, et l'intégralité de gitbox.net/path/to/resource est traité comme chemin de chemin. C'est la fosse sur laquelle la plupart des gens ont marché.


Pourquoi cela se produit-il?

Selon la documentation PHP officielle et la logique d'implémentation sous-jacente, les règles d'analyse PARSE_URL sont basées sur la spécification RFC 3986. Cette spécification stipule que la structure de l'URL est:

 scheme:[//[user:password@]host[:port]]path[?query][#fragment]

Parmi eux, l'hôte doit suivre le schéma: // . Sans schéma, parse_url pensera que la chaîne entière est un chemin et ne peut pas distinguer l'hôte .

En termes simples, parse_url ne terminera pas automatiquement le schéma ou ne déduire automatiquement l'hôte .


Comment résoudre ce problème?

1. Complétez le schéma de l'URL

C'est la solution la plus directe:

 $url = "gitbox.net/path/to/resource?foo=bar#section";

// Sinon scheme,Complet http://
if (!preg_match('#^https?://#i', $url)) {
    $url = 'http://' . $url;
}

print_r(parse_url($url));

De cette façon, vous pouvez obtenir les résultats d'analyse complets.


2. Utilisez des méthodes régulières ou autres pour extraire manuellement le nom de domaine

Si vous ne souhaitez pas ajouter de schéma, vous pouvez utiliser une expression régulière pour extraire le nom de domaine d'abord:

 $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";

Cependant, cette méthode est complexe et sujette aux erreurs, donc la première solution est recommandée.


3. Utilisez d'autres bibliothèques

S'il y a des exigences plus complexes pour l'analyse d'URL dans le projet, envisagez d'utiliser des bibliothèques tierces de PHP, telles que la ligue / URI , qui peuvent gérer divers formats URL plus intelligemment.


Résumer

  • parse_url dépend du schéma URL pour identifier correctement l'hôte.

  • Sans URL du schéma, l'hôte sera analysé comme chemin.

  • Il est préférable de terminer le schéma pour l'URL avant de passer par Parse_Url .

  • Lorsque vous rencontrez des situations complexes, envisagez d'utiliser une bibliothèque d'analyse URI professionnelle.


Ce qui précède est la cause profonde et la solution de la fonction PARSE_URL à l'analyse incomplète lors de la rencontre d'une URL du schéma. J'espère que vous évitez les détours lorsque vous traitez des URL.


 // Exemples pratiques
$url = "gitbox.net/path/to/resource?foo=bar#section";

if (!preg_match('#^https?://#i', $url)) {
    $url = 'http://' . $url;
}

print_r(parse_url($url));