W3docs

substr_compare()

The substr_compare() function in PHP is used to compare two strings from a specified start position up to a specified length. This function is useful when

Introduction

The substr_compare() function compares a portion of one string with another string, starting at a given offset. It works like comparing a substring of $main_str against $str — but without you having to call substr() first to slice the string out. That makes it the idiomatic, allocation-free way to answer questions such as "does this string start with X?" or "does this string end with Y?" in older PHP versions.

This chapter explains the parameters, the meaning of the return value, and the common patterns (prefix checks, suffix checks, case-insensitive comparison) where substr_compare() shines.

Syntax

substr_compare(
    string $haystack,
    string $needle,
    int $offset,
    ?int $length = null,
    bool $case_insensitive = false
): int

Note: The $length parameter is optional. In PHP 8+ it is explicitly typed as nullable (?int); passing null (or omitting it) compares to the end of $haystack.

ParameterDescription
$haystackThe main string. The comparison reads a slice of this string.
$needleThe string compared against the slice of $haystack.
$offsetWhere in $haystack the comparison starts. A negative value counts back from the end of $haystack.
$lengthHow many characters to compare. If null, the longer of the remaining $haystack and the whole $needle is used.
$case_insensitiveIf true, letter case is ignored ("A" equals "a"). Defaults to false.

Return value

substr_compare() returns an int:

  • 0 — the compared portions are equal.
  • a negative number — the slice of $haystack is less than $needle (sorts earlier).
  • a positive number — the slice of $haystack is greater than $needle (sorts later).

The sign is what matters; the exact magnitude is implementation-defined and should not be relied on. To test for equality, compare against 0 explicitly: substr_compare(...) === 0.

Basic example

php— editable, runs on the server

Here we compare the first strlen($string2) (6) characters of "Hello World!" against "Hello!". The sixth character is a space (" ") in the first string but an exclamation mark ("!") in the second; a space (ASCII 32) sorts before ! (ASCII 33), so the function returns a negative integer (-1).

Checking if a string starts with a prefix

Comparing at offset 0 with $length equal to the prefix length is a clean "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)

On PHP 8.0+ you can use the built-in str_starts_with() instead. substr_compare() remains useful on older runtimes and when you also need case-insensitivity.

Checking if a string ends with a suffix

A negative offset counts from the end of the string, which makes "ends with" checks effortless — you don't need to compute the position yourself:

<?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)

Case-insensitive comparison

Set the fifth argument to true to ignore letter case:

<?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 ignored

Gotchas

  • Offset out of range. A positive $offset greater than the length of $haystack raises a ValueError in PHP 8+ (a warning returning false in PHP 7). Validate offsets against strlen($haystack) when they come from user input.
  • $length longer than what remains. If $length exceeds the available characters, only the available characters are compared — the function does not error, it simply compares less.
  • Byte-based, not multibyte-aware. substr_compare() works on bytes. For UTF-8 text where one character may span several bytes, offsets and lengths are byte offsets, not character offsets.
  • strcmp() — binary-safe comparison of two whole strings.
  • strncmp() — compares only the first n characters of two strings.
  • strcasecmp() — case-insensitive comparison of two whole strings.
  • substr() — extract a portion of a string.

Conclusion

substr_compare() compares a slice of one string against another without first extracting it, which makes it efficient for prefix and suffix checks. Remember to test the result against 0 for equality, use a negative $offset for "ends with" tests, and pass true as the last argument when case should be ignored.

Practice

Practice
What does the PHP function substr_compare() do?
What does the PHP function substr_compare() do?
Was this page helpful?