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

Tips

str_contains() remplace un strpos() !== false depuis PHP 8.0

« if ( false !== strpos( $texte, $mot ) ) » a longtemps été le seul moyen de tester une sous-chaîne en PHP. Depuis la version 8.0, une fonction dédiée dit enfin ce qu'elle fait.

Par Clément Hadrot • 23 décembre 2025 • 4 min de lecture • Aucun commentaire
str_contains() remplace un strpos() !== false depuis PHP 8.0

if ( false !== strpos( $texte, $mot ) ) { ... } : cette tournure a occupé des milliers de bases de code PHP pendant des années, WordPress y compris, faute d’alternative native. strpos() retourne la position de la première occurrence trouvée, ou false si la sous-chaîne est absente — et comme la position 0 est une valeur falsy en PHP, comparer le résultat à false avec l’opérateur strict !== était la seule façon fiable de tester une présence, y compris en tout début de chaîne.

Depuis PHP 8.0, cette gymnastique n’est plus nécessaire : str_contains( string $haystack, string $needle ) retourne directement un booléen, sans piège de comparaison, et dit explicitement ce que le code cherche à savoir.

Pourquoi l’ancienne forme posait un vrai risque

Le bug classique consistait à écrire if ( strpos( $texte, $mot ) ) sans la comparaison stricte : si $mot se trouvait tout au début de $texte, à la position 0, la condition évaluait ce 0 comme faux, alors que la sous-chaîne était bien présente. Ce bug ne se manifestait que dans ce cas précis, ce qui le rendait difficile à repérer en test rapide et facile à laisser filer en revue de code.

str_contains() élimine ce piège à la racine : elle retourne toujours un booléen véritable, sans valeur intermédiaire ambiguë à interpréter.

Moderniser une vérification de code existant

L'essentiel à retenir : Teste une sous-chaîne sans comparaison stricte à false ; Retourne un booléen direct, plus lisible qu'un strpos détourné ; Disponible nativement depuis PHP 8.0

Sur une extension qui vérifie, par exemple, si une chaîne d’agent utilisateur correspond à un robot connu, la modernisation est directe :

// Avant PHP 8.0
function est_probablement_un_robot( $user_agent ) {
    return false !== strpos( $user_agent, 'bot' )
        || false !== strpos( $user_agent, 'crawler' );
}

// À partir de PHP 8.0
function est_probablement_un_robot( $user_agent ) {
    return str_contains( $user_agent, 'bot' )
        || str_contains( $user_agent, 'crawler' );
}

Le second bloc se lit sans effort supplémentaire, même par quelqu’un qui découvre le code : la fonction annonce directement son résultat, sans qu’il faille se souvenir de la règle de comparaison stricte à appliquer sur un appel à strpos().

Deux fonctions sœurs arrivées en même temps

PHP 8.0 a introduit str_contains() aux côtés de deux autres fonctions qui couvrent des besoins voisins :

  • str_starts_with( string $haystack, string $needle ) : teste si une chaîne commence par une sous-chaîne donnée.
  • str_ends_with( string $haystack, string $needle ) : teste si une chaîne se termine par une sous-chaîne donnée.
  • str_contains() : teste une présence n’importe où dans la chaîne, ce qui couvre le besoin le plus général des trois.

Ces trois fonctions remplacent, à elles seules, la grande majorité des usages de strpos() détourné en simple test de présence, laissant strpos() aux cas où la position exacte de la sous-chaîne importe réellement pour la suite du traitement.

Vérifier la version minimale avant de moderniser

Avant de remplacer systématiquement un strpos() par str_contains() dans une extension existante, il reste indispensable de vérifier la version minimale de PHP déclarée dans l’en-tête de l’extension. Utiliser str_contains() sur un hébergement encore sous PHP 7.4 provoquerait une erreur fatale à l’exécution, la fonction étant simplement inexistante avant PHP 8.0.

Avant toute modernisation de ce type, vérifier la ligne « Requires PHP » de l’en-tête de l’extension : c’est elle qui indique si str_contains() peut être utilisée sans risque sur l’ensemble du parc d’hébergement visé.

Un détail qui compte : la chaîne vide

Un comportement mérite d’être vérifié avant de généraliser le remplacement : str_contains( $texte, '' ) retourne toujours true, quelle que soit la valeur de $texte, puisqu’une chaîne vide est considérée comme présente partout. C’est également le comportement historique de strpos() sur une aiguille vide, qui renvoie 0 plutôt que false — donc rien ne change ici, mais le cas mérite d’être gardé en tête si un attribut ou un paramètre peut légitimement arriver vide dans le code modernisé.

En résumé

str_contains() n’ajoute aucune capacité qu’un strpos() comparé strictement à false ne couvrait déjà, mais elle élimine un piège de comparaison connu et rend l’intention du code immédiatement lisible. Sur une base de code visant PHP 8.0 ou une version plus récente, il n’y a plus de raison de conserver l’ancienne tournure, sauf dans les cas où la position exacte de la sous-chaîne trouvée reste nécessaire pour la suite du traitement.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi