Introduction : la question qui taraude tout développeur PHP
\n\nImaginez la situation : vous codez en PHP et devez vérifier si une chaîne contient un mot précis. Rien de plus simple, non ? Pourtant, en consultant Stack Overflow, vous découvrez que cette question cumule des milliers de vues et des dizaines de réponses. Les développeurs confondent strpos, utilisent preg_match alors qu'une fonction simple suffit, et tombent dans les pièges de la casse et des encodages. Aujourd'hui, nous ne nous contenterons pas de donner une réponse toute faite — nous allons soulever le capot de PHP et comprendre le fonctionnement interne de ces fonctions. Prêt ? C'est parti !
La méthode classique : strpos et ses pièges
\n\nLa réponse la plus populaire sur Stack Overflow est d'utiliser strpos. Cette fonction native de PHP recherche la position de la première occurrence d'une sous-chaîne. Mais attention : les débutants écrivent souvent ceci :
$string = "Bonjour, le monde !";\n$word = "monde";\nif (strpos($string, $word)) {\n echo "Mot trouvé !";\n} else {\n echo "Mot non trouvé !";\n}\n\n\nEt cela fonctionne... jusqu'à ce que le mot se trouve au début de la chaîne. Pourquoi ? Parce que strpos retourne une position (un nombre), et si le mot est à la position 0, PHP interprète 0 comme false dans la condition if. La bonne façon de faire :
if (strpos($string, $word) !== false) {\n echo "Mot trouvé !";\n}\n\n\nComment fonctionne strpos sous le capot ?
\n\nLorsque vous appelez strpos, PHP utilise en interne un algorithme de recherche de sous-chaîne. Dans les versions modernes de PHP (7.x et 8.x), un algorithme optimisé basé sur l'algorithme de Boyer-Moore-Horspool est employé. Au lieu de parcourir les caractères un par un, il utilise une table de "mauvais caractères" pour sauter des blocs entiers de texte si le caractère recherché ne correspond pas. Cela rend la recherche très rapide, surtout pour les longues chaînes.
Mais attention : strpos est sensible à la casse. "Monde" et "monde" sont considérés comme différents. Pour une recherche insensible à la casse, utilisez stripos, son équivalent qui ignore la casse.
La méthode moderne : str_contains (PHP 8.0+)
\n\nDepuis PHP 8.0, la fonction tant attendue str_contains est disponible. Elle résout définitivement le problème de strpos. Au lieu de vérifier une position, elle retourne simplement true ou false :
$string = "Bonjour, le monde !";\n$word = "monde";\nif (str_contains($string, $word)) {\n echo "Mot trouvé !";\n}\n\n\nQue contient str_contains en interne ?
\n\nSous le capot, str_contains est une surcouche de strpos. Elle appelle la même fonction de recherche interne, mais convertit automatiquement le résultat en valeur booléenne. Cela rend le code plus propre et plus sûr. Cependant, si vous travaillez avec d'anciennes versions de PHP (7.4 et inférieures), str_contains n'est pas disponible — vous devrez utiliser strpos avec la vérification !== false.
Un outil puissant : les expressions régulières avec preg_match
\n\nParfois, vous devez vérifier non seulement la présence d'un mot, mais tout un groupe de mots ou un motif. C'est là que preg_match entre en jeu. Les expressions régulières vous offrent un super-pouvoir : rechercher des mots entiers (pour que "monde" ne corresponde pas à "mondial"), ignorer la casse, chercher par limites de mots, et bien plus.
$string = "Bonjour, mondial !";\n$word = "monde";\nif (preg_match("/\\b" . preg_quote($word, '/') . "\\b/ui", $string)) {\n echo "Mot trouvé !";\n} else {\n echo "Mot non trouvé !";\n}\n\n\nIci, \\b représente la limite de mot, et le drapeau u active le support Unicode (pour gérer correctement les caractères accentués). Le drapeau i rend la recherche insensible à la casse. La fonction preg_quote échappe les caractères spéciaux, si nécessaire.