Le WordPress d'aujourd'hui, décodé pour les développeurs

Astuces

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.

Par WordPress Développement • 28 avril 2023 • 4 min de lecture • Aucun commentaire
wp_parse_url plutôt que parse_url : la différence sur une URL relative

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.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi