substr_count()
The substr_count() function in PHP is used to count the number of occurrences of a substring within a string. This function is useful when working with
Introduction
The substr_count() function in PHP counts how many times a substring appears inside a larger string. It returns a plain integer, which makes it handy for tasks like measuring how often a word shows up in a body of text, counting delimiters before deciding how to parse a value, or validating that a piece of input contains the expected number of separators.
This chapter covers the function's syntax, how the optional $offset and $length arguments narrow the search, the two behaviors that trip people up most often (overlapping matches and case sensitivity), and the practical situations where you would reach for it.
Syntax
substr_count(string $haystack, string $needle, int $offset = 0, ?int $length = null): int| Parameter | Description |
|---|---|
$haystack | The string to search in. |
$needle | The substring to count. It must be at least one character long; an empty $needle throws a ValueError. |
$offset | Optional. The position in $haystack where the search starts. A negative offset counts back from the end of the string. |
$length | Optional. The maximum number of characters to search, starting at $offset. If omitted (or null), the search runs to the end of the string. |
The function returns the number of occurrences of $needle as an int.
Basic example
Here "is" appears twice — once in "This" and once in the standalone word "is" — so the function returns 2.
Limiting the search with $offset and $length
The $offset argument tells substr_count() where to begin, and $length limits how far it looks. This is useful when you only care about part of a string, such as a header section or a fixed-width field.
<?php
$text = "hello world hello";
// Start searching after the first word.
echo substr_count($text, "hello", 6), "\n"; // 1
// Search only the first 5 characters, starting at index 1.
echo substr_count("abcabcabc", "abc", 1, 5), "\n"; // 1In the first call the search begins at index 6, so only the second "hello" is counted. In the second call the window is "bcabc" (5 characters starting at index 1), which contains a single full "abc".
If
$offsetand$lengthwould push the search past the end of the string, PHP throws aValueError. Keep$offset + $lengthwithinstrlen($haystack).
Gotcha: overlapping matches are not counted
substr_count() does not count overlapping occurrences. After it finds a match, it continues from the end of that match, not the next character.
<?php
echo substr_count("aaa", "aa"); // 1, not 2There are two overlapping "aa" pairs in "aaa", but the function counts only the first and then resumes after it. If you need overlapping matches, use a regular expression with a lookahead via preg_match_all().
Gotcha: the search is case sensitive
substr_count() matches exactly, so "Apple" and "apple" are different substrings.
<?php
$text = "Apple apple APPLE";
echo substr_count($text, "apple"), "\n"; // 1
// Normalize the case first for a case-insensitive count.
echo substr_count(strtolower($text), "apple"), "\n"; // 3Lower-casing the haystack with strtolower() before counting is the simplest way to make the comparison case-insensitive.
When to use substr_count()
- Counting delimiters — for example, checking how many commas a CSV line has before splitting it with
explode(). - Word or token frequency — measuring how often a term appears in a block of text.
- Lightweight validation — confirming a value contains the expected number of separators (e.g., exactly two dots in a version string).
When you need the position of a match rather than a count, use strpos(); when you want to extract part of a string, use substr().
Conclusion
substr_count() is a fast, simple way to count substring occurrences and return them as an integer. Remember its two key behaviors — it skips overlapping matches and is case sensitive — and use the $offset/$length arguments to restrict the search when you only need to inspect part of a string.