
Dans cet article
- La fonction strpos en PHP retourne la position (index à partir de 0) de la première occurrence d’une sous-chaîne
- La comparaison stricte avec === false est indispensable pour éviter les bugs liés au retour de la position 0
- Depuis PHP 8, str_contains() remplace avantageusement strpos pour un simple test de présence
- La variante stripos() effectue une recherche insensible à la casse, utile pour les saisies utilisateur
- Le paramètre offset permet de lancer la recherche à partir d’une position précise dans la chaîne
- En production, je recommande de combiner strpos avec substr et explode pour des traitements de chaînes robustes
Sommaire
- Comprendre strpos en PHP : syntaxe et fonctionnement
- Le piège classique : pourquoi utiliser la comparaison stricte
- Exemples pratiques d’utilisation de strpos
- Strpos ou stripos : quelle différence et quand les utiliser
- Str_contains vs strpos : que choisir depuis PHP 8
- Fonctions complémentaires pour manipuler les chaînes
- Bonnes pratiques pour utiliser strpos en production
- Tableau comparatif des fonctions de recherche en PHP
- Erreurs fréquentes et comment les éviter
En plus de dix ans de développement PHP, je peux affirmer que strpos fait partie des fonctions que j’utilise quotidiennement. Que ce soit pour valider une adresse e-mail, parser un fichier CSV ou filtrer des données utilisateur, la recherche de sous-chaîne est une opération fondamentale. Pourtant, cette fonction cache un piège redoutable qui a causé des bugs dans d’innombrables projets, y compris les miens à mes débuts. Dans ce guide, je vous explique tout ce qu’il faut savoir sur strpos en PHP, avec des exemples concrets tirés de situations réelles.
Comprendre strpos en PHP : syntaxe et fonctionnement
La fonction strpos php permet de chercher la position de la première occurrence d’une sous-chaîne dans une chaîne principale. Elle retourne un entier correspondant à l’index (qui commence à 0) ou false si la sous-chaîne n’est pas trouvée.
Voici la signature officielle de la fonction, telle que décrite dans la documentation officielle PHP :
strpos(string $haystack, string $needle, int $offset = 0): int|false
Les trois paramètres sont les suivants :
- $haystack : la chaîne dans laquelle on effectue la recherche (la « botte de foin »)
- $needle : la sous-chaîne que l’on cherche (l’« aiguille »)
- $offset : la position à partir de laquelle débuter la recherche (optionnel, défaut à 0)
Un exemple simple pour bien comprendre le mécanisme :
<?php
$phrase = "Bonjour le monde";
$position = strpos($phrase, "monde");
echo $position; // Affiche 12
?>
Ici, le mot « monde » commence à l’index 12 dans la chaîne. Chaque caractère occupe une position, en partant de 0 pour la lettre « B ». C’est un principe que l’on retrouve dans la plupart des langages de programmation, comme la méthode find en JavaScript par exemple.

Le piège classique : pourquoi utiliser la comparaison stricte
C’est le point le plus important de cet article, et probablement la source de bug la plus courante liée à strpos en php. Quand la sous-chaîne se trouve au tout début de la chaîne, strpos retourne 0. Or, en PHP, 0 est évalué comme false dans un contexte booléen.
<?php
$url = "https://web-city.fr";
// ERREUR CLASSIQUE : ne faites jamais cela
if (strpos($url, "https") == false) {
echo "Pas de HTTPS"; // Ce code s'exécute alors que HTTPS est présent !
}
// BONNE PRATIQUE : comparaison stricte
if (strpos($url, "https") === false) {
echo "Pas de HTTPS";
} else {
echo "HTTPS détecté"; // Ce code s'exécute correctement
}
?>
La différence entre == et === est cruciale ici. L’opérateur === vérifie à la fois la valeur et le type. Comme 0 est un entier et false est un booléen, la comparaison stricte les distingue correctement. J’ai personnellement passé des heures à déboguer ce type de problème en début de carrière, et je le vois encore régulièrement dans les projets que j’audite.
Pour vérifier qu’une sous-chaîne existe dans une chaîne, utilisez toujours ce pattern :
<?php
// Vérifier la PRÉSENCE
if (strpos($chaine, $recherche) !== false) {
// La sous-chaîne a été trouvée
}
// Vérifier l'ABSENCE
if (strpos($chaine, $recherche) === false) {
// La sous-chaîne n'a pas été trouvée
}
?>
Exemples pratiques d’utilisation de strpos
Passons aux cas concrets. Voici les scénarios dans lesquels j’utilise le plus souvent php strpos dans mes projets professionnels.
Valider un format d’adresse e-mail basique
<?php
function contientArobase(string $email): bool
{
return strpos($email, '@') !== false;
}
var_dump(contientArobase('[email protected]')); // true
var_dump(contientArobase('adresse-invalide')); // false
?>
Bien sûr, pour une validation complète d’e-mail, je recommande filter_var() avec le filtre FILTER_VALIDATE_EMAIL. Mais strpos est parfait pour un premier contrôle rapide.
Détecter le type de navigateur
<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'];
if (strpos($userAgent, 'Firefox') !== false) {
$navigateur = 'Mozilla Firefox';
} elseif (strpos($userAgent, 'Chrome') !== false) {
$navigateur = 'Google Chrome';
} elseif (strpos($userAgent, 'Safari') !== false) {
$navigateur = 'Safari';
} else {
$navigateur = 'Autre';
}
echo "Navigateur détecté : $navigateur";
?>
Extraire un domaine à partir d’une URL
<?php
$url = "https://www.web-city.fr/blog/article";
// Trouver la position après le protocole
$debut = strpos($url, '//') + 2;
$fin = strpos($url, '/', $debut);
$domaine = substr($url, $debut, $fin - $debut);
echo $domaine; // www.web-city.fr
?>
Cet exemple combine strpos avec substr pour extraire une portion de chaîne. Notez l’utilisation du paramètre offset dans le second appel à strpos : je démarre la recherche du slash après le protocole pour ne pas retomber sur les slashs de « https:// ».
Utiliser l’offset pour des recherches multiples
<?php
$texte = "PHP est puissant. PHP est flexible. PHP est populaire.";
$mot = "PHP";
$offset = 0;
$occurrences = [];
while (($pos = strpos($texte, $mot, $offset)) !== false) {
$occurrences[] = $pos;
$offset = $pos + strlen($mot);
}
echo "Positions trouvées : " . implode(', ', $occurrences);
// Affiche : Positions trouvées : 0, 18, 35
?>
Ce pattern de boucle avec offset incrémental est très utile pour compter ou localiser toutes les occurrences d’un mot dans un texte. C’est une technique que j’emploie régulièrement dans mes projets utilisant différents frameworks pour le parsing côté serveur.

Strpos ou stripos : quelle différence et quand les utiliser
La fonction stripos() est la version insensible à la casse de strpos. Son rôle est identique : rechercher la position d’une sous-chaîne. La seule différence réside dans le fait qu’elle ne distingue pas les majuscules des minuscules.
<?php
$texte = "Bienvenue sur WordPress";
// strpos est sensible à la casse
var_dump(strpos($texte, 'wordpress')); // false
var_dump(strpos($texte, 'WordPress')); // int(14)
// stripos ignore la casse
var_dump(stripos($texte, 'wordpress')); // int(14)
var_dump(stripos($texte, 'WORDPRESS')); // int(14)
?>
En pratique, j’utilise stripos dans deux situations principales :
- Recherche dans les saisies utilisateur : un visiteur peut taper « paris », « Paris » ou « PARIS », et je veux détecter le mot dans tous les cas
- Analyse de chaînes techniques : les en-têtes HTTP, les User-Agent ou les types MIME peuvent varier en casse selon les serveurs
Attention cependant : stripos est légèrement plus lente que strpos car elle doit normaliser la casse en interne. Sur des boucles traitant des milliers d’itérations, la différence peut devenir mesurable. Si vous maîtrisez la casse de vos données, préférez strpos avec un appel préalable à strtolower pour normaliser la chaîne une seule fois.
Pour ceux qui travaillent sur des projets WordPress, stripos s’avère particulièrement utile pour filtrer du contenu dans les hooks sans se soucier de la casse saisie par les rédacteurs.
Str_contains vs strpos : que choisir depuis PHP 8
Avec l’arrivée de PHP 8.0, trois nouvelles fonctions ont été introduites pour simplifier les opérations courantes sur les chaînes : str_contains(), str_starts_with() et str_ends_with(). Ces fonctions répondent à un besoin que strpos couvrait de manière détournée.
<?php
// Avant PHP 8 : strpos pour tester la présence
if (strpos($email, '@domaine.fr') !== false) {
echo "E-mail interne";
}
// Depuis PHP 8 : str_contains, plus lisible
if (str_contains($email, '@domaine.fr')) {
echo "E-mail interne";
}
?>
La différence fondamentale est la suivante : str_contains retourne un booléen (true ou false), tandis que strpos retourne la position ou false. Le choix dépend donc de votre besoin :
- Vous avez besoin de savoir si une sous-chaîne existe : utilisez
str_contains() - Vous avez besoin de savoir où elle se trouve : utilisez
strpos()
En pratique, dans mes projets Symfony récents, j’utilise str_contains pour la majorité des tests de présence. Le code est plus lisible, il n’y a plus de risque lié à la comparaison stricte, et l’intention est immédiatement claire pour les autres développeurs de l’équipe. C’est un gain de lisibilité similaire à ce qu’on retrouve avec les méthodes modernes de Set en JavaScript.
Voici un comparatif des trois nouvelles fonctions PHP 8, documentées sur le wiki officiel des RFC PHP :
<?php
$fichier = "rapport-2026-final.pdf";
// str_contains : contient la sous-chaîne ?
var_dump(str_contains($fichier, '2026')); // true
// str_starts_with : commence par ?
var_dump(str_starts_with($fichier, 'rapport')); // true
// str_ends_with : se termine par ?
var_dump(str_ends_with($fichier, '.pdf')); // true
?>
Fonctions complémentaires pour manipuler les chaînes
Strpos fonctionne rarement seule. Dans la plupart de mes projets, je la combine avec d’autres fonctions de manipulation de chaînes. Voici les associations les plus courantes.
Strpos et substr : extraire une portion
La combinaison strpos + substr est probablement la plus fréquente. On localise d’abord la position, puis on extrait la sous-chaîne souhaitée.
<?php
$log = "[2026-07-12 14:30:00] ERREUR : connexion base refusée";
$posErreur = strpos($log, 'ERREUR');
if ($posErreur !== false) {
$message = substr($log, $posErreur);
echo $message; // ERREUR : connexion base refusée
}
?>
Strpos et explode : découper intelligemment
La fonction explode découpe une chaîne selon un délimiteur. En combinaison avec strpos, on peut vérifier la présence du délimiteur avant de découper, évitant ainsi des tableaux inattendus.
<?php
$donnee = "nom:prenom:age";
if (strpos($donnee, ':') !== false) {
$parties = explode(':', $donnee);
echo "Nom : " . $parties[0]; // nom
echo "Prénom : " . $parties[1]; // prenom
echo "Âge : " . $parties[2]; // age
}
?>
Strpos et strstr : récupérer tout à partir de l’occurrence
La fonction strstr retourne la portion de chaîne à partir de la première occurrence trouvée. Elle est parfois plus directe que la combinaison strpos + substr.
<?php
$email = "[email protected]";
$domaine = strstr($email, '@');
echo $domaine; // @web-city.fr
// Pour obtenir la partie AVANT le @
$utilisateur = strstr($email, '@', true);
echo $utilisateur; // contact
?>
Lorsque vous travaillez sur du formatage de données comme les dates SQL, ces combinaisons de fonctions de chaînes deviennent particulièrement précieuses pour parser et transformer les résultats.

Bonnes pratiques pour utiliser strpos en production
Après des années à utiliser strpos en php sur des projets en production, voici les règles que j’applique systématiquement.
Toujours utiliser la comparaison stricte
Je le répète car c’est la règle numéro un : utilisez === ou !== pour comparer le retour de strpos. Configurez votre linter (PHPStan ou Psalm) pour détecter les comparaisons lâches avec strpos. C’est un investissement qui évite des heures de débogage.
Typer les paramètres en PHP 8+
<?php
function rechercherMotCle(string $contenu, string $motCle): int|false
{
return strpos($contenu, $motCle);
}
?>
Le typage strict empêche les conversions implicites qui pouvaient causer des comportements inattendus dans les versions antérieures de PHP. Avant PHP 8, passer un entier comme needle provoquait une conversion en caractère ASCII, un comportement supprimé depuis.
Préférer str_contains pour les tests booléens
Si votre projet tourne sur PHP 8.0 ou supérieur, utilisez str_contains pour les simples vérifications de présence. Réservez strpos aux cas où vous avez réellement besoin de la position. Cela rend le code plus explicite et réduit les risques d’erreur.
Attention aux chaînes multibytes
Strpos travaille en octets, pas en caractères. Pour les chaînes contenant des caractères accentués ou des emojis encodés en UTF-8, la position retournée peut ne pas correspondre au nombre de caractères visibles. Utilisez mb_strpos() si vous manipulez du contenu multilingue.
<?php
$texte = "Hébergement web";
echo strpos($texte, 'bergement'); // 3 (position en octets, car é = 2 octets)
echo mb_strpos($texte, 'bergement'); // 2 (position en caractères)
?>
C’est un point crucial si vous développez des sites multilingues ou des applications comme celles qu’on peut mettre en place avec Docker pour le déploiement de projets internationaux.
Tableau comparatif des fonctions de recherche en PHP
Pour vous aider à choisir la bonne fonction selon votre besoin, voici un tableau synthétique que je garde toujours à portée de main.
| Fonction | Retour | Sensible à la casse | PHP minimum | Usage recommandé |
|---|---|---|---|---|
| strpos() | int ou false | Oui | PHP 4+ | Trouver la position d’une sous-chaîne |
| stripos() | int ou false | Non | PHP 5+ | Recherche insensible à la casse |
| strrpos() | int ou false | Oui | PHP 4+ | Trouver la dernière occurrence |
| strripos() | int ou false | Non | PHP 5+ | Dernière occurrence, insensible à la casse |
| str_contains() | bool | Oui | PHP 8.0+ | Tester la présence d’une sous-chaîne |
| str_starts_with() | bool | Oui | PHP 8.0+ | Vérifier le début d’une chaîne |
| str_ends_with() | bool | Oui | PHP 8.0+ | Vérifier la fin d’une chaîne |
| strstr() | string ou false | Oui | PHP 4+ | Extraire à partir de la première occurrence |
| mb_strpos() | int ou false | Oui | PHP 4+ | Position en caractères (multibyte) |
Erreurs fréquentes et comment les éviter
Au fil des années, j’ai identifié les erreurs les plus récurrentes chez les développeurs PHP concernant strpos. Les voici avec leurs solutions.
Erreur 1 : oublier la comparaison stricte
C’est l’erreur numéro un, déjà évoquée. La solution : toujours utiliser === ou !==. Ajoutez une règle dans votre PHPStan ou Psalm pour détecter automatiquement ce pattern.
Erreur 2 : inverser haystack et needle
<?php
// FAUX : les paramètres sont inversés
$pos = strpos('PHP', $longueChaine);
// CORRECT : la grande chaîne en premier
$pos = strpos($longueChaine, 'PHP');
?>
En PHP 8, passer les arguments dans le mauvais ordre génère un avertissement plus explicite, mais le résultat sera de toute façon incorrect. Pensez toujours à la métaphore : on cherche l’aiguille (needle) dans la botte de foin (haystack).
Erreur 3 : ignorer les caractères multibytes
Si votre application traite du contenu en français avec des accents, des caractères spéciaux ou du contenu en langues asiatiques, utilisez mb_strpos() plutôt que strpos. Les positions en octets ne correspondent pas aux positions en caractères pour les chaînes UTF-8.
Erreur 4 : utiliser strpos pour du pattern matching complexe
Strpos cherche une chaîne littérale. Si vous avez besoin de motifs avec des jokers ou des expressions régulières, utilisez preg_match(). L’expression régulière avec php match via preg_match est plus adaptée pour valider des formats complexes comme des numéros de téléphone ou des codes postaux.
<?php
// strpos ne peut pas faire cela
if (preg_match('/^[0-9]{5}$/', $codePostal)) {
echo "Code postal valide";
}
?>
Erreur 5 : ne pas gérer le cas de la chaîne vide
<?php
// En PHP 8 : strpos retourne 0 si needle est vide
var_dump(strpos('Bonjour', '')); // int(0)
// Avant PHP 8 : retournait false avec un warning
// Pensez à vérifier que la needle n'est pas vide
if ($needle !== '' && strpos($haystack, $needle) !== false) {
// Traitement
}
?>
Ce type de vérification défensive est particulièrement important quand la valeur de recherche provient d’une saisie utilisateur, par exemple dans un champ de recherche de votre boutique e-commerce.
Pour aller plus loin dans la gestion des alertes et du débogage côté client, je vous recommande de consulter mon article sur le fonctionnement d’alert() en JavaScript, qui complète bien cette approche côté front.
À retenir
- Utilisez toujours === false ou !== false pour comparer le retour de strpos, jamais
== - Passez à str_contains() pour les simples tests de présence si votre projet est en PHP 8+
- Préférez stripos() quand vous traitez des données saisies par l’utilisateur dont la casse est imprévisible
- Utilisez mb_strpos() dès que votre contenu contient des caractères accentués ou multibytes
- Configurez PHPStan ou Psalm pour détecter automatiquement les comparaisons lâches avec strpos
Questions fréquentes
Que fait la fonction strpos ?
La fonction strpos recherche la première occurrence d’une sous-chaîne (needle) dans une chaîne principale (haystack). Elle retourne la position sous forme d’entier (en commençant à 0) si la sous-chaîne est trouvée, ou false si elle est absente. C’est l’une des fonctions de manipulation de chaînes les plus utilisées en PHP.
Quelle est la différence entre strpos et stripos en PHP ?
La seule différence entre strpos et stripos est la sensibilité à la casse. Strpos distingue les majuscules des minuscules : chercher « php » dans « PHP est génial » retourne false. Stripos ignore la casse : la même recherche retourne 0. Les deux fonctions partagent la même syntaxe et les mêmes paramètres.
Quel est le rôle de stripos en PHP ?
Stripos effectue une recherche de sous-chaîne insensible à la casse. Son rôle principal est de localiser une sous-chaîne sans se préoccuper de la différence entre majuscules et minuscules. Elle est particulièrement utile pour traiter les saisies utilisateur, analyser des en-têtes HTTP ou filtrer du contenu dont la casse n’est pas normalisée.
Quelle est la différence entre str_contains et strpos en PHP ?
Str_contains (disponible depuis PHP 8.0) retourne un booléen (true ou false), tandis que strpos retourne la position (un entier) ou false. Si vous avez simplement besoin de savoir si une sous-chaîne existe, str_contains est plus lisible et élimine le risque de bug lié à la comparaison stricte. Si vous avez besoin de connaître la position exacte, strpos reste indispensable.
Comment chercher toutes les occurrences d’un mot avec strpos ?
Pour trouver toutes les occurrences, utilisez une boucle while avec le paramètre offset. À chaque itération, passez la position trouvée + la longueur du mot recherché comme nouvel offset. La boucle s’arrête quand strpos retourne false. Cette technique permet de collecter toutes les positions dans un tableau.
Strpos fonctionne-t-elle correctement avec les caractères accentués ?
Strpos travaille en octets, pas en caractères. Les caractères accentués (é, è, ê) occupent 2 octets en UTF-8, ce qui peut décaler les positions. Pour obtenir des positions correctes en nombre de caractères, utilisez mb_strpos() qui gère nativement l’encodage multibyte.
Peut-on utiliser strpos avec des expressions régulières ?
Non, strpos recherche uniquement des chaînes littérales. Pour des recherches par motif (pattern matching), utilisez preg_match() qui accepte les expressions régulières PCRE. Strpos est cependant plus performante que preg_match pour les recherches de chaînes fixes.
Ingénieur système et expert hébergement web. Fondateur de web-city.fr, il partage guides pratiques, comparatifs objectifs et outils gratuits pour choisir le bon hébergeur et créer son site WordPress.