# wp_parse_url plutôt que parse_url : la différence sur une URL relative

> PHP_URL_HOST vide, chemin manquant : parse_url() natif trébuche sur les URL relatives là où sa contrepartie WordPress s'en sort sans broncher.

- Auteur : WordPress Développement
- Publié le : 2023-04-28
- Mis à jour le : 2023-04-28
- Catégorie : Astuces
- URL : https://www.wpmoderne.fr/tips/wp-parse-url-url-relative/

## L’essentiel

- parse_url() natif échoue sur certaines URL relatives ou mal formées
- wp_parse_url() applique un correctif avant l'analyse
- Le filtre wp_parse_url renvoie systématiquement un tableau exploitable

`Warning: Illegal string offset` ou, pire, un tableau incomplet sans la clé `path` attendue : c'est souvent ainsi qu'on découvre les limites de `parse_url()`, la fonction native de PHP pour décomposer une URL en ses composants.

Le problème se manifeste rarement sur des URL absolues bien formées. Il apparaît surtout quand on traite des saisies d'utilisateurs, des chemins relatifs, ou des URL construites dynamiquement par un formulaire, un import, ou un champ de configuration mal validé en amont.

## Les limites concrètes de parse_url()

Prenons un cas simple : un utilisateur saisit `www.example.com/produits` sans préciser de schéma. La fonction native PHP interprète alors `www.example.com` comme un chemin plutôt que comme un nom d'hôte, faute de `http://` ou `https://` en préfixe :

```
var_dump( parse_url( 'www.example.com/produits' ) );
// array(1) { ["path"]=> string(24) "www.example.com/produits" }
```

Aucune clé `host` dans le résultat, alors que l'intention de l'utilisateur était manifestement de désigner un domaine. Autre cas piégeux : certaines versions de PHP traitent différemment les URL contenant des caractères spéciaux non encodés, ou des ports mal formés, avec des résultats parfois incohérents d'une version à l'autre du langage.

## Ce que corrige wp_parse_url()

> L'essentiel à retenir : parse_url() natif échoue sur certaines URL relatives ou mal formées ; wp_parse_url() applique un correctif avant l'analyse ; Le filtre wp_parse_url renvoie systématiquement un tableau exploitable

WordPress fournit sa propre fonction, `wp_parse_url()`, qui encapsule `parse_url()` tout en corrigeant ses cas limites les plus fréquents. Avant l'analyse, elle détecte notamment les schémas absents et ajuste l'entrée pour que l'hôte soit correctement identifié :

```
$composants = wp_parse_url( 'www.example.com/produits' );

print_r( $composants );
// array(
//     [host] => www.example.com
//     [path] => /produits
// )
```

Le résultat distingue enfin correctement l'hôte du chemin, ce qui change tout pour une fonction qui doit ensuite comparer des domaines, construire un lien absolu, ou vérifier qu'une redirection reste bien sur le même site.

## Un filtre applicable au résultat

Autre différence notable : `wp_parse_url()` déclenche le filtre `wp_parse_url`, qui reçoit le tableau de composants juste avant qu'il ne soit renvoyé à l'appelant. Cela permet, par exemple, de corriger systématiquement un cas particulier propre à un projet, sans devoir retoucher chaque appel individuel dans le code :

```
add_filter( 'wp_parse_url', function ( $composants ) {
    if ( isset( $composants['host'] ) ) {
        $composants['host'] = strtolower( $composants['host'] );
    }

    return $composants;
} );
```

Ce filtre n'existe évidemment pas sur la fonction native de PHP, puisqu'elle ignore tout du système de hooks de WordPress.

## Quand préférer l'une ou l'autre

- Pour une URL saisie par un visiteur ou provenant d'une source externe non contrôlée, `wp_parse_url()` limite les surprises.
- Pour une URL générée en interne, connue et déjà bien formée, `parse_url()` natif fonctionne sans souci particulier.
- Dans du code destiné à être partagé sur plusieurs projets WordPress, utiliser systématiquement `wp_parse_url()` évite d'avoir à réexpliquer le piège à chaque relecture.

## Un exemple concret de conséquence

Imaginons une fonction qui vérifie qu'un lien de redirection pointe bien vers le domaine du site, avant d'autoriser un renvoi automatique après connexion :

```
function redirection_est_interne( $url ) {
    $cible = wp_parse_url( $url );
    $site  = wp_parse_url( home_url() );

    return isset( $cible['host'] ) && $cible['host'] === $site['host'];
}
```

Avec `parse_url()` natif, une URL relative sans schéma explicite pourrait passer entre les mailles de cette vérification, faute de clé `host` détectée, ouvrant potentiellement la voie à une redirection non maîtrisée. `wp_parse_url()` referme cette faille en normalisant l'entrée avant de statuer.

> Sur toute fonction qui manipule des URL fournies par un visiteur, remplacer systématiquement `parse_url` par `wp_parse_url` coûte une simple relecture de code et évite des comportements imprévisibles selon la forme exacte de l'entrée.

## En résumé

La différence entre les deux fonctions tient à une poignée de cas limites, mais ce sont précisément ceux qui posent problème en production : URL sans schéma, hôte mal identifié, résultat incomplet. Dans un contexte WordPress, il n'y a d'ailleurs guère de raison de se priver de `wp_parse_url()`, disponible nativement et sans dépendance supplémentaire.
