strpos en PHP : trouver la position d’un texte dans une chaîne

Tu cherches où apparaît un mot dans une phrase ? La fonction strpos en PHP te donne la position exacte d’un texte dans une chaîne. Tu peux vérifier la présence d’un caractère, découper une URL ou valider un email.

Cette fonction existe depuis PHP 4 . Elle fonctionne dans toutes les versions modernes du langage.

Signature de la fonction

strpos(string $texte, string $recherche, int $position_depart = 0): int|false

Explication des paramètres :

  • $texte (obligatoire) : la chaîne dans laquelle tu cherches.
  • $recherche (obligatoire) : le texte que tu veux localiser.
  • $position_depart (optionnel, 0 par défaut) : la position où commencer la recherche.

Valeur de retour :

  • Un entier (position trouvée, première lettre à l’index 0).
  • false si le texte recherché n’existe pas.

Exemples pour la fonction strpos en PHP

Exemple 1 : Trouver un mot simple

$phrase = "Apprendre le PHP pas à pas";
$position = strpos($phrase, "PHP");
echo $position;
// 13

La fonction retourne 13. Le mot « PHP » commence au 13ᵉ caractère (en comptant depuis 0).

Exemple 2 : Trouver un caractère

$email = "contact@exemple.com";
$position_arobase = strpos($email, "@");
echo $position_arobase;
// 7

Tu obtiens la position du @. Tu peux ensuite découper l’email en deux parties.

Exemple 3 : Recherche qui échoue

$texte = "Bonjour le monde";
$resultat = strpos($texte, "x");
var_dump($resultat);
// false

La fonction retourne false si le texte recherché n’existe pas dans la chaîne.

Exemple 4 : Rechercher après une position

$phrase = "PHP est un langage PHP très utilisé";
$premier = strpos($phrase, "PHP");        // 0
$second  = strpos($phrase, "PHP", 1);     // 18

Le troisième paramètre permet de continuer la recherche après la première occurrence trouvée.

Exemple 5 : Cas réels

Vérifier présence d’un protocole :

$url = "https://mon-site.com/page";
if (strpos($url, "https://") === 0) {
    echo "URL sécurisée";
}

Extraire domaine d’un email :

$email = "user@exemple.com";
$pos = strpos($email, "@");
$domaine = substr($email, $pos + 1);
echo $domaine;
// "exemple.com"

Trouver extension de fichier :

$fichier = "photo.jpg";
$pos_point = strpos($fichier, ".");
$extension = substr($fichier, $pos_point + 1);
echo $extension;
// "jpg"

Cas d’usage pratiques

  • Vérifier si une chaîne contient un mot clé (« http », « @ », « .php »).
  • Découper une chaîne en deux parties (avant/après un séparateur).
  • Valider la structure d’un email ou d’une URL.
  • Chercher un token ou un paramètre dans une query string.
  • Parser un chemin de fichier pour extraire le dossier ou l’extension.

Bonnes pratiques / pièges

Piège 1 : Confusion entre 0 et false

$texte = "PHP est génial";
$pos = strpos($texte, "PHP");

// ❌ Mauvais test
if ($pos == false) {
    echo "Pas trouvé";
}
// Problème : 0 == false est vrai en PHP

// ✅ Bon test
if ($pos === false) {
    echo "Pas trouvé";
}

La position 0 est valide. Elle indique que le texte commence au début. Tu dois utiliser === false pour tester l’absence.

Piège 2 : Sensibilité à la casse

$texte = "Bonjour tout le monde";
$pos1 = strpos($texte, "bonjour");  // false (majuscule différente)
$pos2 = strpos($texte, "Bonjour");  // 0 (correspondance exacte)

// ✅ Recherche insensible à la casse
$pos3 = stripos($texte, "bonjour"); // 0

La fonction strpos() respecte la casse. La fonction stripos() l’ignore.

Piège 3 : Types non chaînes

// ❌ Pas clair
$pos = strpos(12345, "3");  // PHP convertit en "12345", mais c'est flou

// ✅ Explicite
$nombre = 12345;
$pos = strpos((string)$nombre, "3");

Tu dois passer des chaînes pour garder un code lisible.

Piège 4 : Rechercher plusieurs occurrences

$texte = "PHP, PHP, PHP";
$pos = 0;
while (($pos = strpos($texte, "PHP", $pos)) !== false) {
    echo "Trouvé à : $pos\n";
    $pos++; // Continue après la position trouvée
}
// "Trouvé à : 0"
// "Trouvé à : 5"
// "Trouvé à : 10"

Tu dois incrémenter la position pour éviter une boucle infinie.

Informations cruciales supplémentaires

Différence strpos() vs stripos() vs strrpos()

FonctionComportementCas d’usage
strpos()Première occurrence, sensible casseRecherche standard
stripos()Première occurrence, insensible casseRecherche flexible
strrpos()Dernière occurrence, sensible casseTrouver dernier point/slash
$texte = "PHP est cool, PHP est puissant";
strpos($texte, "PHP");   // 0 (première)
strrpos($texte, "PHP");  // 14 (dernière)

Gestion encodage UTF-8

$texte_utf8 = "Développeur café";
$pos1 = strpos($texte_utf8, "café");     // Position en octets
$pos2 = mb_strpos($texte_utf8, "café");  // Position en caractères

// ✅ UTF-8 sûr
if (mb_strpos($texte_utf8, "café") !== false) {
    echo "Trouvé";
}

La fonction strpos() compte les octets. La fonction mb_strpos() compte les caractères UTF-8.

Comportement avec chaîne vide

strpos("Bonjour", "");   // 0 (trouvé au début)
strpos("", "test");      // false (rien à chercher)

Une recherche de chaîne vide retourne toujours 0.

Performance et limites

Points forts :

  • Très rapide sur chaînes courtes et moyennes (<100 Ko).
  • Efficace pour validation simple (présence @, protocole http).

Limites :

  • Chaînes énormes (>10 Mo) : impact mémoire notable.
  • UTF-8 basique : compte les octets, pas les caractères.
  • Emojis/caractères multioctets : positions incorrectes (utilise mb_strpos()).
  • PHP 8.0+ : paramètres strictement typés (string attendu).

Alternatives

BesoinFonction
Insensible cassestripos()
Dernière occurrencestrrpos()
UTF-8 sûrmb_strpos()
Vérifier présencestr_contains() (PHP 8+)
Remplacer textestr_replace()
Découper chaîneexplode()

Historique et évolutions de la fonction

PHP 8.0 a introduit des changements importants pour strpos().

Nouvelle fonction str_contains() (PHP 8.0+)

// ❌ Ancien code (avant PHP 8)
if (strpos($texte, "PHP") !== false) {
    echo "Contient PHP";
}

// ✅ PHP 8.0+ : plus lisible
if (str_contains($texte, "PHP")) {
    echo "Contient PHP";
}

Avantage : str_contains() retourne directement un booléen. Tu évites la confusion === false.

Nouvelles fonctions associées PHP 8.0

// Vérifier début de chaîne
str_starts_with("https://site.com", "https://");  // true

// Vérifier fin de chaîne
str_ends_with("fichier.php", ".php");  // true

Migration recommandée : sur PHP 8+, privilégie ces fonctions pour la lisibilité.


Différence entre strpos() et strstr()

Point clé : strpos() retourne une position, strstr() retourne la portion de chaîne.

$email = "contact@exemple.com";

// strpos : position du @
$position = strpos($email, "@");  // 7

// strstr : tout après le @
$domaine = strstr($email, "@");   // "@exemple.com"

Cas d’usage comparés

$url = "https://mon-site.com/page?id=5";

// Extraire avec strpos + substr
$pos = strpos($url, "?");
$query = substr($url, $pos + 1);  // "id=5"

// Extraire avec strstr (plus direct)
$query = strstr($url, "?");       // "?id=5"
$query = ltrim($query, "?");      // "id=5"

Quand utiliser quoi :

  • strpos() : tu as besoin de la position numérique.
  • strstr() : tu veux extraire la portion après le texte.

Comportement avec needle (recherche) plus long que haystack (texte)

$court = "PHP";
$long = "Langage de programmation PHP";

// Recherche normale
strpos($long, $court);  // 24

// ⚠️ Recherche inversée (needle > haystack)
strpos($court, $long);  // false (logique)

// ❌ Erreur fréquente débutants
$fichier = "index";
$extension = ".php";
if (strpos($extension, $fichier) !== false) {
    // Ne sera JAMAIS vrai (ordre inversé)
}

// ✅ Correct
if (strpos($fichier, $extension) !== false) {
    echo "Fichier PHP détecté";
}

Validation arguments

// PHP 8.0+ : erreurs strictes
strpos("test", null);   // TypeError
strpos(null, "test");   // TypeError

// ✅ Validation avant
if (is_string($texte) && is_string($recherche)) {
    $pos = strpos($texte, $recherche);
}

Performance comparative

// Test : vérifier présence d'un mot dans 100 000 chaînes

// Méthode 1 : strpos
for ($i = 0; $i < 100000; $i++) {
    if (strpos($texte, "PHP") !== false) { }
}
// ~50ms

// Méthode 2 : preg_match (regex)
for ($i = 0; $i < 100000; $i++) {
    if (preg_match('/PHP/', $texte)) { }
}
// ~150ms (3x plus lent)

// Méthode 3 : str_contains (PHP 8+)
for ($i = 0; $i < 100000; $i++) {
    if (str_contains($texte, "PHP")) { }
}
// ~45ms (légèrement plus rapide)

Recommandation : strpos() reste très performante, mais str_contains() est optimisée en PHP 8+.

retour à la liste des fonctions

Sources : php.net

Cours

Variables et types

Manipulation de chaînes

Tableaux

Fichiers et système

Sécurité, session et cookie