substr_compare()
Die PHP-Funktion substr_compare() vergleicht zwei Zeichenketten ab einer bestimmten Position bis zu einer angegebenen Länge.
Einführung
Die Funktion substr_compare() vergleicht einen Teil eines Strings mit einem anderen String, beginnend an einem bestimmten Offset. Sie funktioniert wie der Vergleich eines Teilstrings von $main_str mit $str — ohne dass man zuerst substr() aufrufen muss, um den String auszuschneiden. Das macht sie zur idiomatischen, allokationsfreien Methode, um Fragen wie "Beginnt dieser String mit X?" oder "Endet dieser String mit Y?" in älteren PHP-Versionen zu beantworten.
Dieses Kapitel erläutert die Parameter, die Bedeutung des Rückgabewerts sowie häufige Muster (Präfix-Prüfung, Suffix-Prüfung, Groß-/Kleinschreibung ignorieren), bei denen substr_compare() besonders nützlich ist.
Syntax
substr_compare(
string $haystack,
string $needle,
int $offset,
?int $length = null,
bool $case_insensitive = false
): intHinweis: Der Parameter
$lengthist optional. In PHP 8+ ist er explizit als nullable typisiert (?int); wirdnullübergeben (oder weggelassen), wird bis zum Ende von$haystackverglichen.
| Parameter | Beschreibung |
|---|---|
$haystack | Der Haupt-String. Der Vergleich liest einen Ausschnitt aus diesem String. |
$needle | Der String, der mit dem Ausschnitt aus $haystack verglichen wird. |
$offset | Die Position in $haystack, an der der Vergleich beginnt. Ein negativer Wert zählt vom Ende von $haystack zurück. |
$length | Wie viele Zeichen verglichen werden. Bei null wird das Maximum aus dem verbleibenden $haystack und dem gesamten $needle verwendet. |
$case_insensitive | Wenn true, wird die Groß-/Kleinschreibung ignoriert ("A" ist gleich "a"). Standardmäßig false. |
Rückgabewert
substr_compare() gibt einen int zurück:
0— die verglichenen Teile sind gleich.- eine negative Zahl — der Ausschnitt aus
$haystackist kleiner als$needle(sortiert früher). - eine positive Zahl — der Ausschnitt aus
$haystackist größer als$needle(sortiert später).
Das Vorzeichen ist entscheidend; die genaue Größe ist implementierungsabhängig und sollte nicht als verlässlich angesehen werden. Um auf Gleichheit zu prüfen, vergleicht man explizit mit 0: substr_compare(...) === 0.
Einfaches Beispiel
Hier vergleichen wir die ersten strlen($string2) (6) Zeichen von "Hello World!" mit "Hello!". Das sechste Zeichen ist ein Leerzeichen (" ") im ersten String, aber ein Ausrufezeichen ("!") im zweiten; ein Leerzeichen (ASCII 32) kommt vor ! (ASCII 33), daher gibt die Funktion eine negative ganze Zahl (-1) zurück.
Prüfen, ob ein String mit einem Präfix beginnt
Ein Vergleich bei Offset 0 mit $length gleich der Präfixlänge ist ein sauberer "starts with"-Test:
<?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)Ab PHP 8.0+ kann die eingebaute Funktion
str_starts_with()verwendet werden.substr_compare()bleibt nützlich auf älteren Laufzeiten und wenn zusätzlich Groß-/Kleinschreibung ignoriert werden soll.
Prüfen, ob ein String mit einem Suffix endet
Ein negativer Offset zählt vom Ende des Strings, was "ends with"-Prüfungen mühelos macht — die Position muss nicht selbst berechnet werden:
<?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)Groß-/Kleinschreibung ignorieren
Das fünfte Argument auf true setzen, um die Groß-/Kleinschreibung zu ignorieren:
<?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 ignoredFallstricke
- Offset außerhalb des Bereichs. Ein positiver
$offset, der größer als die Länge von$haystackist, löst in PHP 8+ einenValueErroraus (in PHP 7 eine Warnung mit Rückgabe vonfalse). Offsets gegenstrlen($haystack)prüfen, wenn sie aus Benutzereingaben stammen. $lengthgrößer als der verbleibende Rest. Überschreitet$lengthdie verfügbaren Zeichen, werden nur die verfügbaren Zeichen verglichen — die Funktion gibt keinen Fehler zurück, sie vergleicht einfach weniger.- Byte-basiert, nicht multibyte-fähig.
substr_compare()arbeitet auf Bytes. Bei UTF-8-Text, bei dem ein Zeichen mehrere Bytes umfassen kann, sind Offsets und Längen Byte-Offsets, keine Zeichen-Offsets.
Verwandte Funktionen
strcmp()— binärsicherer Vergleich zweier vollständiger Strings.strncmp()— vergleicht nur die ersten n Zeichen zweier Strings.strcasecmp()— Groß-/Kleinschreibung ignorierender Vergleich zweier vollständiger Strings.substr()— extrahiert einen Teil eines Strings.
Fazit
substr_compare() vergleicht einen Ausschnitt eines Strings mit einem anderen, ohne ihn vorher zu extrahieren, was ihn effizient für Präfix- und Suffix-Prüfungen macht. Daran denken, das Ergebnis auf 0 für Gleichheit zu testen, einen negativen $offset für "ends with"-Prüfungen zu verwenden und true als letztes Argument zu übergeben, wenn die Groß-/Kleinschreibung ignoriert werden soll.