PHP substr_compare() Function

PHP

PHP substr_compare() - Compare Substrings

Learn PHP substr_compare() function. Binary safe comparison of substrings from positions.

Introduction

The substr_compare() function in PHP is a powerful tool for comparing specific portions or segments of two strings. Unlike a simple string comparison that evaluates entire strings, substr_compare() lets you focus on substrings starting at defined offsets. This is especially useful in scenarios where you want to verify parts of strings—such as prefixes, suffixes, or any segment within—without extracting those substrings manually.

In this tutorial, we'll cover how to use substr_compare(), explore example use cases, go over best practices, common mistakes to avoid, and even prepare you for interview questions that specifically relate to this function.

Prerequisites

  • Basic knowledge of PHP and string handling.
  • PHP installed in your development environment (PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8 supported).
  • A code editor or IDE to write and run PHP code.

Setup Steps

  1. Ensure PHP is installed and running on your system. You can verify with:
    php -v
  2. Create a new PHP file named substr_compare_example.php.
  3. Use any local or online PHP environment to execute your script (like XAMPP, MAMP, or an online PHP sandbox).

Understanding substr_compare()

substr_compare() compares two strings from specified start positions with the option to specify the length of the comparison, and whether the comparison is case-insensitive.

Function signature:

int substr_compare ( string $main_str , string $str , int $offset [, int $length = NULL [, bool $case_insensitivity = FALSE ]] )
  • $main_str: The main string in which you want to compare a substring.
  • $str: The string to compare with the substring of $main_str.
  • $offset: Start position in $main_str to begin comparison. Negative values count from the end.
  • $length (optional): Number of characters to compare. If omitted, compares to the end of the string.
  • $case_insensitivity (optional): If set to TRUE, comparison is case-insensitive.

Return values

  • 0: If the specified portions of the strings are equal.
  • < 0: If the substring from $main_str is less than $str.
  • > 0: If the substring from $main_str is greater than $str.

Examples

Example 1: Basic substring comparison

<?php
$main_str = "Hello World!";
$str = "World";
$offset = 6;

$result = substr_compare($main_str, $str, $offset);

if ($result === 0) {
    echo "Substrings are equal.";
} elseif ($result < 0) {
    echo "Main string substring is less than compared string.";
} else {
    echo "Main string substring is greater than compared string.";
}
?>

Output: Substrings are equal.

Explanation: Starting from position 6 in $main_str ("Hello World!"), the substring "World!" is compared to "World". Since the comparison length is by default to the end, and the beginning matches, the result is zero.

Example 2: Comparing fixed length with case sensitivity

<?php
$main_str = "hello world";
$str = "HELLO";
$offset = 0;
$length = 5;
$case_insensitive = false;

$result = substr_compare($main_str, $str, $offset, $length, $case_insensitive);
echo "Case sensitive comparison: " . $result . "\n";

$case_insensitive = true;
$result = substr_compare($main_str, $str, $offset, $length, $case_insensitive);
echo "Case insensitive comparison: " . $result . "\n";
?>

Output:

Case sensitive comparison: 32
Case insensitive comparison: 0

Here, the first comparison detects that lowercase "hello" differs from uppercase "HELLO" (difference in ASCII values). When case is ignored ($case_insensitive = true), the substrings match exactly.

Example 3: Negative offset usage

<?php
$main_str = "abcdefg";
$str = "efg";
$offset = -3; // Start 3 characters from the end

if (substr_compare($main_str, $str, $offset) === 0) {
    echo "The end of the string matches 'efg'.";
} else {
    echo "No match found.";
}
?>

Output: The end of the string matches 'efg'.

Best Practices

  • Use substr_compare() when you want to compare parts of strings efficiently without extracting substrings.
  • Be mindful of the offset direction; remember negative offsets start counting from the string’s end.
  • Specify length where applicable to avoid unexpected matches when part of the substring contains extra characters.
  • Use the $case_insensitivity flag if you expect case insensitivity in your comparisons.
  • Always check the return value precisely (=== 0) to avoid confusion with truthy/falsy results.

Common Mistakes

  • Forgetting that the $offset is zero-based and negative offsets count from the end.
  • Not using the optional $length argument, leading to comparing till the end of $main_str unintentionally.
  • Confusing the order of arguments, especially $main_str and $str.
  • Ignoring case sensitivity when it's significant in your logic.
  • Testing result with loose equality instead of strict equality.

Interview Questions

Junior Level

  • Q1: What does substr_compare() do in PHP?
    A: It compares a substring of one string to another string starting at a specified position.
  • Q2: What is the significance of the $offset parameter?
    A: It specifies the position in the main string from where comparison starts.
  • Q3: What value does substr_compare() return when substrings are equal?
    A: It returns 0.
  • Q4: How can you perform a case-insensitive substring comparison using substr_compare()?
    A: By setting the fifth parameter $case_insensitivity to TRUE.
  • Q5: Can the $offset parameter be negative? What does that imply?
    A: Yes, a negative $offset starts the comparison that many characters from the end of the string.

Mid Level

  • Q1: What happens if you omit the $length parameter in substr_compare()?
    A: It compares the substring from $offset in $main_str to the end of the string against $str.
  • Q2: How does substr_compare() handle multibyte or Unicode characters?
    A: It is binary safe but not multibyte-safe; use multibyte functions like mb_substr_compare() if working with multibyte encodings.
  • Q3: Can substr_compare() be used to check if one string starts with another? How?
    A: Yes, by setting $offset=0 and $length to the length of the string to check a prefix match.
  • Q4: How would you check if a string ends with another using substr_compare()?
    A: Pass a negative $offset equal to the length of the substring to check, and compare up to that substring length.
  • Q5: What does a negative return value from substr_compare() signify?
    A: The substring from $main_str is less than the comparison string $str.

Senior Level

  • Q1: Explain the binary safety of substr_compare() and why it matters.
    A: It compares strings byte-by-byte without interpreting encoding, ensuring accurate comparison of any binary data, but requiring care when handling multibyte encodings.
  • Q2: How would you implement a UTF-8 safe substring comparison similar to substr_compare()?
    A: By using mb_substr() to extract substrings and then comparing with mb_strcasecmp() or similar multibyte-safe functions.
  • Q3: What are the performance implications of using substr_compare() versus manually extracting substrings and comparing?
    A: substr_compare() avoids allocating new substring memory, offering better performance and less memory consumption.
  • Q4: Discuss how negative offsets in substr_compare() might create bugs if not handled correctly in string boundary checks.
    A: Negative offsets counting from the end can cause unexpected behavior or warnings if their magnitude exceeds string length—proper validation should be done before calling.
  • Q5: In a multithreaded PHP environment with shared strings, how does substr_compare() behave?
    A: Since PHP strings are immutable, substr_compare() safely operates on copies or references without race conditions, making it thread-safe inherently.

Frequently Asked Questions (FAQ)

Q: Is substr_compare() safe to use with multibyte strings?

A: It is binary safe but not multibyte safe. For UTF-8 or other multibyte encodings, use multibyte string functions like mb_substr() combined with proper comparison functions.

Q: How can I check if a string starts with another string using substr_compare()?

A: Use substr_compare($main_str, $prefix, 0, strlen($prefix)) === 0 to verify that $main_str starts exactly with $prefix.

Q: What if the offset is larger than the string length?

A: PHP will emit a warning and substr_compare() will return FALSE. Always validate offsets before calling.

Q: Does substr_compare() modify the original strings?

A: No, it only performs comparison and does not alter either string.

Q: Can substr_compare() be used to compare binary data?

A: Yes, since it is binary safe, it can be used to compare substrings of binary data safely.

Conclusion

The PHP substr_compare() function is a useful and efficient method to compare parts of strings without extracting substrings manually. Its support for offset, length, and optional case-insensitivity makes it flexible for string comparison tasks like checking prefixes, suffixes, or substrings within larger text data.

Understanding its binary safety, proper use of parameters, and limitations with multibyte strings will help you write robust string comparison logic in your PHP applications.