substr_compare()
La fonction substr_compare() en PHP compare deux chaînes à partir d'une position de départ spécifiée jusqu'à une longueur donnée.
Introduction
La fonction substr_compare() compare une portion d'une chaîne avec une autre chaîne, en commençant à un décalage donné. Elle fonctionne comme la comparaison d'une sous-chaîne de $main_str avec $str — sans avoir à appeler substr() au préalable pour extraire la sous-chaîne. C'est ainsi la façon idiomatique et sans allocation mémoire de répondre à des questions telles que « cette chaîne commence-t-elle par X ? » ou « cette chaîne se termine-t-elle par Y ? » dans les anciennes versions de PHP.
Ce chapitre explique les paramètres, la signification de la valeur de retour, et les patterns courants (vérification de préfixe, vérification de suffixe, comparaison insensible à la casse) où substr_compare() excelle.
Syntaxe
substr_compare(
string $haystack,
string $needle,
int $offset,
?int $length = null,
bool $case_insensitive = false
): intRemarque : Le paramètre
$lengthest optionnel. En PHP 8+, il est explicitement typé comme nullable (?int) ; passernull(ou l'omettre) compare jusqu'à la fin de$haystack.
| Paramètre | Description |
|---|---|
$haystack | La chaîne principale. La comparaison lit une tranche de cette chaîne. |
$needle | La chaîne comparée à la tranche de $haystack. |
$offset | L'endroit dans $haystack où la comparaison commence. Une valeur négative compte depuis la fin de $haystack. |
$length | Le nombre de caractères à comparer. Si null, la plus longue entre la partie restante de $haystack et l'intégralité de $needle est utilisée. |
$case_insensitive | Si true, la casse est ignorée ("A" est égal à "a"). Par défaut à false. |
Valeur de retour
substr_compare() retourne un int :
0— les portions comparées sont égales.- un nombre négatif — la tranche de
$haystackest inférieure à$needle(se trie avant). - un nombre positif — la tranche de
$haystackest supérieure à$needle(se trie après).
C'est le signe qui importe ; la magnitude exacte est définie par l'implémentation et ne doit pas être utilisée comme référence. Pour tester l'égalité, comparez explicitement à 0 : substr_compare(...) === 0.
Exemple de base
Ici, nous comparons les strlen($string2) (6) premiers caractères de "Hello World!" avec "Hello!". Le sixième caractère est un espace (" ") dans la première chaîne mais un point d'exclamation ("!") dans la seconde ; un espace (ASCII 32) se trie avant ! (ASCII 33), donc la fonction retourne un entier négatif (-1).
Vérifier si une chaîne commence par un préfixe
Comparer à l'offset 0 avec $length égal à la longueur du préfixe est un test propre pour « commence par » :
<?php
function startsWith(string $haystack, string $prefix): bool
{
return substr_compare($haystack, $prefix, 0, strlen($prefix)) === 0;
}
var_dump(startsWith("php-fpm", "php")); // bool(true)
var_dump(startsWith("python", "php")); // bool(false)Sur PHP 8.0+, vous pouvez utiliser la fonction intégrée
str_starts_with()à la place.substr_compare()reste utile sur les runtimes plus anciens et lorsque vous avez également besoin d'insensibilité à la casse.
Vérifier si une chaîne se termine par un suffixe
Un offset négatif compte depuis la fin de la chaîne, ce qui rend les vérifications « se termine par » simples — vous n'avez pas besoin de calculer la position vous-même :
<?php
function endsWith(string $haystack, string $suffix): bool
{
return substr_compare($haystack, $suffix, -strlen($suffix)) === 0;
}
var_dump(endsWith("report.pdf", ".pdf")); // bool(true)
var_dump(endsWith("report.txt", ".pdf")); // bool(false)Comparaison insensible à la casse
Définissez le cinquième argument à true pour ignorer la casse :
<?php
$sensitive = substr_compare("Hello", "hello", 0);
$insensitive = substr_compare("Hello", "hello", 0, null, true);
echo $sensitive; // non-zero: 'H' and 'h' differ
echo PHP_EOL;
echo $insensitive; // 0: equal when case is ignoredPièges
- Offset hors limites. Un
$offsetpositif supérieur à la longueur de$haystacklève uneValueErroren PHP 8+ (un avertissement retournantfalseen PHP 7). Validez les offsets par rapport àstrlen($haystack)quand ils proviennent d'une entrée utilisateur. $lengthsupérieur à ce qui reste. Si$lengthdépasse les caractères disponibles, seuls les caractères disponibles sont comparés — la fonction ne génère pas d'erreur, elle compare simplement moins.- Basé sur les octets, pas sur le multioctet.
substr_compare()travaille sur les octets. Pour le texte UTF-8 où un caractère peut occuper plusieurs octets, les offsets et les longueurs sont des décalages d'octets, pas de caractères.
Fonctions associées
strcmp()— comparaison binaire sûre de deux chaînes entières.strncmp()— compare uniquement les n premiers caractères de deux chaînes.strcasecmp()— comparaison insensible à la casse de deux chaînes entières.substr()— extrait une portion d'une chaîne.
Conclusion
substr_compare() compare une tranche d'une chaîne avec une autre sans d'abord l'extraire, ce qui la rend efficace pour les vérifications de préfixe et de suffixe. N'oubliez pas de tester le résultat contre 0 pour l'égalité, d'utiliser un $offset négatif pour les tests « se termine par », et de passer true comme dernier argument quand la casse doit être ignorée.